How to set a unique parameter when running a shell_command ? (difficult question)

Hi,
I’ve got

- alias: IPCam Snapshot
  trigger:
    platform: state
    entity_id: binary_sensor.motion_sensor
    to: 'on'
  action:
  - service: shell_command.ipcam_mp4
  - service: notify.ha_telegram
    data:
      message: ''
      data:
        video:
          - file: /config/temp/output.mp4

shell_command.yaml is :

ipcam_mp4: /config/shell_scripts/ipcam_mp4.sh

The shell command ipcam_mp4 is creating a file called /config/temp/output.mp4
The whole automation works.
But If the automation runs two times simultaneously then I could have a race condition, and two files output.mp4 would be created at the same time, and I won’t know which one will be sent via Telegram.

So I’d need something like

- alias: IPCam Snapshot With Param
  trigger:
    platform: state
    entity_id: binary_sensor.motion_sensor
    to: 'on'
  action:
  - service: shell_command.ipcam_mp4_params
    data_template:
      param:   "{{ trigger.event.data.**some_sort_of_unique_id** }}"
  - service: notify.ha_telegram
    data:
      message: ''
      data:
        video:
          - file: /config/temp/output_{{param}}.mp4

shell_command.yaml is :

ipcam_mp4_param: /config/shell_scripts/ipcam_mp4_param.sh {{param}}

So if the unique id is 123, the ipcam_mp4_params would create the file /config/temp/output_123.mp4 and telegram will send output_123.mp4

How could I have this “some_sort_of_unique_id”, to send to my script ?
It could be a timestamp, or the event ID for example ?

What is the actual issue? is it that you may have and need 2 instances running almost simultaneously and therefore do need to differentiate the 2 files, or should you not have 2 automations running at the same time?

If latter, you can add a condition to your automation to check if it ran in the last xxx sec and make sure it doesn’t run again:

    - condition: template
      value_template: '{{ (as_timestamp(now()) - as_timestamp(states.automation.ipcamsnapshot.attributes.last_triggered | default(0)) | int > xxx)}}'

else you could always parse the time the automation last ran, keeping only the sec and milisec ? something along the lines (untested)

- alias: IPCam Snapshot With Param
  trigger:
    platform: state
    entity_id: binary_sensor.motion_sensor
    to: 'on'
  action:
  - service: shell_command.ipcam_mp4_params
    data_template:
      param: "{% set param = as_timestamp(states.automation.ipcamsnapshot_with_param.attributes.last_triggered) | timestamp_custom("%S.%f") %}{{var}}"
  - service: notify.ha_telegram
    data:
      message: ''
      data:
        video:
          - file: /config/temp/output_{{param}}.mp4

Thanks for this great reply.

As the mp4 generation takes around 10 seconds, I don’t want to have something like :

  • trigger 1, starting to write file…
  • 5 seconds after…
  • trigger 2, starting to write in the same file…
  • trigger 1 completes writing to the file - which is now corrupted :slight_smile:

The ‘as_timestamp’ condition is genius and would fix my issue, I will add this for sure.

Your second solution is also very interesting, can we create variables in YAML using
param: "{% set param = "blabla" %}{{var}}"
I didn’t see that documented anywhere. Did you use a custom component ?

no custom component, just standard (though somewhat advanced) HA :wink:
I found it on the community too

I use this for my generic curl shell command (copied from @dale3h)

https://github.com/metbril/home-assistant-config/blob/master/packages/support/curl.yaml

thanks @lolouk44 'll give it a shot

thanks @metbril I see that you can iterate on ‘headers’ like a list, very useful as well