Is webhooks the right answer for multi-garage door automation?

Problem Statement:

I have multi garage doors with different cars in each. I would like for HA to remember which garage door was opened and then closed and who was then marked away, so then upon return it opens the correct door for that person.

Scenerio example:

Wife leaves from garage 1, gone all day, wife returns, home automatically triggers garage 1.

I cant get my head around the configuration of trigger templates / webhooks.

I think I want to create an automation:

Upon garage door opening and closing within 5 minutes, POST who left to a webhook and which garage door (have life360 tracker).

Upon person arrival, check webhook, match person and Door, Open correct Garage door.

I haven’t found how to set this up in a basic enough fashion or I am missing the starting point. 5-6 years ago i was pretty proficient in powershell, but i would consider myself basic at this point when it comes to actual scripting.

If there are some examples that can walk me through getting the bones of this setup, i can trail and error my way forward. Just want to make sure the thought process makes sense and I am not over engineering this.

Events can be given IDs

When automation is triggered you can use

If ID1
Then do xx

You will use device status of phone as the event and provide separate IDs for each. Use that to determine which garage open

If iD_wifephone
Then open garage north

Refer to ID in automations docs

So if the garage Door 1 opens and wife_phone leaves within XX minutes, then store ID1. When wife_phone returns, lookup if IDX exists, then do action?

She is the easy example.

My tough one is me. I will leave with one of 3 cars. I need it to track what i do and then respond in kind, so with this, i guess i can assign a specific ID to each of my scenerios and then have it respond properly, but can I dynamically build the inout and output?

No

When she arrives the device will trigger the automation and the device will have a specified ID.

That ID can be used to trigger a specific door to open.

Typically, the way to save state (e.g., which door opened when a person left) is via a text helper. You can use a service (um, I guess I should say “action” now) to change its value. And then you can read its state later.

Yes, an automation is the way to, well, automate things. :slight_smile: In your use case, it will probably take at least two automations. One to record which door a person used when they left, and then another one to open that door when they arrive back home.

However, it’s a bit more complex than it might sound on the surface, since the automation really needs to use two “events” that happen at different times - i.e., a door opening, and a person leaving. If you try to trigger the automation when the door opens, the person hasn’t left yet. If you wait until the person leaves (i.e., their person or device_tracker entity changes to away, aka not_home), the door may have already closed. Or consider if two people leave at about the same time, where multiple doors are opening/closing and multiple person/device_tracker entities are changing state.

Let’s assume only one person leaves at a time, and the door they leave through is closed by the time another person leaves. The way I would approach it is to trigger the first automation when the person/device_tracker changes to away/not_home. (Actually, I would trigger on the state changing from home to something else. We’ll also ignore the possible unknown or unavailable states, although a robust automation would take those states into account as well.) The action would be to save the door that changed state last to a text helper for that person. The other automation would trigger when the person/device_tracker changes to home, and the action would be to open the door as indicated by that person’s text helper.

That’s the basic idea. Again, getting an automation to do what you want under perfect conditions (e.g., only one person leaves at a time, none of the entities have unknown or unavailable states, HA doesn’t restart while an automatin is running, etc., etc.) is often fairly straightforward. Making them robust can sometimes be the difficult part. But, then again, that’s the way it always is in software development. :rofl:

If you’d like a concrete example of how to build such an automation, just let me know. Also, it would be helpful to know some of the details, like exactly which entities represent the doors and people.

I am going to review the text helper docs and see if i can put something together to achieve my goal. Thank you for your response and will report back my triumphs or failures

1 Like

FWIW, probably the easiest way to determine which door was the last one to change state is via a template. Here’s an example of one way to do that:

{% set doors = [
    states.cover.door1,
    states.cover.door2,
    states.cover.door3
  ]
%}
{% set last_door = (doors|sort(attribute="last_changed"))[-1] %}
{{ last_door.entity_id }}

Thx Phil.

When I go into template editor and enter:

{% set doors = [
states.cover.ratgdov25i_1be829_door,
states.cover.ratgdov25i_1be833_door
]
%}
{% set last_door = (doors|sort(attribute=“last_changed”))[-1] %}
{{ last_door.entity_id }}

I did it with two doors to begin seeing output.

The results to the right show:

Result

Result type: string

cover.ratgdov25i_1be833_door

This template listens for the following state changed events:

  • Entity: cover.ratgdov25i_1be829_door
  • Entity: cover.ratgdov25i_1be833_door

First, it only lists one door on the top part, but does list the two doors below, is that expected?

Dumb question #2, I opened and closed the door, where would the results appear? In the template editor, the results didn’t change as i exercised the door. Should they have?

To your previous post about just outlining how to achieve this, maybe that would be better for my visual mind to see how it works and then i can take it apart piece by piece to understand why it works.

First, when you post YAML/templates/log text/etc., please format it properly so we can read it more easily and characters (such as quotes) aren’t getting changed.

The top part shows the “output” of the template. The bottom part tells you what the template “listens” to to decide when to update its output. So, in this case, when either door changes, the template will be re-evaluated and the output in the top part will be updated to show the new result.

When either door is opened or closed its corresponding cover entity should change, and when that happens, the template output should update as well. Are you sure the cover entities are changing when the doors are opened or closed? You could change the template to the following to show the cover entities, too:

{% set doors = [
  states.cover.ratgdov25i_1be829_door,
  states.cover.ratgdov25i_1be833_door
]
%}
{% set last_door = (doors|sort(attribute="last_changed"))[-1] %}
ratgdov25i_1be829_door: {{ states.cover.ratgdov25i_1be829_door.last_changed|as_local }}
ratgdov25i_1be833_door: {{ states.cover.ratgdov25i_1be833_door.last_changed|as_local }}
last changed: {{ last_door.entity_id }}

