Unable to correctly launch curl command to save image form an URL to the local disc

Your authorisation is wrong, ie username/password.

I don’t have your camera, so i cant test. But this may help curl - Tutorial

I’ve tried it with a random URL off of the internet and it runs in the command line, but I still get the same error message in the Automation.

If the username and password were wrong I’d get the same Asci file with the same error message.

The problem seems to be how I’m calling curl, not curl itself. Curl is just Curl -o destination source.

If I try to create the automation below automation I get the same error message as before (With double quotes, single quotes or no quotes.

alias: Save image from URL
trigger:
  - platform: time
    at: "17:48:00"
action:
  - shell_command: 
      - curl -o /share/snapshots/image.jpg 'https://th.bing.com/th/id/R.8e632b4dbd61ffe21316d0aa8fd99717?rik=S%2fVRgWs8B1QUSA&riu=http%3a%2f%2fwww.dumpaday.com%2fwp-content%2fuploads%2f2019%2f12%2fpictures-10-2.jpg&ehk=QH5i3EAxyZYJFl0N54KuqmERNBOpDvFxygcV4nlsxsk%3d&risl=&pid=ImgRaw&r=0'

If I go to the command line and enter

- curl -o /share/snapshots/image.jpg 'https://th.bing.com/th/id/R.8e632b4dbd61ffe21316d0aa8fd99717?rik=S%2fVRgWs8B1QUSA&riu=http%3a%2f%2fwww.dumpaday.com%2fwp-content%2fuploads%2f2019%2f12%2fpictures-10-2.jpg&ehk=QH5i3EAxyZYJFl0N54KuqmERNBOpDvFxygcV4nlsxsk%3d&risl=&pid=ImgRaw&r=0'

The image downloads perfectly.

Therefore the error doesn’t relate to the file that I’m downloading, it relates to the way that I’m attempting to call curl in the automation.

The automation is failing before it even gets to the URL

curl has no problems on ha. Get your auth right. Is the camera using basic or digest?

On the curl page i gave you look at the http section.

I’ve tried it with a public URL from the web. It ran perfectly in the command line, but it failed with the exact same message in the automation.

The automation is failing before it passes the URL

Going back to square 1. The

action: 
  - shell_command

is not valid. It should be

action:
  - service: shell_command.something

I’m a little confused as to why this wasn’t the first thing that you suggested.

OK

I have the following in my automations.yaml

 id: save_image_from_url
  alias: Save image from URL
  trigger:
    - platform: time
      at: "17:48:00"
  action:
    - service: shell_command.curl -o /share/snapshots/image.jpg {{ states ('sensor.ptz_besderii_motioneye_url')}}

And this in my template.yaml

- sensor:
  - name: ptz_besderii_motioneye_url
    unique_id: ptz_besderii_motioneye_url
    state: "https://logos-world.net/wp-content/uploads/2020/09/Google-Symbol.png"

When run the action fails with the error message

Error running action
Template rendered invalid service: shell_command.curl -o /share/snapshots/image.jpg https://logos-world.net/wp-content/uploads/2020/09/Google-Symbol.png

On it’s own, when I try to enter curl -o /share/snapshots/image.jpg {{ states (‘sensor.ptz_besderii_motioneye_url’)}} into the console I get the error message

bash: syntax error near unexpected token '('

If I enter curl -o /share/snapshots/image.jpg “https://logos-world.net/wp-content/uploads/2020/09/Google-Symbol.png” it downloads the image perfectly.

If I try to take the template out of the automation and just use the string it gives me my original error message back

 Service shell_command.curl -o /share/snapshots/image.jpg https://logos-world.net/wp-content/uploads/2020/09/Google-Symbol.png does not match format <domain>.<name> for dictionary value @ data['action'][0]['service']

I tried with single quote, and double quotes, as well as no quote. This leads me to believe that the root of the problem is that I’m simply not formatting the way that I put the URL in to the curl command correctly and that this is simply a syntax error.

The URL is a publicly available image (The Google logo).

Could you please try this action on your HA system to see if it downloads the image correctly. I can get it to download from the console, but not in an automation.

Based on your previous posts, the solution should be

service: shell_command.curl -o /share/snapshots/image.jpg {{ states ('sensor.ptz_besderii_motioneye_url')}}

This still gives me the same error

does not match format <domain>.<name> for dictionary value @ data['action'][0]['service']. 

Based on everything that I can find, it would seem that the problem is that HA does not like the arguments that are being used with Curl because they’re not formatted correctly, meaning that it doesn’t recognize the arguments.

Are you able to replicate this on your HA?

You don’t seem to have added a shell_command which is why it is saying it cannot find a shell_command.curl.

May I suggest you actually read some docs. Shell Command - Home Assistant

Something like

shell_command:
  curl: curl -o /share/snapshots/image.jpg {{ states ('sensor.ptz_besderii_motioneye_url')}}

Then you will have a service shell_command.curl (after a restart of HA)

It was when I started again at the top of the thread, and had the doc page open at the same time that I realised. If you think it should have been obvious, then I am sorry for trying to help.

Read it, didn’t understand it. As I said before, I’m still getting to grips with the basics of the syntax. Most of this is still Greek to me.

I’m confused as to why you previously suggested taking out the shell_command:

You’re previous suggestion was that I call it directly as an object (or whatever it is that HA calls objects)

action:
  - service: shell_command.something

Have you managed to get this to do anything on your own HA system. At the moment I’m still not 100% certain that this isn’t simply a problem with my installation or seteup

Sorry small error in my last post. The action will be

action:
  service: shell_command.curl

There appears to be nothing wrong with your install. You just need to put in the right code.

There are 3 parts

  1. The template sensor to get the url to download
  2. the shell_command setting - this creates a shell_command service
  3. the automation to call the shell_command service

Have you been able to get 2. to function correctly on your HA setup?

as per my previous post my template is returning the expected output in the Developer Tools. I’m successfully downloading files from a URL in the command line, but when I try to call the same code that I’m using for the command line into an automation I still receive the same error message as I did originally.

does not match format <domain>.<name> for dictionary value @ data['action'][0]['service']. 

My conclusion is that either the I’m not calling Curl correctly, for example there is a syntax error or I’m incorrectly using the arguments, or that this simply isn’t something that can be done in an automation due to some restriction that I don’t yet have enough understanding of HA to determine.

What is the definition of your shell_command integration? You still haven’t said (unless I missed it).

Yes, the shell_command integration works here. You need to configure it first. You don’t seem to have.

I asked

Is that the HA way of saying that it’s installed and configured by default, and that you don’t need to do any additional setup?

you answered

Yes it is installed out of the box. 

Which I took as meaning that there were no additional steps that I needed to do to use shell_command. Thus I have done nothing.

At present this is the only reference to it is this single line in my automation yaml “service: shell_command.curl -o /share/snapshots/image.jpg https://logos-world.net/wp-content/uploads/2020/09/Google-Symbol.png”.

As previously explained, I’m not sufficiently familiar with the way that HA is structured, or how yaml is used to understand the majority of what is in the documentation. I’m still getting that stuff down.

Could you please post what you have.

Let me have at go at trying to explain this.

shell_command is what Home Assistant calls a domain (mentioned in the error message). It’s the same as switch and light etc.

You need to add shell commands that you want to use to your Home Assistant configuration (configuration.yaml) just like anything else that needs to be defined in there.

For example:

shell_command:
  cleanup_snapshots: '/config/_scripts/cleanup_snapshots.sh'
  mount_music: mkdir -p /media/music;mount -t cifs -o username=homeassistant,password=supersecretpassword //192.168.2.6/music /media/music

That is what is listed in my shell_command config.

I call these from automations, BUT and here is the critical piece you are misunderstanding - I can only call them as they are.

action:
  - service: shell_command.cleanup_snapshots

I can’t add random stuff to the end of that - for example:

action:
  - service: shell_command.cleanup_snapshots -o /var/blah/something

That’s not valid - because it doesn’t exist, all that exists is shell_command.cleanup_snapshots

If you want to get CURL to download a file URL passed via a webhook then you need a few things.

  1. You need to have a template sensor, that is triggered by the webhook being received and stores the URL.
  2. You need your CURL command in the shell_command config to be using the state of that sensor as the URL it is downloading.

You CANNOT do what you have been trying to do in an automation.

Basically, what you’re saying is that I’m not able to pass arguments to Curl from within an automation. I need to write a routine somewhere else inside HA, that routine is then set in stone and all that I can do is to call it exactly as it was written?

So, I need to add a line to my configuration.yaml that contains Curl, all the flags, and all of the arguments, and then call that command directly in the automation?

Yes so you would do something like this in configuration.yaml

template:
    - trigger:
        - platform: webhook
          webhook_id: my_curl_url
      sensor:
        - name: my_curl_url
          state: {{ trigger.payload.image_url }}

In your shell_command config it would be something like:

shell_command:
  curl_image: curl -o /share/images/image.jpg {{ states('sensor.my_curl_url') }}

Then your automation will trigger just on the the state change of the sensor.my_curl_url and you would simply do:

action:
  - service: shell_command.curl_image

OK, that was simple

I just cut and past the code that I was trying to run in my automation into my configuration file, and called it from the automation.

I had the code almost entirely correct, but in the wrong place.

Problem solved. Genius. two thumbs up.