Command Line Switch Curl Not Working

Hello everyone,

I am currently running Home Assistant OS 6.1 with core-2021.6.6 on a Raspberry Pi 4. The only user present on my HomeAssistant installation is “root” as installed by Home Assistant OS. To remotely start and stop my projector I decided to use a Command Line Switch. I created two shell scripts inside the config-directory using the Terminal & SSH Add-On installed via Supervisor and made them executable from command line:

Shell script for on command (/config/shell_commands/projejctor_on.sh)
#!/bin/bash

echo "start" >> /tmp/test.txt
# Login twice - only after the second attempt the correct cookie is retrieved
/usr/bin/curl -X POST -d "***" -s -S --cookie-jar /tmp/cookie http://projector/tgi/login.tgi > /dev/null

echo "1" >> /tmp/test.txt
/usr/bin/curl -X POST -d "***" -s -S --cookie-jar /tmp/cookie http://projector/tgi/login.tgi > /dev/null

echo "2" >> /tmp/test.txt
/usr/bin/curl -X POST -d "pwr=Power ON" -s -S  --cookie /tmp/cookie http://projector/tgi/control.tgi > /dev/null

echo "3" >> /tmp/test.txt
# logout again and delete the cookie
/usr/bin/curl -s -S --cookie /tmp/cookie http://projector/tgi/logout.tgi > /dev/null

echo "4" >> /tmp/test.txt
/bin/rm /tmp/cookie

echo "end" >> /tmp/test.txt

Both scripts can be run from the command line via the SSH Add-On and execute properly. I subsequently added the following lines to my configuration.yaml:

switch:
  - platform: command_line
    switches:
      projector:
        command_on: "/config/shell_commands/projector_on.sh"
        command_off: "/config/shell_commands/projector_off.sh"

Afterwards I restarted Home Assistant. Turning this switch on, leaves me with the following two logs:

Timout & Command Failed
Logger: homeassistant.components.command_line
Source: components/command_line/__init__.py:26
Integration: command_line (documentation, issues)
First occurred: 21:20:45 (1 occurrences)
Last logged: 21:20:45

Timeout for command: /config/shell_commands/projector_on.sh
Logger: homeassistant.components.command_line.switch
Source: components/command_line/switch.py:109
Integration: command_line (documentation, issues)
First occurred: 21:20:45 (1 occurrences)
Last logged: 21:20:45

Command failed: /config/shell_commands/projector_on.sh

Increasing the log-level (homeassistant.components.command_line) to debug also does not render more output (I checked /config/home-assistant.log directly via ssh).

When I reconfigure my switch to the following

switch:
  - platform: command_line
    switches:
      kitchen_light:
        command_on: "echo 'test' >> /tmp/test.txt"
        command_off: "rm /tmp/test.txt"

I don’t see any errors inside the logs, but the txt file is not created either.

Only when I create that txt file inside of the /config/shell_commands folder, I see that file from within my SSH shell. I can confirm that (by make the switch echo whoami) that the user running these command line switches is “root” and that he can see the /tmp directory. Funny enough, listing stuff inside the tmp directory inside “that switch environment” shows me my formerly created test.txt and the cookie file (that I both cannot see via SSH).

The /tmp/test.txt files inside the switch environment contains “start 1 2” and some “test” spammed into - so generally some parts of the script seem to run. Checking the content of the cookie-jar shows that curl must have at least run, but somehow does not retrieve the cookies properly:

# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

Does anyone know what is going on here? In which environment does my command get executed? What file-system is that? And what is happening to my first curls? Why are they not properly retrieving the cookie? Any help would be greatly appreciated! :slight_smile:

It’s running inside the HA container.
Here’s how you open a shell in it.

Welcome to HA! :slightly_smiling_face:

