Just wanted to report back that Node-Red was indeed the solution!
Remember that my camera only sends intrusion detection events ‘IsInside: true’. It never sends ‘IsInside: false’ afterwards. So the binary sensor went to on once and then stayed there.
Even when using a template sensor with an auto_off, that would turn the template sensor off indeed, but it would never go to on again, because the ONVIF integration was waiting for a change, not a repeat message.
So now I’ve made a Node-Red flow that reads the ONVIF event for intrusion detection and doesn’t care if the state changes or not (because it doesn’t):
[{"id":"075dde15536a9c84","type":"tab","label":"Hikvision intrusion detection","disabled":false,"info":"","env":[]},{"id":"c0c2921e400fab23","type":"onvif-events","z":"075dde15536a9c84","name":"","deviceConfig":"699b141d532b4f3a","action":"start","x":470,"y":180,"wires":[["e220e090ca7d4068"]]},{"id":"e220e090ca7d4068","type":"switch","z":"075dde15536a9c84","name":"Topic: intrusion detection","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"RuleEngine/FieldDetector/ObjectsInside","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":690,"y":220,"wires":[["a81480cf201ffa7d","14d2a1fdd87bbcd6"]]},{"id":"16f3bf1025ee7b5e","type":"ha-entity","z":"075dde15536a9c84","name":"NR_hikvision_intrusion_detection","server":"dba1afad4b847d7d","version":1,"debugenabled":false,"outputs":1,"entityType":"binary_sensor","config":[{"property":"name","value":"NR_hikvision_intrusion_detection"},{"property":"device_class","value":"motion"},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"payload","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1380,"y":300,"wires":[[]]},{"id":"8259c7c927843f31","type":"change","z":"075dde15536a9c84","name":"","rules":[{"t":"set","p":"action","pt":"msg","to":"start","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":160,"wires":[["c0c2921e400fab23"]]},{"id":"9c7dd5fed75baad4","type":"inject","z":"075dde15536a9c84","name":"Start listening","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":120,"y":160,"wires":[["8259c7c927843f31"]]},{"id":"5e7d436e0d279eeb","type":"inject","z":"075dde15536a9c84","name":"Stop listening","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":200,"wires":[["26db0157817e8787"]]},{"id":"26db0157817e8787","type":"change","z":"075dde15536a9c84","name":"","rules":[{"t":"set","p":"action","pt":"msg","to":"stop","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":200,"wires":[["c0c2921e400fab23"]]},{"id":"a81480cf201ffa7d","type":"debug","z":"075dde15536a9c84","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":180,"wires":[]},{"id":"14d2a1fdd87bbcd6","type":"switch","z":"075dde15536a9c84","name":"Property: changed","property":"property","propertyType":"msg","rules":[{"t":"eq","v":"Changed","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":930,"y":260,"wires":[["fe25d76af2531a15"]]},{"id":"fe25d76af2531a15","type":"trigger","z":"075dde15536a9c84","name":"","op1":"true","op2":"false","op1type":"str","op2type":"str","duration":"10","extend":true,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":1130,"y":260,"wires":[["16f3bf1025ee7b5e","9a7f65b2d0fb2e7e"]]},{"id":"9a7f65b2d0fb2e7e","type":"debug","z":"075dde15536a9c84","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1310,"y":220,"wires":[]},{"id":"b0c09a5de225e6ab","type":"inject","z":"075dde15536a9c84","name":"test","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"property","v":"Changed","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"RuleEngine/FieldDetector/ObjectsInside","payloadType":"date","x":490,"y":260,"wires":[["e220e090ca7d4068"]]},{"id":"699b141d532b4f3a","type":"onvif-config","xaddress":"10.25.100.10","port":"80","timeout":"30","checkConnectionInterval":"5","name":""},{"id":"dba1afad4b847d7d","type":"server","name":"Home Assistant","version":1,"addon":false,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
The ‘start listening’ is injected when the flow is deployed, so you don’t have to press that.
The magic is in the trigger node, which sets the NR_hikvision_intrusion_detection entity state to true when a message is received.
It doesn’t care which message, that’s already been filtered out by the two switch nodes.
It then puts it back to false 10 seconds later.
So the field detection binary sensor, from the ONVIF integration, just sits there:
But the new Node-Red entity does not:
BTW1: I informed Hikvision about this bug using both their Benelux and Global email addresses. In both cases I got a response that I should contact my local retailer, so they won’t do a thing with it.
BTW2: This:
Was fixed by manually editing the Node-Red package.json file, adding this line:
Without it npm would remove the nodes after a reboot.