How to save a Variable, triggered by an event

Hello

I am an average programer and I need some help please.
I have a problem that I thought would be easy but it appears to be difficult to solve. ( or I am making it hard)

I have a water tank level meter
I have 5 inputs. Full, 3/4, 1/2, 1/4, 0
Due to corrosion concerns I turn the power on to the level sensor for 10 sec, get the level reading and then turn it off.

When the power is on to this system I need to take the value that is read, either 5, 4, 3, 2, 1 and save it as a variable.

This is what I am struggling with.

I am using and ESPHome device to deliver these levels to HA.

I have tried an automation but I cannot get the value to stick.

Here is my code

When the switch.water_relay = ON
Then I need the sensor.water_tank_level value to be saved to sensor.water_tank_level_store_2

automation:

  • alias: “Water tank Store 3”
    trigger:
    platform: state
    entity_id: switch.water_relay
    to: “on”
    action:
    • service: input_number.set_value
      target:
      entity_id: input_number.water_level_stored
      data:
      sensor.water_tank_level_store_2: “{{ states(‘states.sensor.water_tank_level.state’) | int }}”

Use a trigger based template sensor:

https://www.home-assistant.io/integrations/template/#trigger-based-template-sensors

Your trigger is the relay state to: 'on'.

Your template for the state will be:

state: "{{ states('sensor.water_tank_level') | int }}"

So putting that all together:

template:
  - trigger:
      - platform: state
        entity_id: switch.water_relay
        to: 'on'
    sensor:
      - name: Water Level
        state: "{{ states('sensor.water_tank_level') | int }}"
        unit_of_measurement: ' ' # if you want a history graph

We could get fancy and convert that to % full if you want.

    sensor:
      - name: Water Level
        state: >
          {% set level = states('sensor.water_tank_level') | int %}
          {% if level == 5 %}
            100
          {% elif level == 4 %}
            75
          {% elif level == 3 %}
            50
          {% elif level == 2 %}
            25
          {% elif level == 1 %}
            0
          {% else %}
            unknown
          {% endif %}

        unit_of_measurement: '%'

Also when pasting code, please format it correctly. See point 11 here How to help us help you - or How to ask a good question

Hi Tom

Thank you for your help

This works well but I need the sensor.water_tank_level value to be saved to sensor.water_tank_level_store_2

How would you suggest I do that?

Andy

Why that particular sensor?

Does it exist already?

If not, and only if not, just change the template sensor name:

      - name: Water Tank Level Store 2

That will generate entity_id sensor.water_tank_level_store_2

Good question.
When the Relay is off, the sensor.water_tank_level = 5 ( because there is no power to energise the sensors)
When the relay is on it gives the real reading for the tank level. Currently 3.
Therefore when the relay is on, it reads the true value of the tank level.

Is this an OK explanation ?

We can take that into account by checking the relay state in the template. Do you want the % level or just the integer (1-5)?

I do not mind if I have % or not right now but I will use it going forward.

I use the Numeric value for an E-paper display to give me a level indicator ( 5 vertical dots )

Actually when the relay is off the triggered template sensor won’t update. It only updates when the relay turns on. So there is nothing to change.

Ok, I was not sure about that buy it is not the case

This is when the replay is in the off state

This is in the ON state

In the off state , sensor.water_tank_level does not retain the value

That’s strange, I wonder if your relay contact is bouncing. Try this trigger:

template:
  - trigger:
      - platform: state
        entity_id: switch.water_relay
        to: 'on'
        for: 1

Because the sensor.water_tank_level changes when the relay ( power) is of, I need to store that value some how.

I need to do this but I do not know how.
I need a funtion that does this
When the relay is ON, sensor.water_tank_level_store_2 = sensor.water_tank_level

Then when the relay goes of, sensor.water_tank_level_store_2 retains the level value.

How would you suggest I do that?

Exactly as I have explained. The trigger template sensor only updates when the relay turns on.

EDIT: I see what you are saying now.

That’s odd the template sensor state should be retained when the rely turns off. Let me try a few things.

