IMAP Content Sensor

Can somebody help me to get a working template sensor from the body of a Imap Content sensor?
The Imap Sensor looks like this:

from: [email protected]
subject: Sensoren
date: 'Thu, 22 Apr 2021 18:00:51 +0200'
body: "    26.9C\r\n  10.09pH\r\n    154mV\r\n    4.1mS\r\n\x03\r\n\r\n"
friendly_name: Profilux Raw

Its from a Aquarium Computer. I want to have the Temperature, the pH, EC and Redox in my Home Assistant.

Here are the sensors:

- platform: template
    sensors:
      temp_profilux:
        friendly_name: Temperatur Profilux
        unit_of_measurement: °C
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9].+[0-9])', index=0) }}"
      ph_profilux:
        friendly_name: pH Profilux
        unit_of_measurement: pH
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9].+[0-9])', index=1) }}"
      redox_profilux:
        friendly_name: Redox Profilux
        unit_of_measurement: mV
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9]+[0-9])', index=2) }}"
      ec_profilux:
        friendly_name: EC Profilux
        unit_of_measurement: mS
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9].+[0-9])', index=3) }}"

Everythings good. Except the Redox Sensor. Can somebody see my fault?
Would be really nice if somebody could help me.

A little bitty period.

([0-9].+[0-9])
([0-9]+[0-9])

I’m no regex expert, but with trial and error i found this:

Note the indexes.
Maybe one with more regex fu can explain?

Ok thanks for the answers. After reading a lot i think i understand the regex_findall_index function.
With ([0-9].+[0-9]) he searchs for a number with a point. The index is the number of the hit. So Index=0 is the first hit. And Index=1 is the second and so on.
The Problems come when the pH Value goes exactly on 10. So the dot dissappears. And another problem is when the Redox Value goes under 100mV.
I found a really dirty solution. I search for the unit.
Than i make another sensor that only searchs for the numbers. :smiley:
Its dirty but i hope it works.
I friend of mine said that for me the regex function is stupid. He said that my value for Temperature is always in row 1 the Value for pH always in row 2 and so on.
But i dont know a other function.

So here is my dirty solution:

  - platform: template
    sensors:
      temp_profilux_con:
        friendly_name: Temperatur Profilux Con
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9].+C)', index=0) }}"
      temp_profilux:
        friendly_name: Temperatur Profilux
        unit_of_measurement: °C
        value_template: "{{ states('sensor.temp_profilux_con') | regex_findall_index(find='([0-9].+[0-9])', index=0) }}"
      ph_profilux_con:
        friendly_name: pH Profilux Con
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9].+pH)', index=0) }}"
      ph_profilux:
        friendly_name: pH Profilux
        unit_of_measurement: pH
        value_template: "{{ states('sensor.ph_profilux_con') | regex_findall_index(find='([0-9].+[0-9])', index=0) }}"
      redox_profilux_con:
        friendly_name: Redox Profilux Con
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9]+[0-9]mV)', index=0) }}"
      redox_profilux:
        friendly_name: Redox Profilux
        unit_of_measurement: mV
        value_template: "{{ states('sensor.redox_profilux_con') | regex_findall_index(find='([0-9]+)', index=0) }}"
      ec_profilux_con:
        friendly_name: EC Profilux Con
        value_template: "{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='([0-9].+mS)', index=0) }}"
      ec_profilux:
        friendly_name: EC Profilux
        unit_of_measurement: mS
        value_template: "{{ states('sensor.ec_profilux_con') | regex_findall_index(find='([0-9].+[0-9])', index=0) }}"

Hey guys maybe i found a good solution:
When a add a space to the find= function, i define a clear border between the values. The problem was always that one value goes smooth and the find index was wrong. So with the Space i have a clean seperation.

