Help with my Ambulance Dispatch automation, please!

Good morning everyone. I’m a Paramedic Refrigerator Repairman, and when I’m dispatched to a call, I get an email with the address. I’m using the IMAP integration, and trying to set HA to send me a notification to my phone when I get dispatched. I’m having a bit of troubling getting it to work.

Here’s an example dispatch email. This is obviously redacted, if you think there’s something I redacted that could have bearing on my automation, let me know and I’ll provide it

Delivered-To: <redacted>
Received: by <redacted> with SMTP id <redacted>;
        Wed, 6 Aug 2025 07:21:01 -0700 (PDT)
X-Received: by <redacted> with SMTP id <redacted>.6.1754490061354;
        Wed, 06 Aug 2025 07:21:01 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1754490061; cv=none;
        d=google.com; s=arc-20240605;
        b=<redacted>==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605;
        h=to:subject:message-id:date:from:mime-version:dkim-signature;
        <redacted>=;
        f<redacted>s=;
        b=<redacted>w==;
        dara=google.com
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass [email protected] header.s=20230601 header.b="GtoNF/W5";
       spf=pass (google.com: domain of <redacted>@gmail.com designates <redacted> as permitted sender) smtp.mailfrom=<redacted>.com;
       dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com;
       dara=pass [email protected]
Return-Path: <<redacted>@gmail.com>
Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41])
        by mx.google.com with SMTPS id 586e51a60fabf-30be4aaa62fsor873072fac.14.2025.08.06.07.21.01
        for <[email protected]>
        (Google Transport Security);
        Wed, 06 Aug 2025 07:21:01 -0700 (PDT)
Received-SPF: pass (google.com: domain of <redacted>@gmail.com designates <redacted> as permitted sender) client-ip=2<redacted>1;
Authentication-Results: mx.google.com;
       dkim=pass [email protected] header.s=20230601 header.b="GtoNF/W5";
       spf=pass (google.com: domain of <redacted>@gmail.com designates <redacted> as permitted sender) smtp.mailfrom=<redacted>@gmail.com;
       dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com;
       dara=pass [email protected]
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20230601; t=1754490061; x=1755094861; darn=chaveir.im;
        h=to:subject:message-id:date:from:mime-version:from:to:cc:subject
         :date:message-id:reply-to;
        bh=pyj+RVtf5dsnDOowowtfwO4UF9Qz7ui0+gpXEKES2RY=;
        b=<redacted>==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20230601; t=1754490061; x=1755094861;
        h=to:subject:message-id:date:from:mime-version:x-gm-message-state
         :from:to:cc:subject:date:message-id:reply-to;
        bh=pyj+RVtf5dsnDOowowtfwO4UF9Qz7ui0+gpXEKES2RY=;
        b=<redacted>==
X-Gm-Message-State: <redacted> <redacted>/<redacted>/<redacted> <redacted>+2oeWFOyf+Hl5xK8
X-Gm-Gg: <redacted>/1j3QXvLZB9DUo <redacted>/<redacted>+<redacted>+<redacted> xSx1X9zHAy3/UZxu2oC5g/I8VHGoZD2tjn7pGZti8wjkdofI5xA3Y/AgBCVzIrIfbViuzBePOyj oEeuRw=
X-Google-Smtp-Source: AGHT+IF/<redacted>+<redacted>+<redacted>/FgwoekkTDcURq8w=
X-Received: by 2<redacted> with SMTP id <redacted>-<redacted>.23.1754490060457; Wed, 06 Aug 2025 07:21:00 -0700 (PDT)
MIME-Version: 1.0
From: <redacted> <<redacted>@gmail.com>
Date: Wed, 6 Aug 2025 10:20:49 -0400
X-Gm-Features: <redacted>
Message-ID: <<redacted>[email protected]>
Subject: 
To: <redacted>@<redacted>.com
Content-Type: multipart/alternative; boundary="000000000000d0cd24063bb30c87"

--000000000000d0cd24063bb30c87
Content-Type: text/plain; charset="UTF-8"

 266B Something Rd -- Between Fake Ave & Another St - Access: First - Call
ID: 1508041230 - <s>Unresponsive</s> Broken Fridge

--000000000000d0cd24063bb30c87
Content-Type: text/html; charset="UTF-8"

<div dir="ltr">



266B Something Rd -- Between Fake Ave &amp; Another St - Access: First - Call ID: 1508041230 - <s>Unresponsive</s> Broken Fridge







<br></div>

