Button to send shell command then display RTSP from camera

G’day all!
Does anyone know a way I can have a button (or picture card) in lovelace that will send a shell command and then display the feed from a camera?

I have set up my PTZ presets as shell commands and i’m looking for a way to press one button to execute the PTZ preset and then show the display from the camera.

So far, I have been able to make switches that display as icons in a picture_glance card. Pressing them moves the camera but then you have to press the card to bring up the live stream.

Cheers for any solutions, leads or hints in advance.

I did the same thing – Picture Glance card with PTZ buttons – but got stuck where you are too. The only potential method I found is this Custom Component, but I didn’t want the extra maintenance so I ended up going a completely different route.

I’m doing a similar sort of thing using fully kiosk browser’s REST commands.
So far, I’ve been able get HA to detect a line cross event from a HIK camera and then it sends the URL to a wall mounted tablet which opens the stream (more info) for about 10 seconds. It works very well!

Now trying to make a very simple UI that will let me press on picture.jpg and that then activates the PTZ shell command and open the stream (more info) at the same time.

I came across this custom camera card which has the live stream at full frame rate directly inside the card which also works but i need to figure out how to resize them or how to make them trigger a shell command when pressed.

I’m really very impressed with HA and the community, so many possibilities!
It’s ripe for a sweet CCTV camera UI/interface for wall mounted tablets but i never really learnt to properly code.

May I ask what your completely different route is?

1 Like