{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='( +[0-9].+[0-9])', index=0)
{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='( +[0-9].+[0-9])', index=1)
{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='( +[0-9].+[0-9])', index=2)
{{ state_attr('sensor.profilux_raw','body') | regex_findall_index(find='( +[0-9].+[0-9])', index=3)

hello

I also have a profilux 4 and I am looking to do its integration (reading the parameters) in HA. can you tell me how you proceeded STP

So first you create an email account that is only for the sensor data. Then you go to the configuration.yaml and add the following under sensor::

  - platform: imap_email_content
    name: Profilux Tunnel Raw
    server: imap.gmx.net 
    port: 993
    username: [email protected]
    password: yourpassword
    senders:
      - [email protected]  

You also use this email as sender in Profilux. There you have to send a mail every X minutes which contains the sensor data.

If that worked, you should have an entity in Home Assistant that is named after “Name” you assigned.

Then you can create a few template sensors. These must also be added to our sensor in configuration.yaml

  - platform: template
    sensors:
      temp_profilux_tunnel:
        friendly_name: Temperatur Profilux Tunnel
        value_template: "{{ (state_attr('sensor.profilux_tunnel_raw','body') | regex_findall_index(find='([0-9].*C)', index=0))[:-1] }}"
        unit_of_measurement: °C
      ph_profilux_tunnel:
        friendly_name: pH Profilux Tunnel
        value_template: "{{ (state_attr('sensor.profilux_tunnel_raw','body') | regex_findall_index(find='([0-9].*pH)', index=0))[:-2] }}"
        unit_of_measurement: pH
      redox_profilux_tunnel:
        friendly_name: Redox Profilux Tunnel
        value_template: "{{ (state_attr('sensor.profilux_tunnel_raw','body') | regex_findall_index(find='([+-]?[0-9].*mV)', index=0))[:-2] }}"
        unit_of_measurement: mV
      ec_profilux_tunnel:
        friendly_name: EC Profilux Tunnel
        value_template: "{{ (state_attr('sensor.profilux_tunnel_raw','body') | regex_findall_index(find='([0-9].*mS)', index=0))[:-2] }}"
        unit_of_measurement: mS

The last thing to do is to run a Python script periodically which deletes all mails except the two most recent ones. But we will get to that when it works :smiley:

Thank you for your quick response. I’m testing this :wink:

Hello, well I have a little advanced… The mail entity goes back well the data sensors are created but no data goes back … Surely a problem in the format of the email sent by the profilux an idea ?

So you say the raw email sensor is good? But the filtered template sensors are not working? If that is the Case, send me a screenshot from the state in developer tools. Like this picture. But note that my Profilux is for months offline. Because i only use it from spring to autum. So yours should be looking diffrent. I need the Value from the attribute “body”.

So your email sensor is not working. Do you have the mails in your inbox?

Yes emails are available

ok i m reboot now

body: “Temperature 1 : 22.1C\r\nvaleur-pH 1 : 7.90pH\r\nRedox 1 : 244mV\r\nConduct. (S) 1 : 29.3\r\n¿c\x01\r\n\r\n”

It’s ok now the data is coming thanks

Are the template Sensors working?
If yes. Then we need to setup the Pythonscript to delete all old mails except the two newest.
Because if you reboot, the Mail Sensor starts from the oldest Mails and and will go through every mail. It is a bit stupid and will destroy your history. Thats the reason i created a separate Mailaddress because other Mails in the Inbox can fuck up the delete script.

ok thank you I am a script taker but I have no python skills :sweat_smile:

Me neither. My cousin wrote it for me :smiley:.

MAIL_SERVER = 'imap.gmx.net'
USERNAME = 'algen****@gmx.de'
PASSWORD = '******'
MAILBOX = 'INBOX'


import imaplib


imap = imaplib.IMAP4_SSL(MAIL_SERVER)
imap.login(USERNAME, PASSWORD)
imap.select(MAILBOX)
typ, data = imap.sort('DATE', 'UTF-8', 'ALL')
# imap.search(None, 'ALL', search_args)

ids = data[0]  # data is a list.
id_list = ids.split()  # ids is a space separated string 
id_list.pop()
id_list.pop()
id_list.pop()
id_list.pop()


for num in id_list:
    imap.store(num, '+FLAGS', '\\Deleted')

imap.expunge()

imap.close()
imap.logout()

I had some problems with a diffrent Mailprovider. The Mail delete didnt worked. But after the switch everything worked.

Here you can find a instruction to run the python script.
I think this script keeps the 4 newest Mails.

thank again for your help