--000000000000d0cd24063bb30c87--

Here’s my automation so far. The triggers are working, and my phone notification is getting delivered, but instead of correctly parsing the email, I’m getting the “Unknown” notification.

alias: <s>EMT</s> Repair Dispatch Notification
description: Process <s>EMT</s> Repair dispatch emails and send phone notifications
triggers:
  - event_type: imap_content
    id: emergency_notifications
    event_data:
      server: imap.gmail.com
      username: [email protected]
    trigger: event
conditions:
  - condition: template
    value_template: >-
      {{ trigger.event.data.sender.lower() in ['<s>[email protected]</s>[email protected]',
      '[email protected]'] }}
actions:
  - variables:
      email_subject: "{{ trigger.event.data.subject }}"
      email_body: "{{ trigger.event.data.text | replace('\r\n', '\n') | replace('\r', '\n') }}"
      address_matches: >-
        {{ email_body | regex_findall('(?m)\s*(.*?) -- (.*?) - (?:Access: (.*?)
        - )?Call ID: (\d{10}) - (.+)') }}
      parsed_address: "{{ address_matches[0][0] if address_matches else 'Unknown Address' }}"
      parsed_cross_streets: >-
        {{ address_matches[0][1] if address_matches else 'Unknown Cross Streets'
        }}
      parsed_access_info: >-
        {{ address_matches[0][2] if address_matches and address_matches[0][2]
        else '' }}
      parsed_call_id: "{{ address_matches[0][3] if address_matches else 'Unknown Call ID' }}"
      parsed_call_type: "{{ address_matches[0][4] if address_matches else 'Unknown Call Type' }}"
  - data:
      title: Regex Debug
      message: "{{ address_matches }}"
    action: persistent_notification.create
  - data:
      title: >-
        {% if parsed_call_type != 'Unknown Call Type' %}{{ parsed_call_type }}{%
        else %}🚨 Incoming <s>Emergency</s> Repair Call 🚨{% endif %}
      message: >-
        📍 {{ parsed_address }} 🛣️ {{ parsed_cross_streets }} {% if
        parsed_access_info %}🔑 {{ parsed_access_info }}{% endif %} 🆔 {{
        parsed_call_id }} 📞 {{ parsed_call_type }}
      data:
        channel: <s>EMT</s>Repair_Dispatch
        importance: high
        priority: high
        persistent: true
        sticky: true
        tag: <s>emt</s>repair_dispatch
        actions:
          - action: ACKNOWLEDGE
            title: Acknowledge
          - action: NAVIGATE
            title: Navigate
            uri: >-
              intent://maps.google.com/maps?daddr={{ parsed_address | urlencode
              }}#Intent;scheme=https;package=com.google.android.apps.maps;end
    action: notify.mobile_app_my_phone

Can someone help me get the regex parsing to work correctly?
Any suggestions on a better system?

Thanks so much
Dovy

You are using the developer tools → Templates to troubleshoot your syntax?

The persistent notification from my most recent email test shows “Regex Debug

and on my phone, I just get “Incoming Emergency Call Unknown Address Unknown Cross Sreets Unknown Call ID”

I haven’t figured that out yet. I keep getting errors about things being undefined

It seems to me as it should work.
Having this in developer tools works as expected.

{% set email_body = "266B Something Rd -- Between Fake Ave &amp; Another St - Access: First - Call ID: 1508041230 - Unresponsive" %}

{% set  address_matches = email_body | regex_findall('(?m)\s*(.*?) -- (.*?) - (?:Access: (.*?) - )?Call ID: (\d{10}) - (.+)') %}
      parsed_address: "{{ address_matches[0][0] if address_matches else 'Unknown Address' }}"
      parsed_cross_streets: >-
        {{ address_matches[0][1] if address_matches else 'Unknown Cross Streets'
        }}
      parsed_access_info: >-
        {{ address_matches[0][2] if address_matches and address_matches[0][2]
        else '' }}
      parsed_call_id: "{{ address_matches[0][3] if address_matches else 'Unknown Call ID' }}"
      parsed_call_type: "{{ address_matches[0][4] if address_matches else 'Unknown Call Type' }}"

I think…

Er… Where are you? If it’s the UK I’m not making any more 999 calls. Home Assistant is a hobbyist’s toy. You mustn’t use it in life or death situations.

Seriously.

Edit: Also, I’m pretty sure you need permission to use information like this (let alone post it here). Have you got it?

1 Like

Then again… if they send emails to their personal Gmail emails like this then the response times can’t be a factor.
Nor data security .