Unless mistaken, the shell scripts are called with “sh” (#!/bin/bash is ignored).
There doesn’t seem to be any bashisms in your scripts, but does sh /config/shell_commands/projector_on.sh work in shell?

If not, you might do, e.g.

command_on: "bash /config/shell_commands/projector_on.sh"

Next step would be to check AppArmor.

Hey @VDRainer,
thank you very much for that hint - it is pure gold :+1:

After having figured out, that the mentioned add-on differs from the official “Terminal & SSH” Add-On a lot, I finally figured out my problem. The homeassistant docker container does not seem to be able to resolve DNS names :exploding_head: When switching to an IP-Adress inside my curl command, I could finally run that it from within the docker container.

Porting these changes to my scripts & switch made the whole thing work then.

Final working switch & script
switch:
  - platform: command_line
    switches:
      projektor:
        command_on: "/config/shell_commands/projektor_on.sh"
        command_off: "/config/shell_commands/projektor_off.sh"
        command_state: "/config/shell_commands/projektor_state.sh"
        value_template: '{{ value == "1" }}'
        friendly_name: "Projektor"
#!/bin/bash

# Login twice - only after the second attempt the correct cookie is retrived
curl -X POST -d "admin=" -s -S --cookie-jar /tmp/cookie http://192.168.178.59/tgi/login.tgi > /dev/null
curl -X POST -d "admin=" -s -S --cookie-jar /tmp/cookie http://192.168.178.59/tgi/login.tgi > /dev/null

curl -X POST -d "pwr=Power ON" -s -S  --cookie /tmp/cookie http://192.168.178.59/tgi/control.tgi > /dev/null

# logout again and delete the cookie
curl -s -S --cookie /tmp/cookie http://192.168.178.59/tgi/logout.tgi > /dev/null
rm /tmp/cookie

For future readers I’ll list my misunderstandings on my way to get it working:

  1. the HomeAssistant OS directly installs home assistant “bare metal” → it is instead installed as a docker container, see 2
  2. the official Terminal & SSH Add-On lets you log in as root on the machine seeing everything → instead it logs you in as root but somehow hides e.g. docker completely from you (I still don’t have a clue, how that is possible :sweat_smile: - hints greatly appreciated)
  3. the homeassistant docker container (which you’ll only see and have access to when using the community SSH & Web Terminal Add-On properly resolves DNS names as the host system does → it unfortunately does not, just use an IP address directly

Maybe I missed a lot of fine print but it seems to be very tricky for a new user to get a command line switch working. I would propose the following adoptions to make it a little more easier:

  1. make the command line switch print out the correct error output from the script instead of some generic error (timeout or command failed)
  2. adjust the documentation of the official Terminal & SSH Add-On explaining that that SSH access doesn’t show the real truth on the server
  3. explain somewhere in the installation documentation that home assistant is indeed running as a docker container and how to properly access that
  4. add a “debugging” section to the command line switch documentation explaining how you can run your commands manually
  5. fix the dns resolution inside the docker container

What are you thinking about these proposals? And what would be the correct way to tackle them, in case they are reasonable?

Best regards

Felix

I am trying to turn on a video stream on my pi via my HA which is running on my NUC on docker container.

I have the following in my configuration file:

  - platform: command_line
    switches:
      magicmirror:
        friendly_name: Pi Display
        command_on: "ssh [email protected] 'vcgencmd display_power 1'"
        command_off: "ssh [email protected] 'vcgencmd display_power 0'"

  - platform: command_line
    switches:
      mmskynews:
        friendly_name: Skynews
        command_on: "ssh [email protected] '/home/pi/skynews.sh'"
        command_off: "ssh [email protected] 'killall streamlink'"

The Pi Display switch works perfectly fine as it turns on and off the Pi. However the second one which is playing live Skynews on my pi, it doesnt like it and HA throws the following error:

2021-08-05 17:09:20 ERROR (SyncWorker_1) [homeassistant.components.command_line] Command failed: ssh [email protected] '/home/pi/skynews.sh'
2021-08-05 17:09:20 ERROR (SyncWorker_1) [homeassistant.components.command_line.switch] Command failed: ssh [email protected] '/home/pi/skynews.sh'

I have got no idea why it does that and I am thinking could it be due to the time that HA expects the ssh command to act instantly but obviously my Sky News SSH Command takes a few seconds to connect to the live stream and then it plays.

@koying @VDRainer @FelixT I am not sure what could be wrong but is there a way where HA can anticipate the delay for turning on a live stream via the command line switch?

Thanks.

Try, from a HA ssh terminal (+login)

  1. Do the ssh [email protected] part
  2. Do the /home/pi/skynews.sh part

Does it work?

Yes I can ssh into my pi and play the stream the way you pointed out in your reply.

Does the script returns after launching whatever player you use?
I.e. does it launch the player in the background?

If not, you should, or HA will timeout waiting for the return code of the script.

More info on the failure might be available if you turn up logging level to debug for the command_line platform.

I think HA does timeout waiting for the return. Is there a way I can avoid this?

I am using vlc player to stream Sky News. However its via streamlink.

Yep let me do that and see what logs I get.

@mrand Do you think this is suffice?

logger:
  default: info
  logs:
    homeassistant.components.command_line: debug

UPDATE:

This is my log can’t find anything really:

2021-08-06 01:20:50 INFO (MainThread) [homeassistant.helpers.script.mm_sky_news] MM Sky News: Running template script
2021-08-06 01:20:50 INFO (MainThread) [homeassistant.helpers.script.mm_sky_news] MM Sky News: Executing step call service
2021-08-06 01:20:50 INFO (SyncWorker_9) [homeassistant.components.command_line.switch] Running command: ssh [email protected] 'killall streamlink'
2021-08-06 01:20:50 DEBUG (SyncWorker_9) [homeassistant.components.command_line] Running command: ssh [email protected] 'killall streamlink'
2021-08-06 01:20:50 ERROR (SyncWorker_9) [homeassistant.components.command_line] Command failed: ssh [email protected] 'killall streamlink'
2021-08-06 01:20:50 ERROR (SyncWorker_9) [homeassistant.components.command_line.switch] Command failed: ssh [email protected] 'killall streamlink'
2021-08-06 01:20:52 INFO (MainThread) [homeassistant.helpers.script.mm_sky_news] MM Sky News: Running template script
2021-08-06 01:20:52 INFO (MainThread) [homeassistant.helpers.script.mm_sky_news] MM Sky News: Executing step call service
2021-08-06 01:20:52 INFO (SyncWorker_0) [homeassistant.components.command_line.switch] Running command: ssh [email protected] '/home/pi/skynews.sh'
2021-08-06 01:20:52 DEBUG (SyncWorker_0) [homeassistant.components.command_line] Running command: ssh [email protected] '/home/pi/skynews.sh'
2021-08-06 01:20:52 ERROR (SyncWorker_0) [homeassistant.components.command_line] Command failed: ssh [email protected] '/home/pi/skynews.sh'
2021-08-06 01:20:52 ERROR (SyncWorker_0) [homeassistant.components.command_line.switch] Command failed: ssh [email protected] '/home/pi/skynews.sh

Yeah, looking now at the source code, I’m thinking debug only prints out the “Running” line extra. Not much help. It should really print out return codes at a minimum.

But… while I was there, I noticed that timeout is explicitly called out. And since you presumably aren’t seeing that in your logs, it means that you aren’t dealing with Home Assistant timing out.

https://github.com/home-assistant/core/blob/64c9f9e1cb60690a890ab5f5a88e53746439a6a9/homeassistant/components/command_line/init.py#L25

Does command_off error out as well?
Also, what is in the skynews.sh script?

Just launch VLC in background, likely simply by putting an “&” at the of the command.

@mrand so you think its not to do with the timeout?

when I run the script on my raspberry pi terminal it works well as expected and if I was to turn off the switch in HA i.e. which is killall streamlink it does stop the stream and also there are no errors.

However if I was to turn the switch on in HA i.e. run the script on raspberry pi which contains the following:

#!/bin/bash

#export XAUTHORITY=/home/pi/.Xauthority

export DISPLAY=:0

streamlink https://www.youtube.com/watch?v=9Auq9mYxFEE 720p --player=cvlc -a "--fullscreen {filename}" -l none

then I get the errors as shown above and also then the command_off doesn’t work and gives the same error as command_on.

my skynews/sh script in my raspberry pi contains the following:

#!/bin/bash

#export XAUTHORITY=/home/pi/.Xauthority

export DISPLAY=:0

streamlink https://www.youtube.com/watch?v=9Auq9mYxFEE 720p --player=cvlc -a "--fullscreen {filename}" -l none

Have to admit I’m not following what you’re doing 100%. When this works, where is the stream displayed? Are you running a window manager on your Pi?

When HA executes this by itself, where are you expecting it to display the stream?

Regardless, have you tried command_on: "xhost + ; command_on: "ssh [email protected] ‘/home/pi/skynews.sh’ " And/or maybe you need -X or -Y on the ssh command line.

Also, going back to your previous response, ssh’ing to the Pi isn’t exactly same as what @koying suggested by using the HA terminal. By using the terminal, you are operating closer to how HA would operate.

is this correct?

I have my raspberry pi connected to my tv and I am using HA on my NUC via docker to control it. So one of the things I am trying to achieve is playing a stream in this case Skynews via HA.

“&” will likely not be enough as the process would be killed when the ssh session ends.

You should use nohup, e.g.

nohup streamlink https://www.youtube.com/watch?v=9Auq9mYxFEE 720p --player=cvlc -a "--fullscreen {filename}" -l none &

1 Like

Maybe not :slight_smile: I understand better now. I had it twisted in my mind where you were trying to display to. So the Pi is able to display graphics and video to the TV, presumably with a window manager.

If you are successful in opening a terminal window via the HA sidebar or add-on page and running your ssh command from there, my only idea is to create your own logging to a file for when HA does it, either on the Pi, or your HA system, or both:

  • Turn on verbose mode for ssh and redirect output to a file. Be aware that it might default some stuff to stderr, so the full redirect would be something like “ssh -vvv command >> logfile 2>&1”
  • For streamlink, looks like are a number of log and debug command line options you could enable
1 Like