[email protected]
value_template: >-
{% if ‘dominos pizza order confirmation’ in body %}
order
{% else %}
no_order
{% endif %}
It starts out as unknown, until it receives an email. Then once it receives an email (that matches the value_template, it goes into order, otherwise it goes in no_order. All fine.
Then it goes to states of 13minutes unknown (i guess a gmail thing) and then back to order again (if a pizza was ordered.
How can i make read email in the past 5 minutes or so. Or make a imap mail READ…
# Sensor for School New Email
- platform: imap_email_content
name: School
server: imap.gmail.com
#search: BODY accident
port: 993
username: !secret x_google
password: !secret x_google_pw
folder: Inbox
senders:
- [email protected]
value_template: >-
{% if 'accident' or 'unwell' in body and
(now() - (strptime(date, "%a, %d %b %Y %H:%M:%S %z")) < timedelta(minutes=5)) %}
accident
{% else %}
no_accident
{% endif %}
I got the email yesterday but i missed it as it didn’t include ‘unwell’, then i changed the sensor to also include the above (e.g. and ‘unwell’) then it triggered to accident again at 21:59.
I have no idea why it did that, should it not only parse the last 5 minutes ?
The issue is the construction of your if statement. Strings by themselves are considered true, so when you start your template with if 'accident' or 'unwell' in body...., that get rendered as if TRUE or ('unwell' in body') so it’s always true.
To test multiple terms, you can use multiple in tests i.e.
{% if ('accident' in body or 'illness' in body) and ...
or use the search() function instead, using | between search terms:
....
senders:
- [email protected]
value_template: >-
{% if body is search('accident | illness') and
(now() - (strptime(date, "%a, %d %b %Y %H:%M:%S %z")) < timedelta(minutes=5)) %}
accident
{% else %}
no_accident
{% endif %}
Understood, i will try with search. But even if the string is true, should it not only become true when there is an email from the school in the last 5 minutes ?
No, because the ‘and’ operator has precedence over the ‘or’. So, assuming the email is older than 5 minutes and neither word is in the body of the email, if we show it in steps it renders as follows:
{% if 'accident' or 'unwell' in body and
(now() - (strptime(date, "%a, %d %b %Y %H:%M:%S %z")) < timedelta(minutes=5)) %}
Step 1: Render each clause to TRUE or FALSE
{% if TRUE or FALSE and FALSE %}
Step 2: Since "AND" has precendence, combine those clauses
{% if TRUE or FALSE %}
Step 3: Return the result of the "OR"
TRUE
You can overrule this by using parentheses () around the clauses you want to combine as I did in the example using multiple in tests.
{% if 'accident' or 'unwell' in body and
(now() - (strptime(date, "%a, %d %b %Y %H:%M:%S %z")) < timedelta(minutes=5)) %}
So i understand the a string is always true, and i use ‘accident’ OR ‘unwell’ in body, if the sensor is still active, that is because the AND operator has precedence. But the code after the AND operator only reads only the last 5 minutes right ?
Just in case i get my parentheses mixed up, i think i needed one more ) in your example code? (it didn’t work for me otherwise) i.e. |illness’))
One more question if you wouldn’t mind, does the sensor go to unavailable sometimes? Obviously it is unavailable until it gets an email, but after that it should either be accident or no_accident right?
I have a feeling sometimes gmail looses connection and it goes back to unknown.
Because the IMAP Content integration is based on a Cloud Push mechanism, you can expect the state of the sensor will be ‘unknown’ after every restart of HA or anytime the integration is reloaded. Once an email is received from the sender the state will change to the appropriate value based on the template.
There have been a few times I have noticed that my own IMAP content sensors don’t go back to “unknown” after restart, but I have no idea why that was.