1 Like

It’s a privacy issue.

“NHS staff are allowed to share patient details by email, but strict conditions apply. Staff must use secure email systems (such as NHSmail or other DCB1596-accredited systems) when sending confidential or sensitive information, especially if sending details externally or between different NHS organisations. Sharing patient information by unencrypted email is only permissible if the patient has given explicit consent and the risks have been explained to them.”

1 Like

This is the US, not UK. What permission are you talking about? I’ve not shared any private information at all. What private information do you see?

1 Like

Actually HIPAA
https://www.hhs.gov/hipaa/index.html

:hospital: Who Must Comply?

  • Covered Entities: Health plans, healthcare clearinghouses, and healthcare providers who transmit health information electronically.HHS.gov
  • Business Associates: Individuals or entities that perform certain functions or activities on behalf of, or provide certain services to, a covered entity that involve the use or disclosure of protected health information.

you are #2

That patient info (incident at address is absolutely PII if you include what to expect at the incident, anyone who thinks name / address pairing isnt a solved issue for bad guys think again. So that + Health Incident + Ambulance - covered entity is PHI) in gmail is already sus unless it’s a government tenant. But lets say it is, your notification goes through Google’s public notification system to your phone which is NOT secure. So… Unless you have specific clearance to send dispatch notices through google’s notification system - I wouldn’t…

As a us Citizen - former emt and responder myself I’d prefer you didn’t, just sayin (and yes i did edit this with an llm - because my typing sucks)

Shorten to just location and grab info later through terminal or radio… The answer is totally different if the transport of the message is 100% owned by public systems.

2 Likes

I’m 100% certain that this post here is not in any way a HIPAA violation. I didn’t come here for a discussion of how our ambulance company should best dispatch calls. I’m looking for help with the regex in my automation.

I’m pretty sure that dispatch addresses in and of themselves are not PHI under HIPAA, but again, that’s not what I came here for. Facts are, for several agencies I work for, I get notified of the address via SMS, email, or over an open radio system, none of which are in any way encrypted.

Perhaps I should rephrase my request.

I’m looking for how to best parse emails that I’m receiving that all follow a specific pattern. Using the IMAP integration and regex, I’d like to parse that pattern and break the email into specific portions that I can use in home assistant. The automation is noticing emails, but it appears an error with my regex causes HA to see an empty field and send nothing. How can I fix this?

Your post wasn’t. The code because it broadcasts using Google network could be. Just be advised. And advise yojr clients to tell thier lawyer and let THEM make that decision.

The US district Court Is very clear that ambulance is covered entity and people who work for ambulance even consultant or volunteer are business partner and therefore HIPAA applies. I would and have advised any fire chief same. The rest is up to thier lawyers. :wink:

I’ve edited my initial post, because apparently it was freaking people out.

Can anyone help me get notifications for my refrigerator repair company??

5 Likes

:rofl: < >

I didn’t see the original post, so I thought you repaired the refrigerators on Ambulances and was wondering while people were freaking out about HIPPA violations for a refrigerator that was dead and needed repair. LOL

3 Likes

I’ve (mostly) got the automation working now. For anyone else who might come across this, here’s some information:

Developer Tools / Template:

{% set email_body = " 266B Something Rd -- Between Fake Ave & Another St - Access: First - Call ID: 1508041230 - Unresponsive"  %}
Email to be parsed:
{{ email_body }}

Regex:
{% set address_matches = email_body | regex_findall('(?m)\\s*(.*?) -- (.*?) - (?:Access: (.*?) - )?Call ID: (\\d{10}) - (.+)') %}
{{ address_matches }}

Parsed Values:
Address: {{ address_matches[0][0] if address_matches else 'Parse Failed' }}
Cross Streets: {{ address_matches[0][1] if address_matches else 'Parse Failed' }}
Access Info: {{ address_matches[0][2] if address_matches else 'Parse Failed' }}
Call ID: {{ address_matches[0][3] if address_matches else 'Parse Failed' }}
Call Type: {{ address_matches[0][4] if address_matches else 'Parse Failed' }}

This is how I was able to confirm that the regex portion of my automation was actually correct. However, I will still getting “:rotating_light: Incoming Emergency Call :rotating_light:,” the default “unknown” alerts. It was also becoming a pain in the neck to keep sending myself emails to test my automation.

Developer Tools / Events:

