How to create a automation, each time a floating value reaches the next integer value

How can I create a message, when my rain gauge reaches (from here: ☔ DIY Zigbee rain gauge - #450 by FrankRy) the next integer value? e.g. when there is a another mm of rain reached ?

I’m not sure how you’ll do this but this idea came to me:

Could you create a sensor that is the internet part of your rain measurement.

Then, have a derivative sensor that detects the rapid increases when the above sensor goes from one integer to the next.

To determine if the rainfall value is an integer, use the modulo operator.

Assuming rainfall is reported by sensor.rainfall you can use a template like this to determine if its value is an integer.

{{ states('sensor.rainfall') | float(0) % 1 == 0 }}

Basically, it’s using integer division to determine if the value has a remainder. If the remainder is zero then it means the value is an integer. Depending on your application, the template can be used in a Template Condition or Template Trigger (or wherever else needed).

You can test it by copy-pasting the following into the Template Editor and observing the result:

{{ 5.6 % 1 == 0 }}
{{ 5.0 % 1 == 0 }}
1 Like

use the sensor entity and calculate the modulus value. if the modulus is 0 then it’s an integer.

{{ states('sensor.your_rain_sensor') | float % 1 == 0 }}

Edit:

123 beat me to it.

Thanks for all your suggestions. I’m not sure if this is what I want. I actually don’t want to know whether number is a integer as such (modulo 0). I want to know when another mm of rainfall happened. My gauge has exactly 0.3mm increases. So it’s value will only be a integer every 10th flip =3mm.
Values are: 0,0.3,0.6,0.9,1.2,1.5,1.8,2.1 …3.0,3.3 and so forth.

OK, the first post clearly stated ‘when the rain gauge reaches the next integer value’ but, in your follow-up post, you stated that’s not actually what you want:

What you want appears to be to simply detect when more rain has fallen:

On first glance, a simple State Trigger would serve to indicate when the rainfall changed. However, since you didn’t use a State Trigger, the requirements must be more complex than what a ‘first glance’ suggests. Can you explain what must happen to the rainfall value in order for it to trigger the automation?

Thanks to your reply 123 Taras.
Unfortunately, I expressed myself a bit unclearly, and I apologize for that. Let me try again: I have a rain sensor with a resolution of 0.3mm of rain. Now, I want to trigger an automation (e.g., a message to my phone) when an additional 1mm of rain has fallen. Essentially, the automation should respond to a change in the integer value of the total accumulated rainfall. I hope that was more understandable?

alias: example
trigger:
  - platform: state
    entity_id: sensor.rainfall
    to:
condition:
  - condition: template
    value_template: >
      {{ trigger.to_state.state | float(0) - trigger.from_state.state | float(0) >= 1 }}
action:
  - service: notify.whatever
    data:
      title: Rainfall Increase
      message: "Rainfall increased by {{ trigger.from_state.state | float(0) - trigger.to_state.state | float(0) }} mm."

EDIT

Correction. Reversed from_state and to_state.

Wow - Thanks a lot! Just entered this in my automation. Now waiting for the rain to confirm it works ¨::slight_smile:

How it works:

The State Trigger detects any changes to the state value of sensor.rainfall.

The State Trigger subtracts the previous state value of sensor.rainfall from its new value. If the result of the subtraction is greater than or equal to 1 it means the rainfall has increased by 1 mm since the last measurement.

I italicized that last part because it means rainfall has to increase by a full millimeter from one reading to the next in order to fulfill the State Condition. That might not be what you want.

For example, if you encounter rain showers that deposits 1, 2, or more millimeters over a period of say three hours, reported as multiple increments of 0.3 mm each, the State Condition will not be fulfilled. It’s looking for an increase of 1 full millimeter from one measurement to the next.

If that’s not how you want it to work, then you will have to take time into consideration. In other words, not merely an increase of rainfall but also a specific period of time in which it accumulates (perhaps in a day or a certain number of hours). That strategy will probably involve the use of the History Stats Sensor or something similar to track accumulation over time.

Thank you for your explanations, ‘123 Taras.’ While I appreciate your code and grasp its concepts, it doesn’t produce the desired behavior I was hoping for. My understanding is that ‘trigger.to_state.state - trigger.from_state.state’ always results in a 0.3mm increase in the ‘sensor.rainfall’ value. As a result, the condition never evaluates to true.

My intention is for the trigger to activate whenever the ‘sensor.rainfall’ value changes to a specific range, which I refer to as a ‘yellow value.’ By ‘yellow value,’ I mean a change in either the positions before the decimal point or the integer part of the ‘sensor.rainfall’ value. That’s why I mentioned the term ‘integer’ in my initial post.

I try now with this code:

Configuration.yaml:

- name: Rainfall today integer
        unit_of_measurement: mm
        state_class: total_increasing
        unique_id: rainfall_today_integer
        state: >-
          {% set count = states('sensor.rainsensor_flips') | int(0) %}
          {% set mm = count * 0.30303 %}
          {% if count >= 0 %}
             {{ mm|int }}
          {% endif %}

Automation:

alias: Rainfall increase alarm
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.rainfall_today_integer
condition: []
action:
  - service: notify.mobile_app_iphone_steph
    data:
      message: Rainfall increased by 1mm to {{ sensor.rainfall_today_integer }}
mode: single

Not sure whether it works ? :slight_smile:

That table helps to clarify your usage of the word “integer”.

alias: Rainfall increase alarm
description: ""
trigger:
  - platform: state
    entity_id: sensor.rainsensor_flips
    to:
condition:
  - condition: template
    value_template: >
      {{ (trigger.to_state.state | float(0) // 1) >  (trigger.from_state.state | float(0) // 1) }}
action:
  - service: notify.mobile_app_iphone_steph
    data:
      message: 'Rainfall increased by 1mm to {{ trigger.to_state.state }}'
mode: single

Thanks. I’ve got it solved by my approach :slight_smile:

When using your suggestion, I get the following error:

Call a service ‘Notifications: Send a notification via mobile_app_iphone_steph’ on
“Error rendering data template: UndefinedError: ‘dict object’ has no attribute ‘to_state’”

The’ to_state’ object seems not to be accessible in the context.

It is accessible because the automation employs a State Trigger and trigger.to_state is one of the properties of a State Trigger. It’s documented here.

How did you test the automation? If you executed it via its Run command, that’s an incorrect testing procedure and would cause it to fail.

Any automation that references the trigger object cannot be tested via the Run command (because the Run command skips the automation’s trigger and condition sections). That’s documented here.

The Run command would only execute the automation’s action where it would encounter a reference to the undefined trigger object and produce the error message you reported.

Wow, I’m truly impressed by your expertise! Your analysis is indeed spot on. I executed it through the Run command, and unfortunately, as you predicted, it failed. Now, I’ll patiently wait for the rain and eagerly anticipate the results!

Thank you so much for your tremendous effort and the invaluable knowledge you’ve shared with me.

1 Like