I have a binary sensor defined which uses the IMAP integration. It’s been working OK until recently, but I just noticed that it has stopped working, and the sensor state is “unavailable”.
When I restart HA I get this error in the log:
2023-10-28 10:17:11.376 ERROR (MainThread) [homeassistant.helpers.binary_sensor] Error rendering state template for binary_sensor.parking_booking: AttributeError: 'bool' object has no attribute 'lower'
The definition is below. I’m running HA Core 2023.10.1.
Any idea how I can fix this?
template:
- trigger:
- platform: event
event_type: "imap_content"
event_data:
sender: "[email protected]"
- platform: event
event_type: "imap_content"
event_data:
sender: "[email protected]"
- platform: event
event_type: "imap_content"
event_data:
sender: "[email protected]"
- platform: event
event_type: "imap_content"
event_data:
sender: "[email protected]"
binary_sensor:
- name: Parking Booking
auto_off: "00:02:00"
state: >
{% if trigger.event.data['subject'] is match
"You have a new booking|Booking received|JustPark booking|Booking request for My Road" and is_state(trigger.event.data['initial'], "True")
%}
true
{% endif %}
The is_state() function expects an entity ID as the first argument… trigger.event.data['initial'] returns True/False, not an entity ID. Just compare the trigger variable to your desired value.
{{ trigger.event.data['subject'] is match("You have a new booking|Booking received|JustPark booking|Booking request for My Road")
and trigger.event.data['initial'] == "True" }}
Hmmm…so I changed the sensor definition to the code below. I no longer see an error in the log, but the sensor is “unavailable” and doesn’t seem to be triggering
???
binary_sensor:
- name: Parking Booking
auto_off: "00:02:00"
state: >
{{ trigger.event.data['subject'] is match("You have a new booking|Booking received|JustPark booking|Booking request for My Road") and trigger.event.data['initial'] == "True" }}
true
{% endif %}
The above is unnecessary and is breaking the template. There is no reason to use an if statement when everything fits in a single boolean expression.
binary_sensor:
- name: Parking Booking
auto_off: "00:02:00"
state: >
{{ trigger.event.data['subject'] is match("You have a new booking|Booking received|JustPark booking|Booking request for My Road")
and trigger.event.data['initial'] == "True" }}
Sorry to trouble you again, but I still seem to be getting something wrong. I now have the sensor defined as below. It doesn’t give any errors, but it NEVER triggers:
binary_sensor:
- name: Parking Booking
auto_off: "00:02:00"
state: >
{{ trigger.event.data['subject'] is match("You have a new booking|Booking received|JustPark booking|Booking request for My Road") and trigger.event.data['initial'] == "True" }}
If I remove the 2nd condition it triggers fine:
binary_sensor:
- name: Parking Booking
auto_off: "00:02:00"
state: >
{{ trigger.event.data['subject'] is match("You have a new booking|Booking received|JustPark booking|Booking request for My Road") }}
…but will trigger multiple times (hence why I need to add the “initial” attribute. This attribute is described in the documentation as follows:
“initial
Returns True if this is the initial event for the last message received. When a message within the search scope is removed and the last message received has not been changed, then an imap_content event is generated and the initial property is set to False. Note that if no Message-ID header was set on the triggering email, the initial property will always be set to True.”
It looks like it’s just a boolean-string comparison issue. I have tested using the trigger variable as a boolean as follows:
binary_sensor:
- name: Parking Booking
auto_off: "00:02:00"
state: >
{{ trigger.event.data['subject'] is match("You have a new booking|Booking received|JustPark booking|Booking request for My Road")
and trigger.event.data['initial'] }}
However, make sure you understand how the initial tag actually works.