Attaching photo to persistent notification

Hello,

I am trying to figure out how to attach a photo to a persistent notification. I would like to send a notification when my front door camera detects a person with an image attached.

I have it working but for some reason it always sends the same photo. It’s like it is cached somewhere and doesn’t update the image even though a new image has been created.

Here’s the code that creates the snapshot:

metadata: {}
data:
  filename: /config/www/images/front_door/front-door-person.jpg
target:
  entity_id: camera.doorbell_clear
action: camera.snapshot

Running that creates this image (note the time: 08:26):

When I run this:

alias: Send a notification
action: notify.persistent_notification
data:
  message: >-
    Person Detected<p> ![Front Door
    Motion](/local/images/front_door/front-door-person.jpg)
  title: Front Door

It always sends this file (note time: 08:14):

If I obtain the link from the image in the notification it displays the old file until I refresh the browser then it shows the correct updated photo.

Is there a way to send the updated file via the notification?

I’d like the file to overwrite so I only have the last version of the photo only.

Thanks in advance.

Did you ever get this figured out. I am seeing the same thing

Can’t say I have.

I figured out the .jpg name needs to be unique for them to display right in the HA App/Web UI. I couldn’t get the variables to work in an automation from one command to another, so I went with a script which stores the file name in a helper, then call that script in the automation. I have setup a bunch of them and works significantly better than the DVR software alone, given the data I have in HA to work with.

I am using this in a script to take the snapshot:

alias: Snapshot-Mailbox
sequence:
  - variables:
      timestamp: "{{ now().strftime('%Y%m%d_%H%M%S') }}"
      snapshot_filename: snapshot_uvc_front_door_{{ timestamp }}.jpg
      snapshot_path: /config/www/tmp/{{ snapshot_filename }}
  - data:
      value: "{{ snapshot_filename }}"
    target:
      entity_id: input_text.snapshot_mailbox_filename
    action: input_text.set_value
  - data:
      filename: "{{ snapshot_path }}"
    target:
      entity_id: camera.uvc_front_door_high_resolution_channel_insecure
    action: camera.snapshot
  - wait_template: >-
      {{ snapshot_filename in
      state_attr('camera.uvc_front_door_high_resolution_channel_insecure',
      'entity_picture') }}
    timeout: "00:00:01"
mode: single

Then the action part of the automation:

actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - OPEN
              - CLOSED
              - ERROR
              - NOT-UPDATING
        sequence:
          - action: script.snapshot_mailbox
            data: {}
          - delay:
              hours: 0
              minutes: 0
              seconds: 1
              milliseconds: 0
          - data:
              title: |-
                Mailbox - {% if is_state('binary_sensor.mailbox_door', 'off') %}CLOSED
                         {% elif is_state('binary_sensor.mailbox_door', 'on') %} OPENED
                         {% else %} UNKNOWN {% endif %}
              message: |-
                {{ now().strftime("%m-%d-%Y - %r") }}
                Battery: **{{ states('sensor.mailbox_battery') }}%**
                Signal: **{{ states('sensor.mailbox_signal_strength') }} dBm**
                Status: {% if is_state('binary_sensor.mailbox_door', 'off') %} **Closed**
                        {% elif is_state('binary_sensor.mailbox_door', 'on') %} **Open**
                        {% else %} **Unknown** {% endif %}
                ![image](/local/tmp/{{
                states('input_text.snapshot_mailbox_filename') }})
                [Link](/config/devices/device/6ea919d6417bc8ffd735fd9df31f0589)
            action: notify.persistent_notification
          - data:
              title: |-
                Mailbox - {% if is_state('binary_sensor.mailbox_door', 'off') %} CLOSED
                         {% elif is_state('binary_sensor.mailbox_door', 'on') %} OPENED
                         {% else %} UNKNOWN {% endif %}
              message: |-
                {{ now().strftime("%m-%d-%Y - %r") }}
                Status: {% if is_state('binary_sensor.mailbox_door', 'off') %} Closed
                        {% elif is_state('binary_sensor.mailbox_door', 'on') %} Opened
                        {% else %} Unknown {% endif %}
              data:
                attachment:
                  content-type: jpeg
                  url: |-
                    /local/tmp/{{ states('input_text.snapshot_mailbox_filename') }}
            action: notify.mobile_app_joes_iphone
          - action: shell_command.delete_camera_snapshots
            metadata: {}
            data: {}
mode: single

Figured out that the Snapshots have to stay around until you view them in the App/Web GUI. So I do it on every run:

# Delete snapshots older than 7 days
  delete_camera_snapshots: "find /config/www/tmp -name '*.jpg' -mtime +7 -delete"
1 Like

Thanks for posting that. I will certainly be giving this a go. Thanks again :+1:.

