Template Trigger for Sensor State Change

Hello,

I am new to this forum but been working with Home Assistant for a while. Just getting around to making more complicated templates and sensors and appreciate any assistance.

Overview: I’m trying to build a smart cat door that lets me know if my two cats are inside or outside. I built a door that has an RFID tag scanner and a contact sensor that only triggers when the cat exits the door to outside. My plan is to trigger a template sensor when a specific RFID tag is scanned (cat entering doorway) and check whether the contact sensor has closed (door opened toward outside and cat leaving) that will then update the sensor to read “Outside,” otherwise if RFID tag scanned and the contact sensor wasn’t closed (cat entering the door), then it reads as “Inside.”

I have created this sensor, which works in the Developer area, but reports an Unknown state in my configuration.

template:
- trigger:
    - platform: state
      entity_id: 'sensor.rfid_info'
      to: '985112011533024'
  sensor:
    - name: "Milo Location"
      state: >
        {% if (now() - (states.sensor.catdoor_last_opened.last_changed) < timedelta(seconds=2)) %}
          Outside
        {% else %}
          Inside
        {% endif %}

template:
- trigger:
    - platform: state
      entity_id: binary_sensor.catio_contact
      from: 'on'
      to: 'off'
  sensor:
    - name: CatDoor Last Opened
      state: "{{now()}}"
  1. I think part of the issue is that it remains unknown until the trigger (RFID tag) is satisfied, leaving the sensor on unknown until that happens. Though, I have also tried scanning the RFID tags and it remains unknown (despite the sensor.rfid_info displaying a tag number in the logs). Is there a way to fix this?
  • One possible issue is that the RFID sensor only displays a tag number in the logs, and not in the history section. I’m not sure why this is occurring and maybe is related to the sensor not being updated by a scanned RFID tag?
  1. I realize that this also only defaults to “Inside” if the sensor reads an RFID tag and the contact sensor isn’t closed, but maybe there is a better way to accomplish this? I am thinking it may be better to separate the RFID reading portion into another separate sensor and use an “AND” statement to both check which RFID tag is scanned and whether the contact is closed.

Overall, I have reached the limit of my abilities despite reviewing the template/trigger documentation. Any assistance is greatly appreciated!

Go to Developer Tools > States and find sensor.rfid_info. What is its value in the State column?

Does this value change when you scan another RFID tag?

You may have more cat-state accuracy using tag_scanned Event triggers instead of State triggers. When triggering off the state of the RFID sensor, you will need to reset the state to a value that is not either of the cats’ RFID after each cat-related state change. For example, if Milo goes inside then outside without Cat 2 following, the ‘out’ event will not be recorded because the state trigger will not fire. “Milo Location” will state “Inside”, even though he is outside. Using an Event trigger should ameliorate that issue.

It currently doesn’t have anything showing in the state column and doesn’t change when I scan an RFID tag. It was previously showing the RFID tag number in the history area when each one was scanned but has stopped doing that for some reason. I will try resetting up the ESP32 I am using with ESPhome for the sensor integration and see if that fixes the reporting issue as I’m assuming when it was recording in the history area it would have also displayed in the state column?

The RFID sensor does switch back to a blank value (unsure what exactly this is recorded as, see photo) after a RFID chip is read, so I don’t think it would have the issue you describe, @Didgeridrew ?

I also am trying to add an MQTT sensor instead of the sensor via ESPhome to see if this helps with the issue and I’ll look into using the tag_scanned events.

Obviously, this situation gives your automation’s State Trigger nothing to trigger on. You’ll need to investigate and correct the problem.

Yeah, I’ll try resetting up the ESP and maybe MQTT will help with that. I didn’t know about this state area (just started using the developer tools) so that is very helpful.

Ok, I reset the ESP32 and tried some other debugging methods.

  1. I set up the ESP to convert the text string to the name of the cat based on their associated tag (I don’t think this changed anything else about how it reports, just makes it easier to work with in home assistant). I set up an automation with these text triggers to notify me when rfid_info state changes to one of the names and it works well without issues, so it must be changing the state without me being able to observe it (as I have it set as reset: true so goes back to blank value).

  2. I set it up so that there are now two individual sensors, “sensor.finn_door” and “sensor.milo_door”, to help simplify the comparison logic in the main sensor for inside/outside (see code below). This also fixed the issue of an unknown state and now shows both cats as “outside,” but I can’t get them to switch to “inside” if I scan a tag and don’t trigger the binary_sensor.catio_contact. There clearly is an issue with my logic at this point.

*** To recap: all the below sensors update correctly including both the cat_door sensors and the patio_contact sensor, though the location sensors are stuck on “outside” if a tag is scanned (without contact sensor triggering). I tried both subtractions, with and without state trigger for sensor, etc without effect.

- sensor:
    - name: "Finn Location"
      state: >
        {% if ((states.sensor.finn_door.last_changed) - (states.sensor.catdoor_last_opened.last_changed) < timedelta(seconds=5)) %}
          Outside
        {% else %}
          Inside
        {% endif %}
        
- trigger:
    - platform: state
      entity_id: sensor.milo_door
  sensor:
    - name: "Milo Location"
      state: >
        {% if ((states.sensor.milo_door.last_changed) - (states.sensor.catdoor_last_opened.last_changed) < timedelta(seconds=5)) %}
          Outside
        {% else %}
          Inside
        {% endif %}

- trigger:
    - platform: state
      entity_id: binary_sensor.catio_contact
      to: 'off'
  sensor:
    - name: CatDoor Last Opened
      state: "{{now()}}"
      
- trigger:
    - platform: state
      entity_id: sensor.rfid_info
      to: 'milo'
  sensor:
    - name: Milo Door
      state: '{{now()}}'

- trigger:
    - platform: state
      entity_id: sensor.rfid_info
      to: 'finn'
  sensor:
    - name: Finn Door
      state: '{{now()}}’

Ok, finally figured it out. Making multiple sensors seemed to simplify the whole thing and make the time comparison easier. Here is my final code in case anybody is looking for something similar:

- trigger:
    - platform: state
      entity_id: sensor.milo_door
  sensor:
    - name: "Milo Location"
      state: >
        {% if ((now() - states.sensor.catdoor_last_opened.last_changed) < timedelta(seconds=200)) %}
          Outside
        {% else %}
          Inside
        {% endif %}

- trigger:
    - platform: state
      entity_id: binary_sensor.catio_contact
      to: 'off'
  sensor:
    - name: CatDoor Last Opened
      state: "{{now()}}"
      
- trigger:
    - platform: state
      entity_id: sensor.rfid_info
      to: 'milo'
  sensor:
    - name: Milo Door
      state: '{{now()}}'

I just copied the same name_door sensor for the other cat.