This will show when each door last changed, and then which one changed most recently.

I can try to put an example together for the two automations…

:+1:

It now shows the two devices and which changed last.

Result

Result type: string

ratgdov25i_1be829_door: 2024-12-06 07:52:57.699852-05:00 ratgdov25i_1be833_door: 2024-12-05 10:38:54.823963-05:00 last changed: cover.ratgdov25i_1be829_door

This template listens for the following state changed events:

  • Entity: cover.ratgdov25i_1be829_door
  • Entity: cover.ratgdov25i_1be833_door

looking forward to it

But nothing about how it determines which door was the last to open or close changed. So, did it work before, but you just didn’t realize???

Now it states which door changed last as it shows in the results. It doesn’t show what the state was and is now, etc. Just listed the door that changed.

Where I struggle is the storing the proper results.

Meaning the:

Door1 Opens
Wife Away
Store Wife.door1

Wife Home, reference wife.doorX, action open said door

When you used the first template I suggested, you said, “I opened and closed the door, where would the results appear? In the template editor, the results didn’t change as i exercised the door.”

The first template was only designed to show the Entity ID of the door whose state most recently changed (i.e., the door that was opened or closed last.) Yet, you said when you exercised the door, the result of the template did not change.

But now you say with the second template, it does. But that part did not change. So, I’m asking, how could it have not worked before, but it does now?

Yes, the newer template also shows, for each door, the last time it changed. But the first part of the template still does what it did before, which is to indicate which door changed last. So, you are confusing me by your statements.

That is what a text helper is for. The first automation, which is triggered when one of the “people” leaves home, will have an action to store the Entity ID of the door that last changed, using the first template I showed. It would call the input_text.set_value action with the text helper for that person.

How is that called out in the YAML to reference the change?

description: ""
mode: single
triggers:
  - trigger: state
    entity_id:
      - device_tracker.life360_person1
    from: home
    to: not_home
conditions: []
actions:
  - action: input_text.set_value
    metadata: {}
    data: {}

First, thanks for formatting the YAML!

It could be something like this:

- id: save_door_used_when_leaving
  alias: Save door used when leaving
  triggers:
    - trigger: state
      entity_id:
        - device_tracker.life360_person1
        - device_tracker.life360_person2
      from: home
      to: not_home
  actions:
    - action: input_text.set_value
      target:
        entity_id: "input_text.door_{{ trigger.entity_id.removeprefix('device_tracker.life360_') }}"
      data:
        value: >
          {% set doors = [
              states.cover.ratgdov25i_1be829_door,
              states.cover.ratgdov25i_1be833_door
            ]
          %}
          {% set last_door = (doors|sort(attribute="last_changed"))[-1] %}
          {{ last_door.entity_id }}

This assumes there is an input_text for each person, where the end of the Entity ID matches the end of the corresponding device_tracker Entity ID. If it’s not that straightforward, then there are a few easy ways to deal with that.

When I dropped that into a new Automation in the UI switched to edit YAML, i get eh following error attempting to save so I can test / debug.

“Only automations in automations.yaml are editable”

Then it just kicks me out.

Should i be creating a folder in /Config/Misc/ and then adding TEST.YAML under there?

From what i quickly read, then the UI can no longer see it.

If you want to use the UI to create this automation, then you need to copy the appropriate bits from the YAML above into their corresponding places, piece by piece.

Or you can just drop the automation into automations.yaml (which sits next to configuration.yaml in your config directory.) Note that this file contains a list of automations, so you’ll need to put a dash (“-”) before the first line (with everything else indented accordingly.)

Oh, and I just realized I used the description key instead of alias. I’ll edit the automation above to fix that and add the dash. Then you’ll be able to put it directly into your automations.yaml file. (BTW, if that file just contains one line which is “[]”, you can just delete that and add the automation.)

Or you can leave out the id (and alias) key. Try adding this to a new automation, editing in YAML mode:

triggers:
  - trigger: state
    entity_id:
      - device_tracker.life360_person1
      - device_tracker.life360_person2
    from: home
    to: not_home
actions:
  - action: input_text.set_value
    target:
      entity_id: "input_text.door_{{ trigger.entity_id.removeprefix('device_tracker.life360_') }}"
    data:
      value: >
        {% set doors = [
            states.cover.ratgdov25i_1be829_door,
            states.cover.ratgdov25i_1be833_door
          ]
        %}
        {% set last_door = (doors|sort(attribute="last_changed"))[-1] %}
        {{ last_door.entity_id }}

Thank you again for the continued help here @pnbruckner .

So I got the above to be added using the UI in YAML mode.

How do I now build an Automation to now call the stored output.

This is directly calling one door if either of us go from AWAY to HOME.

How can I call last_door.entity_id to then populate whom left and what to trigger?

alias: Garage Away->Home
description: Open garage door when Person Arrives
triggers:
  - trigger: state
    entity_id:
      - device_tracker.life360_Person1
    from: not_home
    to: home
  - trigger: state
    entity_id:
      - device_tracker.life360_Person2
    from: not_home
    to: home
conditions: []
actions:
  - device_id: 4ca9c8777268882a2af9a4361fb2fc68
    domain: cover
    entity_id: a5975c28ed568dd2946a4be43338f9a0
    type: open
mode: single

triggers:
  - trigger: state
    entity_id:
      - device_tracker.life360_person1
      - device_tracker.life360_person2
    from: not_home
    to: home
actions:
  - action: cover.open_cover
    target:
      entity_id: "{{ states('input_text.door_' ~ trigger.entity_id.removeprefix('device_tracker.life360_')) }}"