Thanks for the info, here is my code / version of your script / automation. I decided that I’d write the file name to a text help from within the automation. Hopefully that will work.

alias: Doorbell Person or Button Pressed
description: >-
  Triggers when a person is detected or the doorbell button is pressed. Takes a
  snapshot, announces, and sends a notification.
triggers:
  - entity_id: binary_sensor.doorbell_person
    to: "on"
    trigger: state
  - entity_id: binary_sensor.doorbell_visitor
    to: "on"
    trigger: state
conditions:
  - condition: state
    entity_id: binary_sensor.doorbell_person
    state: "off"
    for: "00:02:00"
    enabled: true
  - condition: state
    entity_id: binary_sensor.doorbell_visitor
    state: "off"
    for: "00:02:00"
    enabled: true
actions:
  - if:
      - condition: or
        conditions:
          - condition: sun
            after: sunset
            after_offset: "-00:15:00"
          - condition: sun
            before: sunrise
            before_offset: "00:15:00"
    then:
      - action: light.turn_on
        metadata: {}
        data:
          brightness_pct: 100
        target:
          entity_id:
            - light.porch_2
            - light.porch_led
      - wait_for_trigger:
          - entity_id:
              - binary_sensor.doorbell_person
              - binary_sensor.doorbell_visitor
            to: "off"
            for: "00:05:00"
            trigger: state
      - target:
          entity_id:
            - light.porch
            - light.porch_led
        action: light.turn_off
        data: {}
    alias: Turn on the porch lights if dark
  - alias: Set snapshot filename
    action: input_text.set_value
    metadata: {}
    data:
      value: doorbell_{{ now().strftime('%d%m%Y_%H%M%S') }}.jpg
    target:
      entity_id: input_text.doorbell_snapshot
  - alias: Take a snapshot
    data:
      filename: >-
        /config/www/images/front_door/{{
        (states("input_text.doorbell_snapshot")) }}
    action: camera.snapshot
    target:
      entity_id: camera.doorbell_fluent
  - metadata: {}
    data:
      announcement: Someone is at the front door
    alias: Announce that someone is at the front door
    action: script.play_an_announcement_speaker_selection
  - delay: "00:00:02"
  - data:
      title: Front Door Alert
      message: Someone is at the front door.
      data:
        attachment:
          content-type: jpeg
          url: >-
            /local/images/front_door/{{ (states("input_text.doorbell_snapshot"))
            }}
    action: notify.mobile_app_steves_iphone
    alias: Send a notification to Steve's phone
  - alias: Turn off the porch lights if dark and they are on
    if:
      - condition: or
        conditions:
          - condition: sun
            after: sunset
            after_offset: "-00:15:00"
          - condition: sun
            before: sunrise
            before_offset: "00:15:00"
          - condition: state
            entity_id: light.porch_2
            state: "on"
          - condition: state
            entity_id: light.porch_led
            state: "on"
    then:
      - wait_for_trigger:
          - entity_id:
              - binary_sensor.doorbell_person
              - binary_sensor.doorbell_visitor
            to: "off"
            for: "00:05:00"
            trigger: state
        timeout:
          hours: 0
          minutes: 5
          seconds: 30
          milliseconds: 0
        alias: Wait until the doorbell goes clear for 5 minutes
      - target:
          entity_id:
            - light.porch
            - light.porch_led
        action: light.turn_off
        data: {}
  - action: shell_command.purge_doorbell_snapshots
    metadata: {}
    data: {}
    alias: Purge old snapshots (> 1 week)
mode: single

The only issue I am having is that I don’t see an image when I click on the notification on my iPhone. I can see an image on my apple watch and when the notification is received but when I click on it, the home assistant app opens but no image is presented. Is there something I am overlooking?

Thanks again for your advice.

I had the same issue, I couldn’t get the variables to work in an automation, that’s why I moved them to the script.
Using
filename: /config/www/tmp/snapshot_uvc_front_door_{{ timestamp }}.jpg Created
snapshot_uvc_front_door_.jpg

I do see your URL is double quoted vs single, not sure if that matters:

url: /local/tmp/{{ states(‘input_text.snapshot_bar_filename’) }}

Did you check the input_text value matches the actual file name in created in /local/images/?

I moved the commands from the script to the automation and this is working:

