Node Red Dashboard for Blue Iris ALPR

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
@Alan_F

I am confused here;
  • Create a separate folder to store the images where ALPR detected a tag (outside Blue Iris)
    • The original images are deleted when Blue Iris deletes the clip/alert. Copying them elsewhere allows you to keep them as long as you want
    • This folder should be local to the Node Red instance
Who is writing to this folder Blue Iris or Node Red? Do I have to put a path to it in node red? (My first time using node red)

I'm breaking this off into it's own thread since I expect as more people try this, the same questions will come up - thanks to my near total lack of details in the instructions :)

For anyone finding this thread, most of what you need to get up to speed is in this post: Blue Iris and CodeProject.AI ALPR

There are a few places you need to change things in the main flow to get things going:


1675360928514.png

In the source folder function node, replace the part in the quotes:
Code:
msg.sourcepath = "s:\\BlueIris\\Alerts\\" + msg.payload.Camera
return msg;
with the path to your Blue Iris alerts folder. Mine resides in s:\BlueIris\Alerts. Note the double backslashes. So if your Blue Iris Clips and Archiving tab has the alert folder location as c:\BlueIrisVideo\Alerts, this would read:
Code:
msg.sourcepath = "c:\\BlueIrisVideo\\Alerts\\" + msg.payload.Camera
return msg;
In the copy file node, put the path to the new folder you created in Destination Path. I copy my alert images to S:\BlueIris\LPRImages

1675361055072.png



While we're listing the configuration steps for the main flow:

- In the MQTT listener, make sure the Topic is the same as the topic you set in Blue Iris in the On Alert action

- In the SQL database node (labeled "LPR") you have to click the edit icon (pencil) next to the Database field and set up the connection to your database.

I think that is everything that has to be configured in that flow for your environment.
 

kccustom

Getting the hang of it
Joined
Nov 8, 2014
Messages
100
Reaction score
30
In the source flow you attached there is no source folder or copy file
1675362802546.png
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Sorry. I must have messed up the export. Here is the flow, and I tried importing to it verify all the nodes are included.
Code:
[{"id":"4e4757364b6290fb","type":"group","z":"9796107b389bdb9e","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["c76f238773caf170","87d44d61fefcfd9a","902c1a6918c0db03","5a78a14f6887f171","1ca1a7c8197a712f","4b7b582067b02d1b","2edbc803fde92f3e","efeb83d79c2edc7f","9e119b47c49a583b"],"x":14,"y":19,"w":592,"h":242},{"id":"c76f238773caf170","type":"mqtt in","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"","topic":"BlueIris/LPRdata","qos":"2","datatype":"auto-detect","broker":"a44c57ac297015e5","nl":false,"rap":true,"rh":0,"inputs":0,"x":140,"y":120,"wires":[["87d44d61fefcfd9a","902c1a6918c0db03","9e119b47c49a583b"]]},{"id":"87d44d61fefcfd9a","type":"debug","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"debug 53","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":140,"y":180,"wires":[]},{"id":"902c1a6918c0db03","type":"sqlstring-format","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"","query":"REPLACE INTO lpr_images (tag,file,image_description,filedatetime,camera) VALUES \n(?,?,?,?,?) ","vars":"payload.plate,payload.AlertImgPath,payload.Alert_AI,payload.Date,payload.Camera","outField":"topic","x":310,"y":100,"wires":[["5a78a14f6887f171"]]},{"id":"5a78a14f6887f171","type":"mysql","z":"9796107b389bdb9e","g":"4e4757364b6290fb","mydb":"17c59737.09ace9","name":"LPR","x":450,"y":100,"wires":[["1ca1a7c8197a712f"]]},{"id":"1ca1a7c8197a712f","type":"debug","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"debug 54","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":460,"y":60,"wires":[]},{"id":"4b7b582067b02d1b","type":"debug","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"debug 55","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":480,"y":220,"wires":[]},{"id":"2edbc803fde92f3e","type":"comment","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"BlueIris/LPRdata to database","info":"","x":160,"y":60,"wires":[]},{"id":"efeb83d79c2edc7f","type":"fs-ops-copy","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"Copy file","sourcePath":"sourcepath","sourcePathType":"msg","sourceFilename":"payload.AlertImgPath","sourceFilenameType":"msg","destPath":"s:\\BlueIris\\LPRImages","destPathType":"str","destFilename":"payload.AlertImgPath","destFilenameType":"msg","link":false,"overwrite":true,"x":520,"y":160,"wires":[["4b7b582067b02d1b"]]},{"id":"9e119b47c49a583b","type":"function","z":"9796107b389bdb9e","g":"4e4757364b6290fb","name":"Source folder","func":"msg.sourcepath = \"s:\\\\BlueIris\\\\Alerts\\\\\" + msg.payload.Camera\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":160,"wires":[["efeb83d79c2edc7f"]]},{"id":"a44c57ac297015e5","type":"mqtt-broker","name":"Pi MQTT","broker":"192.168.0.12","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"5","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"17c59737.09ace9","type":"MySQLdatabase","name":"","host":"192.168.0.12","port":"3306","db":"LPR","tz":"America/New_York","charset":"UTF8"}]

