A Dashboard setup for video cameras

Well, seems this is an increasing interest in todays society being able to monitor your home and other belongings using all kind of video devices. Especially since they have become rather affordable and easy to install and configure

So let's start simple, this beginners example flow just demonstrates how you can view live video in the dashboard. Obviously you have to change the url's to fit your specific cameras

Next steps could involve adding features to integrate with your home automation & alarm system, take snapshots, view latest as well as to introduce AI object detection and sending notifications to your smart phone. Many features will depend on the capabilities of your cameras and if you have an underlying video system. In my case, I use a video system software named Motion that adds a lot of such capabilities/intelligence and it allows you to use all kind of non-intelligent usb to more intelligent ip cameras. Really recommended.

In this project I run everything on a single RPI 3+. To install Motion, just follow the guide here describing "Installing with a release deb package". I used the latest Stretch version: https://github.com/Motion-Project/motion/releases/download/release-4.2.2/pi_stretch_motion_4.2.2-1_armhf.deb

My current system structure is rather straight forward & simple:
Cameras <---> Motion and other services <---> Node-RED/Dashboard

In this example, I have just one camera. A really nice and cheap ESP-EYE configured as a web cam but you can use any camera that is supported

Let's see if there is an interest and how this can be developed & extended further!

The flow:

[{"id":"286dfcc6.d4e334","type":"comment","z":"55f532a.497bccc","name":"Just a live view of cameras","info":"","x":190,"y":60,"wires":[]},{"id":"bb5fdb34.e3dd88","type":"inject","z":"55f532a.497bccc","name":"","topic":"","payload":"checkWeb","payloadType":"str","repeat":"30","crontab":"","once":true,"onceDelay":"10","x":150,"y":160,"wires":[["769295e6.93ea2c"]]},{"id":"769295e6.93ea2c","type":"ui_template","z":"55f532a.497bccc","group":"1c70d4cd.325c0b","name":"Just a view of cameras","order":1,"width":"35","height":"12","format":"<!DOCTYPE html>\n<html>\n<style>\nimg {\n    border: 1px solid #ddd;\n    border-radius: 8px;\n    padding: 2px;\n    width: 405px;\n}\n</style>\n\n<script type=\"text/javascript\">\nscope.$watch('msg', function(msg) {\n    inMessage(msg.payload);\n});\n\nfunction updatePic() {\n    document.getElementById('c51').src = \"\";\n    document.getElementById('c52').src = \"\";\n    document.getElementById('c53').src = \"\";\n    document.getElementById('c54').src = \"\";\n    document.getElementById('c55').src = \"\";\n    document.getElementById('c56').src = \"\";\n    document.getElementById('c57').src = \"\";\n    document.getElementById('c58').src = \"\";\n    //alert('updated pics');\n}\n\nfunction inMessage(event) {\n    if (event.match('checkWeb')) {\n        updatePic();\n    }\n}\n\n</script>\n<center>\n<table>\n    <tr><!-- Row 1 -->\n    \t\t<td style=\"text-align: center\"><img src=\"\" id=\"c51\" /></td>\n   \t\t    <td style=\"text-align: center\"><img src=\"\" id=\"c52\" /></td>\n    \t\t<td style=\"text-align: center\"><img src=\"\" id=\"c53\" /></td>\n    \t\t<td style=\"text-align: center\"><img src=\"\" id=\"c54\" /></td>\n    </tr>\n    <tr><!-- Row 2 -->\n    \t\t<td style=\"text-align: center\"><img src=\"\" id=\"c55\" /></td>\n   \t\t    <td style=\"text-align: center\"><img src=\"\" id=\"c56\" /></td>\n    \t\t<td style=\"text-align: center\"><img src=\"\" id=\"c57\" /></td>\n    \t\t<td style=\"text-align: center\"><img src=\"\" id=\"c58\" /></td>\n    </tr>\n</table>\n</center>\n</html>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":380,"y":160,"wires":[[]]},{"id":"debe02e2.7163a","type":"ui_template","z":"55f532a.497bccc","group":"1c70d4cd.325c0b","name":"Clock Toolbar","order":5,"width":"0","height":"0","format":"\n<script id=\"titleScript\" type=\"text/javascript\">\n    $('#clock').remove();\n    var toolbar = $('.md-toolbar-tools');\n    var div = $('<div></div>');\n    var p = $('<p/ id=\"clock\">');\n    $('#titleScript').parent().hide();\n    div.append(p);\n    div[0].style.margin = '5px 5px 5px auto';\n    toolbar.append(div);\n\n    function displayTitle(lh) {\n        p.text(lh); \n    }\n    \n    function upTime() {\n        var d = new Date();\n        p.text(d.toLocaleTimeString('de-AT'));\n    }\n\n    // Watch the payload and update the title\n    (function(scope) {\n        scope.$watch('msg.payload', function(data) {\n            if (data.match(\"systemsummary\")) { //Systemstatus\n                m = data;\n                n = m.split(':');\n                //alert(n[1]);\n                var sSummary = parseInt(n[1], 10);\n                if(sSummary === 14){\n                    document.getElementById(\"clock\").style.backgroundColor =\"transparent\";\n                }\n                if(sSummary < 14){\n                    document.getElementById(\"clock\").style.backgroundColor =\"#FF0033\";\n                }\n            }else{\n                displayTitle(data);\n            }\n        });\n        setInterval(upTime,1000);\n    })(scope);\n</script>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":160,"y":100,"wires":[[]]},{"id":"1c70d4cd.325c0b","type":"ui_group","z":"","name":"LiveVideo","tab":"df07ccac.714e9","disp":false,"width":"35","collapse":false},{"id":"df07ccac.714e9","type":"ui_tab","z":"","name":"LiveVideo","icon":"dashboard","disabled":false,"hidden":false}]