How are you doing this? I have a soon-to-be-wall-mounted tablet too (Odroid XU4 running Android/10" touchscreen) that I’d like to get a video popup onto. I saw the card you mentioned as well but after reading this I’m holding off:

HADashboard might be able to do something close to what you want (although the button would have an icon instead of a .jpg). I initially built my tablet with the intention of running HADashboard on it, but I wasn’t able to get as much info on the screen as I’d like so I’m back to Lovelace. I’m running a Blue Iris camera server that will switch its web feed from a grid view to a single camera when motion is detected or when any cam is tapped on, so the route I’m taking now is just a simple iframe card in my Lovelace ‘Home’ panel along with the same iframe in full panel view on my ‘Surveillance’ panel.

Come to think of it, you might be able to accomplish what you want with a script or automation that executes your shell command and switches to a full panel view. I’m going to look at a couple things and report back…

1 Like

Yeah, this might work for you: Add a new panel with your video feed in an iframe, then create a script that executes your shell command and navigates to the new panel…?

The android app called Fully Kiosk is what i’m using for a wall mounted tablet. The fully unlocked version is a few dollars to buy but it’s well worth it. Got some great features like using the camera to turn the screen on when it detects motion as well as being able to send TTS to the tablet.

Because my coding is not great i’m using node red to detect the camera event and then send URL requests to Fully Kiosk to show the camera feed:

http://192.168.x.xxx:2323/?cmd=loadURL&url=http://192.168.x.xxx:8123/api/camera_proxy_stream/camera.carparkcamera?api_password=PW&password=PW

The flow looks like this:

Ah yes, that should work, will give that a go.

Using that custom camera card I have come up with this:

The two top images are live video from the 2 PTZ cameras.
The smaller images are picture cards that call the shell commands.

It all works and the framerate is good but it does get a bit laggy after a few mins and then you have to do a browser refresh. I do have my cameras on their highest quality settings though.

I’m still using the ffmpeg for these cameras, not tried the stream component yet to see if that can be improved.

1 Like

Ah OK, I overlooked your mention of Fully Kiosk.

My panel view idea won’t work because scripts can only execute services and there’s no service for panel navigation. :slightly_frowning_face:

But, it looks like your mostly there. You have the hardest part (the video popup) done, you just need to combine the code above with your PTZ shell command. Just copy your existing flow, add an ‘exec’ node with your POST command (I’m assuming) for PTZ preset, create an input_boolean in HA to link your Picture Glance button to, change your ‘Car Park Detector’ node to monitor the input_boolean, remove your ‘motion’ node, and add a ‘call service’ node after your ‘Return View’ node that turns your input_boolean back off.

I think i’m slowly coming to the same conclusion. Seems a long winded workaround though.

My explanation was long-winded :woozy_face: , but here’s a visual…

code:

[{“id”:“b71240ad.d74f3”,“type”:“exec”,“z”:“b1bf2358.5bf2a”,“command”:“'curl -u user:password -k "https://192.168.x.xxx/cgi-bin/action.cgi?cmd=ptz_preset_1\“'”,“addpay”:false,“append”:”“,“useSpawn”:“false”,“timer”:”“,“oldrc”:false,“name”:“PTZ Preset 1”,“x”:810,“y”:140,“wires”:[,,]},{“id”:“e956b6cb.94cdc8”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:”“,“method”:“GET”,“ret”:“txt”,“paytoqs”:false,“url”:”“,“tls”:”“,“proxy”:”“,“authType”:“basic”,“x”:630,“y”:280,“wires”:[[“65c6698a.96f2e8”,“84136953.f37778”,“b71240ad.d74f3”]]},{“id”:“65c6698a.96f2e8”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“Show Camera”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:“http://192.168.x.xxx:2323/?cmd=loadURL&url=http://192.168.x.xxx:8123/api/camera_proxy_stream/camera.carparkcamera?api_password=PW&password=PW",“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:820,“y”:200,“wires”:[[“80429967.070fc8”]]},{“id”:“84136953.f37778”,“type”:"http request”,“z”:“b1bf2358.5bf2a”,“name”:“Speech”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:”“,“tls”:”“,“proxy”:”“,“authType”:“basic”,“x”:800,“y”:360,“wires”:[]},{“id”:“37782dab.76bfb2”,“type”:“switch”,“z”:“b1bf2358.5bf2a”,“name”:“on”,“property”:“payload”,“propertyType”:“msg”,“rules”:[{“t”:“eq”,“v”:“on”,“vt”:“str”}],“checkall”:“true”,“repair”:false,“outputs”:1,“x”:450,“y”:280,“wires”:[[“e956b6cb.94cdc8”]]},{“id”:“80429967.070fc8”,“type”:“delay”,“z”:“b1bf2358.5bf2a”,“name”:“delay 20s”,“pauseType”:“delay”,“timeout”:“20”,“timeoutUnits”:“seconds”,“rate”:“1”,“nbRateUnits”:“1”,“rateUnits”:“second”,“randomFirst”:“1”,“randomLast”:“5”,“randomUnits”:“seconds”,“drop”:false,“x”:1020,“y”:200,“wires”:[[“2b5f9838.f35558”]]},{“id”:“486ed363.89cbfc”,“type”:“server-state-changed”,“z”:“b1bf2358.5bf2a”,“name”:“HA input_boolean: toggle”,“server”:“f56cacb4.ec621”,“entityidfilter”:“input_boolean.”,“entityidfiltertype”:“exact”,“outputinitially”:false,“state_type”:“str”,“haltifstate”:”“,“halt_if_type”:“str”,“halt_if_compare”:“is_not”,“outputs”:1,“output_only_on_state_change”:true,“x”:230,“y”:280,“wires”:[[“37782dab.76bfb2”]],“outputLabels”:[“on”]},{“id”:“2b5f9838.f35558”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“Return View”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:”“,“tls”:”“,“proxy”:”“,“authType”:“basic”,“x”:1210,“y”:200,“wires”:[[“b9159fe.1ff576”]]},{“id”:“b9159fe.1ff576”,“type”:“api-call-service”,“z”:“b1bf2358.5bf2a”,“name”:“HA input_boolean: turn_off”,“server”:“f56cacb4.ec621”,“service_domain”:“input_boolean”,“service”:“turn_off”,“data”:”{"entity_id":"input_boolean."}“,“mergecontext”:”“,“output_location”:“payload”,“output_location_type”:“msg”,“x”:1460,“y”:200,“wires”:[]},{“id”:“f56cacb4.ec621”,“type”:“server”,“z”:”",“name”:“Home Assistant”,“legacy”:false,“hassio”:false,“rejectUnauthorizedCerts”:true,“ha_boolean”:“y|yes|true|on|home|open”,“connectionDelay”:true}]

Alternatively, you have the feed stay on until the button is pressed again…

code:

[{“id”:“e63d129d.f9336”,“type”:“server-state-changed”,“z”:“b1bf2358.5bf2a”,“name”:“HA input_boolean: on / off”,“server”:“f56cacb4.ec621”,“entityidfilter”:“input_boolean.”,“entityidfiltertype”:“exact”,“outputinitially”:false,“state_type”:“str”,“haltifstate”:“on”,“halt_if_type”:“str”,“halt_if_compare”:“is_not”,“outputs”:2,“output_only_on_state_change”:true,“x”:370,“y”:900,“wires”:[[“907c4e43.9de1e”],[“a6f70fa1.c5d9e”]],“outputLabels”:[“on”,“off”]},{“id”:“907c4e43.9de1e”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“”,“method”:“GET”,“ret”:“txt”,“paytoqs”:false,“url”:“”,“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:610,“y”:800,“wires”:[[“f10e1f8f.197be”,“32642ecc.07c612”,“f34efa60.560638”]]},{“id”:“a6f70fa1.c5d9e”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“”,“method”:“GET”,“ret”:“txt”,“paytoqs”:false,“url”:“”,“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:610,“y”:1000,“wires”:[[“e52e1448.241278”,“86e16521.7c1e98”,“a15b6785.86f2e8”]]},{“id”:“f10e1f8f.197be”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“Show Camera”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:“http://192.168.x.xxx:2323/?cmd=loadURL&url=http://192.168.x.xxx:8123/api/camera_proxy_stream/camera.carparkcamera?api_password=PW&password=PW",“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:800,“y”:800,“wires”:[[]]},{“id”:“32642ecc.07c612”,“type”:"http request”,“z”:“b1bf2358.5bf2a”,“name”:“Speech”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:“”,“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:780,“y”:860,“wires”:[]},{“id”:“f34efa60.560638”,“type”:“exec”,“z”:“b1bf2358.5bf2a”,“command”:“'curl -u user:password -k "https://192.168.x.xxx/cgi-bin/action.cgi?cmd=ptz_preset_1\“'”,“addpay”:false,“append”:”“,“useSpawn”:“false”,“timer”:”“,“oldrc”:false,“name”:“PTZ Preset 1”,“x”:790,“y”:740,“wires”:[,,]},{“id”:“e52e1448.241278”,“type”:“exec”,“z”:“b1bf2358.5bf2a”,“command”:”'curl -u user:password -k "https://192.168.x.xxx/cgi-bin/action.cgi?cmd=ptz_preset_0\“'”,“addpay”:false,“append”:“”,“useSpawn”:“false”,“timer”:“”,“oldrc”:false,“name”:“PTZ Preset 0”,“x”:790,“y”:940,“wires”:[,,]},{“id”:“86e16521.7c1e98”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“Return View”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:“”,“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:790,“y”:1000,“wires”:[]},{“id”:“a15b6785.86f2e8”,“type”:“http request”,“z”:“b1bf2358.5bf2a”,“name”:“Speech”,“method”:“POST”,“ret”:“txt”,“paytoqs”:false,“url”:“”,“tls”:“”,“proxy”:“”,“authType”:“basic”,“x”:780,“y”:1060,“wires”:[]},{“id”:“f56cacb4.ec621”,“type”:“server”,“z”:“”,“name”:“Home Assistant”,“legacy”:false,“hassio”:false,“rejectUnauthorizedCerts”:true,“ha_boolean”:“y|yes|true|on|home|open”,“connectionDelay”:true}]

Nice!
Looks like this is the way to go for now. Will have to see how responsive it is.
Been messing around with it for 5 hours straight, need to get some sunshine but I can’t pull myself away :slight_smile:

1 Like

I’ll edit and post the code for each so you can get some sun…

:slight_smile:

1 Like

That’s very kind of you good sir. We Brits have to make the most of when the sun comes out.

1 Like