Notifcation on different email addresses using only one script & notify

Hello

I have for 20 sensors, 20 automations. Every automation calls a script witch are all the same beside of the notification, the script call the service notication, and the notification send the mail.
how can i reuse the code, instead of copy&paste it for every sensor?

it would be cool to have only 1 script and 1 notification for all of the automations, but every automation need to send to a different mailadress…

Thanks for any help!

my config files so far:
automation.yaml

id: '1603195752548'
  alias: Sensor 01
  description: ''
  trigger:
  - platform: numeric_state
    entity_id: sensor.netatmo_01_co2
    above: '900'
  condition: []
  action:
  - service: script.send_mail_01
    data: {}
  mode: single

scripts.yaml

send_mail_01:
  alias: Send Mail 01
  sequence:
    - service: notify.sendmail01
      data:
        title: Test
        message: Test
        data:
            html: "<html> <body>Hello</body> </html>


            "

notify.yaml

- name: sendmail01
  platform: smtp
  server: !secret mail_server
  port: !secret mail_port
  sender: [email protected]
  encryption: starttls
  username: !secret mail_user
  password: !secret mail_password
  recipient:
    - [email protected]
  sender_name: Home Assistant

Scripts can take in variables passed in under the data section.

You’ll want a way to map each sensor to whatever notify you have. My guess from your one example is sensor 01 calls notify.sendmail01, sensor 02 would be notify.sendmail02, etc.

Looking at the smtp integration, it seems like you’re stuck having 20 of those separate since it doesn’t have a “target” input.

send_mail_script:
  # Inputs to this scirpt are
  # id: sensor id
  # title: email title
  # message: email message
  # html: extra html stuff
  alias: Send Mail
  sequence:
    - service: "notify.sendmail{{id}}"
      data:
        title: "{{title}}"
        message: "{{message}}"
        data:
          html: "{{html}}"

Then you would simply call your script passing those in via the data section.

  - action: script.send_mail_script
    data:
      id: 01
      title: "Test Title"
      message: "Test Message"
      html: " ... "

So the trick would be to extract all of that info from a single automation based on the sensor.

You can figure that part out on your own, and even use what I’m about to show you below. I propose you ditch the script entirely since it’s just doing an extra step that isn’t needed. Since we are going to be templating the single automation, we will already have to extract this info, so there is no need to have the script do it.


To do this all in a single automation (no script required), I’m going to use the new (since 0.115) variables section. Before this, I would advice you name all of your sensors in such a way that you can extract some info from them. For example sensor.<platform>_<id>_<type> such that no matter what you have, you could extract the given id from any sensor with some template magic.

In this example, just create the variable map.

The advantage of using this map like this is you don’t have to have a consistent naming structure for all of your sensors, and can easily add new ones. All I’m doing is mapping a sensor to its own personal information.

id: '1603195752548'
  alias: Sensor notify
  # Allow multiple sensors to trigger this at the same time, but queue them
  # just incase the smtp service can't handle multiple calls at once. 
  mode: queued
  description: 
  variables:
    my_sensors:
      # Assumes a list of sensors who's state is some numeric value. 
      # Not sure if we can have periods in yaml keys, so just store the object_id as the lookup.
      netatmo_01_c02:
        id: 01 
        trigger_value: 900
        email_title: "Title for sensor 01"
        email_message: "Message for sensor 01"
        email_html: "..."
      random_sensor:
        id: 02
        trigger_value: 204
        email_title: "Title for sensor 02"
        email_message: "Message for sensor 02" 
        email_html: "..."
  trigger:
  # Unless you turn on the beta template list feature in 0.117, we can't
  # generate a list from yaml. It's a little unfortunate that we have to repeate
  # the sensor names here.
  - platform: numeric_state
    entity_id: 
      - sensor.netatmo_01_co2
      - sensor.random_sensor
    # Optional, allow each sensor to define its own trigger condition rather than
    # use the same value for each one. 
    above: "{{ my_sensors[state.object_id].trigger_value }}"
  condition: []
  action:
  - variables:
       # Get the notify from the lookup table. Creating another variables section
       # so we don't have to type my_sensors[XXXXX] a bunch below in the event
       # we want to call multiple services. In this case, it's the same amount :P
       notify_service: "notify.sendmail{{my_sensors[trigger.to_state.object_id].id}}"
       the_title: "{{my_sensors[trigger.to_state.object_id].email_title}}"
       the_message: "{{my_sensors[trigger.to_state.object_id].email_message}}"
       the_html: "{{ my_sensors[trigger.to_state.object_id].email_html}}"
  - service: "{{ notify_service}}"
    data:
      title: "{{the_title}}"
      message: "{{the_message}}"
      data:
        html: "{{the_html}}"

Basically, by using the variables section, we can store a bunch of info in a single place to reference it in all parts of the automation. Before, we would have to duplicate this information at every single template which was a pain.

Hello Jim
Thank you very much for your hints, i will test it tommorrow.
Because the mail is for every sensor the same, only the recipient changes, is it possible to pass a varialble with the recipient mailadress to one notify.sendmail service?

Doesn’t look like it. The SMTP integration requires a recipient in the config (or a list) and there doesn’t seem to be a way to specify it dynamically.

If the message is the same, then the script makes sense. You can just pass in which notify service to call, or just do it all in the automation.

And because SMTP wont let you pass those in as variables, you can just store that in the variables list rather than an ID.

  variables:
    # The message is the same for everyone
    email:
      title: "The Title"
      message: "The Message"
      html: "The HTML"
    # Match the sensors with the recipient service, and store anything
    # else here that might be useful
    my_sensors:
      # Assumes a list of sensors who's state is some numeric value. 
      # Not sure if we can have periods in yaml keys, so just store the object_id as the lookup.
      netatmo_01_c02:
        email: notify.sendmail01
        trigger_value: 900
      random_sensor:
        email: notify.sendmail02
        trigger_value: 204
   trigger: ...
   condition: ...
   action:
  - service: "{{ my_sensors[trigger.to_state.object_id].email }}"
    data:
      title: "{{email.title}}"
      message: "{{email.message}}"
      data:
        html: "{{email.html}}"