OK, now I understand.

That is not what I am seeing here.

At turn on it updates and at turn off it updates.

Try this trigger:

template:
  - trigger:
      - platform: state
        entity_id: switch.water_relay
        from: 'off'
        to: 'on'
        for: 1

If that does not work we can use this in the template:

template:
  - trigger:
      - platform: state
        entity_id: switch.water_relay
        from: 'off'
        to: 'on'
        for: 1
    sensor:
      - name: Water Tank Level Store 2
        unit_of_measurement: '%'
        state: >
          {% set level = states('sensor.water_tank_level') | int %}
          {% if is_state('switch.water_relay', 'on') %}
            {% if level == 5 %}
              100
            {% elif level == 4 %}
              75
            {% elif level == 3 %}
              50
            {% elif level == 2 %}
              25
            {% elif level == 1 %}
              0
            {% else %}
              unknown
            {% endif %}
          {% else %}
            {{ states('sensor.water_tank_level_store_2') }}
          {% endif %}

But we really shouldn’t have to (it triggers when the relay is on, so the “if relay on” test should not be required. If this is the only thing that works we need to open an issue.

Thanks Tom

I am testing this now.
No instant success yet.

If that second template with the relay on test is the only thing that works we can remove the trigger altogether:

template:
  - sensor:
      - name: Water Tank Level Store 2
        unit_of_measurement: '%'
        state: >
          {% set level = states('sensor.water_tank_level') | int %}
          {% if is_state('switch.water_relay', 'on') %}
            {% if level == 5 %}
              100
            {% elif level == 4 %}
              75
            {% elif level == 3 %}
              50
            {% elif level == 2 %}
              25
            {% elif level == 1 %}
              0
            {% else %}
              unknown
            {% endif %}
          {% else %}
            {{ states('sensor.water_tank_level_store_2') }}
          {% endif %}

This will update on any change of the water tank level but will only store the value if the relay is on, otherwise it will keep the old value.

Hi Tom

Thanks for your help but no luck sorry.
I still cannot keep that value for sensor.water_tank_level after the relay is off.
When the relay is on, it reads fine ( i see a value of 3 ) but when the relay is off it goes back to 5.

I am lost
I was hoping I could do something like this
When the relay is ON, sensor.water_tank_level_store_2 = sensor.water_tank_level

That is exactly what this does:

template:
  - sensor:
      - name: Water Tank Level Store 2
        unit_of_measurement: '%'
        state: >
          {% set level = states('sensor.water_tank_level') | int %}
          {% if is_state('switch.water_relay', 'on') %}
            {% if level == 5 %}
              100
            {% elif level == 4 %}
              75
            {% elif level == 3 %}
              50
            {% elif level == 2 %}
              25
            {% elif level == 1 %}
              0
            {% else %}
              unknown
            {% endif %}
          {% else %}
            {{ states('sensor.water_tank_level_store_2') }}
          {% endif %}

I have tested and use this format many times, though admittedly not with the new template format. Lets try the legacy format, put this under your sensor: definition in configuration.yaml, or in your sensor.yaml file if you use !includes.

- platform: template
  sensors:
    sensor.water_tank_level_store_2:
      friendly_name: 'Water Tank Level Store 2'
      unit_of_measurement: '%'
      value_template: >
          {% set level = states('sensor.water_tank_level') | int %}
          {% if is_state('switch.water_relay', 'on') %}
            {% if level == 5 %}
              100
            {% elif level == 4 %}
              75
            {% elif level == 3 %}
              50
            {% elif level == 2 %}
              25
            {% elif level == 1 %}
              0
            {% else %}
              unknown
            {% endif %}
          {% else %}
            {{ states('sensor.water_tank_level_store_2') }}
          {% endif %}

Don’t forget to delete the old template sensor.

I deleted the template from the automations

I inserted the content above into the sensor.yaml and ( checked config) restarted
The sensor.water_tank_level_store_2 now continually says , unknown…

Wait, let me correct this. give me 5 mins