alias: Notify - Mailbox
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.mailbox_door
    to: "on"
    id: OPEN
    alias: Mailbox Opened
  - alias: Mailbox Closed
    trigger: state
    entity_id:
      - binary_sensor.mailbox_door
    to: "off"
    id: CLOSED
  - value_template: >-
      {{ now() - states.binary_sensor.mailbox_door.last_changed >=
      timedelta(days=3) }}
    id: NOT-UPDATING
    trigger: template
    alias: Mailbox Not Updating
  - trigger: numeric_state
    entity_id:
      - sensor.mailbox_battery
    below: 50
    id: BATTERY
    alias: Mailbox Battery Low
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - OPEN
              - CLOSED
        sequence:
          - action: input_text.set_value
            metadata: {}
            data:
              value: snapshot_mailbox_{{ now().strftime('%Y%m%d_%H%M%S') }}
            target:
              entity_id: input_text.snapshot_mailbox_filename
          - action: camera.snapshot
            metadata: {}
            data:
              filename: >-
                /config/www/tmp/{{
                states('input_text.snapshot_mailbox_filename') }}
            target:
              entity_id: camera.uvc_front_door_high_resolution_channel
          - delay:
              hours: 0
              minutes: 0
              seconds: 1
              milliseconds: 0
          - data:
              title: >-
                Mailbox - {% if is_state('binary_sensor.mailbox_door', 'off') %}
                CLOSED
                         {% elif is_state('binary_sensor.mailbox_door', 'on') %} OPENED
                         {% else %} UNKNOWN {% endif %}
              message: >-
                {{ now().strftime("%m-%d-%Y - %r") }}

                Battery: **{{ states('sensor.mailbox_battery') }}%**

                Signal: **{{ states('sensor.mailbox_signal_strength') }} dBm**

                {%- from 'relative_time_plus.jinja' import relative_time_plus %}

                Updated: **{{
                relative_time_plus(states.binary_sensor.mailbox_door.last_changed,3)
                }}**

                Status: {% if is_state('binary_sensor.mailbox_door', 'off') %}
                **Closed**{% elif is_state('binary_sensor.mailbox_door', 'on')
                %} **Open**{% else %}**Unknown**{% endif %}

                ![image](/local/tmp/{{
                states('input_text.snapshot_mailbox_filename') }})

                [Link](/config/devices/device/6ea919d6417bc8ffd735fd9df31f0589)
            action: notify.persistent_notification
          - data:
              title: >-
                Mailbox - {% if is_state('binary_sensor.mailbox_door', 'off') %}
                CLOSED
                         {% elif is_state('binary_sensor.mailbox_door', 'on') %} OPENED
                         {% else %} UNKNOWN {% endif %}
              message: >-
                {{ now().strftime("%m-%d-%Y - %r") }}

                Battery: {{ states('sensor.mailbox_battery') }}%

                Signal: {{ states('sensor.mailbox_signal_strength') }} dBm

                {%- from 'relative_time_plus.jinja' import relative_time_plus %}

                Updated: {{
                relative_time_plus(states.binary_sensor.mailbox_door.last_changed,3)
                }}

                Status: {% if is_state('binary_sensor.mailbox_door', 'off') %}
                Closed{% elif is_state('binary_sensor.mailbox_door', 'on') %}
                Opened{% else %} Unknown{% endif %}
              data:
                attachment:
                  content-type: jpeg
                  url: >-
                    /local/tmp/{{ states('input_text.snapshot_mailbox_filename')
                    }}
            action: notify.mobile_app_joes_iphone
          - action: shell_command.delete_camera_snapshots
            metadata: {}
            data: {}
      - conditions:
          - condition: trigger
            id:
              - NOT-UPDATING
              - BATTERY
        sequence:
          - data:
              title: Mailbox - ERROR
              message: >-
                {{ now().strftime("%m-%d-%Y - %r") }}

                Battery: **{{ states('sensor.mailbox_battery') }}%**

                Signal: **{{ states('sensor.mailbox_signal_strength') }} dBm**

                {%- from 'relative_time_plus.jinja' import relative_time_plus %}

                Updated: **{{
                relative_time_plus(states.binary_sensor.mailbox_door.last_changed,3)
                }}**

                Status: {% if is_state('binary_sensor.mailbox_door', 'off') %}
                **Closed**{% elif is_state('binary_sensor.mailbox_door', 'on')
                %} **Opened**{% else %} **Unknown**{% endif %}

                [Link](/config/devices/device/6ea919d6417bc8ffd735fd9df31f0589)
            action: notify.persistent_notification
          - data:
              title: Mailbox - ERROR
              message: >-
                {{ now().strftime("%m-%d-%Y - %r") }}

                Battery: {{ states('sensor.mailbox_battery') }}%

                Signal: {{ states('sensor.mailbox_signal_strength') }} dBm
                           {%- from 'relative_time_plus.jinja' import relative_time_plus %}
                Updated: {{
                relative_time_plus(states.binary_sensor.mailbox_door.last_changed,3)
                }}

                Status: {% if is_state('binary_sensor.mailbox_door', 'off') %}
                Closed{% elif is_state('binary_sensor.mailbox_door', 'on') %}
                Opened{% else %} Unknown{% endif %}
              data:
                url: /config/devices/device/6ea919d6417bc8ffd735fd9df31f0589
            action: notify.mobile_app_joes_iphone
mode: single