event_type: imap_content
server: imap.gmail.com
username: [email protected]
sender: [email protected]
#make sure those three lines match your automation's server, username, and sender!
text: "266B Something Rd -- Between Fake Ave &amp; Another St - Access: First - Call ID: 1508041230 - Test call"

This is how you can fire the event and test the automation without sending an email over and over.

It also has a hint to the actual problem I was running into. (FYI, Gemini proved to be the AI agent that seems most familiar with HA’s intricacies.) It seems that

Emails are notorious for containing junk you can’t see, like HTML tags (<b>, <div>), HTML entities (&amp;, &nbsp;), or weird whitespace characters. When you copy-paste the text into the Template tool, that junk often gets cleaned up automatically, which is why it works there.

By changing my variables: block to

- variables:
      email_subject: "{{ trigger.event.data.subject }}"
      email_body: "{{ trigger.event.data.text | replace('\r\n', ' ') | replace('\r', ' ') | replace('\n', ' ') }}"
      raw_email_text: "{{ trigger.event.data.text }}"
      cleaned_email_body: >-
        {{ raw_email_text | striptags | replace('&amp;', '&') |
        regex_replace('\s+', ' ') | trim }}

& becomes &, and the automation now works!

Another change to look out for is the actions at the bottom. I’m on android phones and I want to be able to quickly open the address in google maps.

      data:
        channel: EMT_Dispatch
        importance: high
        priority: high
        ttl: 0
        sticky: true
        tag: emt_dispatch
        actions:
          - action: ACKNOWLEDGE
            title: Acknowledge
          - action: URI
            title: Navigate
            uri: >-
              intent://maps.google.com/maps?daddr={{ parsed_address | urlencode
              }}#Intent;scheme=https;package=com.google.android.apps.maps;end

the action: needs to be URI for the uri: to open an app.

What I’m still stuck on for the moment is the Acknowledge button. I want each of the phones I alert to have this persistent notification until it’s acknowledged. Is there an easy way to get the notify.mobile_app’s “my_phone” ID? I created this automation:

alias: Clear notification
description: Clears the notification on the device that presses "Acknowledge"
triggers:
  - event_type: mobile_app_notification_action
    event_data:
      action: ACKNOWLEDGE
    trigger: event
actions:
  - data:
      message: clear_notification
      data:
        tag: emt_dispatch
    action: notify.mobile_app{{ trigger.event.context.user_id }}
mode: single

but that gets me the error of Error: Action notify.mobile_appf52f0964398c419f80a216f0724c663d not found
Anyone know the proper template, if it exists?

There are a couple ways. I just manually set up a mapping that links the notifier action to an available piece of information like user ID or device ID. This can be done in the automation itself or as a custom macro.

alias: Clear notification
description: Clears the notification on the device that presses "Acknowledge"
triggers:
  - event_type: mobile_app_notification_action
    event_data:
      action: ACKNOWLEDGE
    trigger: event
actions:
  - variables:
      notifiers:
        f52f0964398c419f80a216f0724c663d: dovy_iphone
  - data:
      message: clear_notification
      data:
        tag: emt_dispatch
    action: notify.mobile_app_{{ notifiers.get(trigger.event.context.user_id) }}
mode: single

A more programmatic method could be to use the person entities’ user_id attribute and the device_trackers attribute… but that can get complicated if you have users not attached to person entities, person entities with multiple trackers, or if you have modified the entity ID of the trackers to something that no longer matches the notifier action.

Best case scenario it would require something like:

{{ (states.person
| selectattr('attributes.user_id', 'eq', context.user_id) 
| map(attribute='attributes.device_trackers')
| first)[0] 
| replace('device_tracker.', 'notify.') }}

Close, but if one user_id has two phones, they both will get cleared when either phone "acknowledge"s, and I was looking for each phone to have to clear individually.

Changing this line to action: notify.{{ notifiers.get(trigger.event.data.device_id) }} worked. Thank you!

For other beginners, I used Developer Tools / Events / Listen to events, listened to mobile_app_notification_action, sent a test notification, and pressed the Acknowledge button on each phone to obtain the device_id.

Karen? Is that you?!?

That’s a bit too much in my opinion.
Privacy, especially medical privacy should not be something that we just hope for.
It should be something that is required.

I would say I’m not that bothered with leaving tracks of me on the internet.
But in this case it’s someone else possibly revealing your medical situation that could cost you your job in a worst case scenario.

If you think that is “Karen” then go ahead.
But just make sure you live by the same rules yourself. Post all your medical history for everyone to see so that any current or future employer can see.

2 Likes