Typical Dashboard ui view for 8 cameras:


Thanks for sharing!

Is there a list of supported cameras or some requirements for such cameras?
i.e. will a picamera work, how about a USB web camera?

Yes, they will, in Motion you can configure either a netcam or a device directly connected (e.g. /dev/videoX) Myself I have USB cameras but one of my friends purchased really nice, rather cheap, onvif WiFi netcams from China, they are also working really great with Motion

The output from Motion is http -> dashboard, makes it simple

Ok, so the requirement is any camera that will work with motion...right?

Well, yes & no, you can skip Motion if you have proper url's for the cameras and then connect them directly to the dashboard. I mentioned Motion since it gives so much more in terms of pre-processing the images, various filtering possibilities, privacy masks, frame rate settings, compensation for sudden light changes etc etc. Also if you later want AI object detection, Motion is used to send images for analyze to a separate AI detection service, I have currently written in Python


Thanks for sharing this :slight_smile: - one quick observation, the new dashboard tab ‘Live Video’ adjusts the logo I have put at the top - see examples below, of a normal tab and then of the one just added from your code? (I already had a time/date dashboard element so removed yours )

Other tabs...


Sorry, in that part I have not spent too much effort but similar issues (putting elements in the tool bar) was discussed earlier in this thread. Maybe something of that could provide some help or ideas


It’s a strange one; as I’ve never had an issue with my image or the clock before, they have been unaffected by the various dashboard items I’ve added. But for some reason your camera template and the resulting new dashboard tab, alters how my default image looks..

Well, try to add an empty ui_template node and just copy the text from mine. Does it change or is the problem still there. Could it be that I did set fixed sizes, you are using auto?

Also this older thread is discussing position/formatting in the toolbar


Thank you for the prompt reply.

I have imported your flow and have had no success.

If I browse on chromium using my pi's url and the assigned port for the camera in Motion :7777 I can access the camera's image.

If I amend your http to "document.getElementById('c51').src = "";" I get a broken image.

Do I need the /1/stream or something else?

I have Foscam C1's and I can get an RTSP with VLC and now Motion.



Try to use the same url as the one that is working directly in your browser. I think the syntax is depending on what version if Motion you are using. I think in newer versions they have the /x/stream at the end

My settings for cameras in Motion version 4.1.1 is like this

    document.getElementById('c11').src = "";
    document.getElementById('c12').src = "";
    document.getElementById('c22').src = "";
    document.getElementById('c21').src = "";
    document.getElementById('c31').src = "";
    document.getElementById('c32').src = "";
    document.getElementById('c41').src = "";
    document.getElementById('c42').src = "";

I'm struggling here.

The browser syntax works with and without /1/stream.

If I put either with or without as you describe above the image is not transferred to the dashboard.

Is your ip addresses your pi address?

Yes I have 4 RPi's with those ip-addresses, each RPi has 2 cameras. I'm running Motion in all 4 RPi's

What happens if you just add a simple ui_template node as follows (with the url to one of your cameras)?

If I do as above it is still a broken image

What do you mean by a broken image?

I mean like this


that means the browser could not find the image. Only thing I can think of is a syntax problem. Please share the code from your ui_template node, maybe we can help and find something, it could be a minor thing causing a major error :wink:

Appreciate the assistance

What do you see if you put that address in the browser -

I see the live video image.

Just to be absolutely sure I copied and pasted your from your reply into the browser.