It should look like this:

1675366250261.png

For anyone new to Node Red, you don't need those debug nodes. Once everything is working you can delete them or just click the green rectangle sticking out the right side to deactivate them. With them active you can see the messages that are flowing out of the nodes by using the debug window on the right side of the Node Red interface.

I'll also attach the dashboard JSON here to make this thread more complete
 

Attachments

Last edited:

kccustom

Getting the hang of it
Joined
Nov 8, 2014
Messages
100
Reaction score
30
Thanks!

Is the "Copy File" the folder that you are supposed to attach to the webserver?
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Thanks!

Is the "Copy File" the folder that you are supposed to attach to the webserver?
Yes, you want the web server pointed to that folder, so when you go to

Code:
http://web_server_ip:port/name_of_alert_image.jpg
your browser displays the image.

You'll put the same URL in the "Set URL Here" node on the dashboard flow... minus the "name_of_alert_image.jpg"... so
Code:
http://web_server_ip:port/
goes in that node.
 

kccustom

Getting the hang of it
Joined
Nov 8, 2014
Messages
100
Reaction score
30
I think I am close, I am trying to get this to run on unraid and I keep getting this node red error

[error] [fs-ops-copy:Copy file] Error: ENOENT: no such file or directory, copyfile '/data/Alerts/EastLPR/EastLPR.20230203_003704.522739.3-1.jpg' -> '/data/ALPR/EastLPR.20230203_003704.522739.3-1.jpg'

for some reason it looks like the mqtt message is trying to create an extra folder that I don't have "/EastLPR"
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Are all of your alert images in a single folder under Blue Iris? As in, are they NOT in subfolders for each camera?

If so, try putting the source path for the Blue Iris alerts folder in the source path box in the copy node. Enter it just like the destination path is entered.

If that works, you should be able to remove the function node that is labeled "source folder" and reconnect a wire directly from the MQTT node to the copy file node.

The purpose of that function node is to add the camera name as a subfolder to the main Blue Iris alerts path as my alerts are in subfolders.
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Since the original Node Red LPR dashboard doesn't work well on small screens, I created a separate UI tab for use on my phone. The attached flow json is for a mobile-scale version of the dashboard. I'm using a Pixel 5a. Depending on your phone resolution you might have to tweak the element widths for your phone

1675442336991.png

Edit: uploaded a tweaked V2 version. As soon as I posted I saw a few things that needed attention.
 

Attachments

Last edited:

Vettester

Getting comfortable
Joined
Feb 5, 2017
Messages
740
Reaction score
693
Thanks for sharing this! I had to tweak the formatting a bit for my iPhone but it works great!

Screen Shot 2023-02-03 at 10.11.04 AM.png
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Thanks for sharing this! I had to tweak the formatting a bit for my iPhone but it works great!

View attachment 152943
Take a look at the V2 version I uploaded a little while ago. It gets rid of the "Database Search" title, fits the from/to dates on one line, and hides the date picker icons. That gives you a little more vertical room for the data table. I added the updated version screenshot to the original post.
 

Vettester

Getting comfortable
Joined
Feb 5, 2017
Messages
740
Reaction score
693
That's better, thank you!

Screen Shot 2023-02-03 at 5.07.27 PM.png
 
Last edited:

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Someone asked for a list of all the nodes that are used in these flows, as some of them are not packaged with the standard install of Node Red. These are all the items listed in the palette in my Node Red.

node-red
node-red-contrib-fs-ops
node-red-contrib-moment
node-red-contrib-sqlstring
node-red-dashboard
node-red-node-mysql
node-red-node-ui-table
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
That's better, thank you!

View attachment 152990
There's still space being reserved for the invisible calendar icon, which is causing your from: date to get cut off. Try changing the template node in the LPR Mobile flow to this:

Code:
<style>
    .md-datepicker-button 
    {
    display:none !important;
    }
 
    .md-datepicker-input
    {
    text-align:center !important;
    }

    .md-datepicker-triangle-button 
    {
    display:none !important;
    }
</style>

and see if that looks better.
 

Alan_F

Getting the hang of it
Joined
May 17, 2019
Messages
64
Reaction score
57
Location
Maryland
Under the heading of "More options, more better"

If you want to use Grafana instead of Node Red to search and display the images, you can do that too.

This Grafana dashboard uses the Dynamic Image Panel plugin. It displays the images within the selected timeframe using the 'tag' search box at the top to filter them. The colored bar below each image indicates what camera it is from, and the text below the image is the time of day and the tag. If you hover on an image, it pops up a tooltip with the elapsed time and full date/time ("11 hours ago - 2023-02-25 05:01:30"). If you click on an image, it opens the full size image in a new tab. If you're familiar with Grafana, this is pretty easy to set up once you install that plugin using the data from MySQL. If you want a copy of my dashboard.json, let me know and I can share it.

1677341571634.png
 
Top