I am trying to improve an automation I have which gives an announcement when a sensor value is above certain levels.
In order to optimise, I need to be able to extract the last three digits of the sensor value. E.g. if the value is 21345, I want to use 345 in the condition of the automation.
Thanks for the tip, what Iâm trying to do is make a condition that each time the value of the last three digits is >100 make one announcement, then again when itâs over 500, make an announcement e.g.
25123 make announcement
25543 make announcement
24789 make announcement
26101 make announcement
The first 2-3 digits can be anything and are not part of the condition, only when the values go above 100, then again above 500.
It would be helpful if you describe the goals, function, and design of the automation as you see it. It seems like you want the condition to pass when the last three digitsâ have any value above 99⊠but I donât think thatâs really what you want.
Does the value only increase, or does it fluctuate up and down?
Should the condition pass for value changes in both directions?
If it is numbers, then %1000
% instead of / is just a division, but instead of returning the normal result it will return the rest of an integer division, ie. 25123%1000=123
Thanks @WallyR that does indeed get the last three digits, now I need to work out the conditions.
@Didgeridrew here is my current automation which works, and hopefully shows what I am trying to achieve. The question is how can I get rid of all the numeric_state triggers and replace with a more efficient way of achieving the same result. Currently there are lots more triggers than listed below, which I have cut out to make it more readable here. The sensor value can go up & down.
Then use the value of trigger.id in the action if you need to give different messages. If you donât need that, you can remove the id: lines.
This might not trigger as you expect, though. If the sensor goes from say 42000 to 42150, the â>100â trigger will fire. If it then goes from 42150 to 43120, I donât think anything will happen.
If you care about that, you need to work out a description of what you want to happen in such cases. Perhaps this for 100, which will fire for every state change above xx100:
trigger:
- platform: state
entity_id: sensor.mysensor
condition:
- "{{ trigger.to_state.state|int(0) % 1000 > 100 }}"
action:
ACTION HERE
Add some examples when you donât want an announcement.
And it now triggers based on the 100/500 values. However, it now triggers every time the sensor is updated where >500 is true e.g. if the sensor updates to 550, itâs trigger, 600 itâs triggered etc
On my original method above, it only triggered once per trigger value. Is there a way to replicate that? So stop it triggering again until it reaches the next value (100 or 500)?
It is a using int as a way to round, so you only get the hundreds digit.
You can remove the last *100 if you want to use a single digit in your triggers instead, so 5 for 500 and 2 for 200 and so on.
You can also do it with a round function if you want. The important thing here is that it stays at the same number in the hundred interval.
Thanks for the tip, I can get the value using the method I mentioned above, the problem now is as belowâŠ
It would be very rare for that to happen, so I donât mind if 23500+ announcement was skipped and just the 24120 announcement was made.
At the moment, if the sensor value is above 100, itâs being triggered, if above 500, itâs being triggered twice after it updates (once for the 100 and one for the 500 trigger).
I would like it to trigger once when the value goes above xx100, then not trigger again until the value goes above xx500. That could be either;
The calculation I made will give you 100,200,300 and so on as result. (if you removed the *100, then it would be 1,2,3 and so on)
If your trigger is made to trigger on the value and not with the above attribute, then you should work.
trigger:
- platform: state
entity_id: sensor.mysensor
condition:
- condition: template
value_template: >
{% set old = trigger.from_state.state %}
{% set new = trigger.to_state.state %}
{% set oldpre = old[:-3] %}
{% set newpre = new[:-3] %}
{% set oldsuf = old[-3:]|int %}
{% set newsuf = new[-3:]|int %}
{{ (oldsuf <= 100 and newsuf > 100) or
(oldsuf <= 500 and newsuf > 500) or
(oldpre != newpre and newsuf > 100) or
(oldpre != newpre and newsuf > 500) }}
action:
- NOTIFICATION HERE
The four lines of logic should cover cases like:
23080 » 23105
23480 » 23510
23150 » 24120
23550 » 24510
It relies on the sensor state always being a numeric string of at least three digits.
It will also trigger on e.g. 25600 » 23105 (old prefix different from new, suffix above 100). If you donât want that, either tweak the logic above or explain the rules in even more detail.
The first digits are part of the condition if we need to use them to distinguish 23120 » 23250 (no action) versus 23120 » 24250 (action).
You havenât answered either of these important questions. Iâve assumed either in my logic, taking the prefix part of the sensor state as a âtokenâ, not caring what its numeric value is but only comparing before and after.
Thanks for the updated conditions and your time on this (I am learning a lot by seeing them), I will test them out later.
Yes, the sensor value goes up and down and the condition should pass in both directions. The likely range of the sensor is between 1,000 to 1,000,000 (unlikely to go outside of that range).
It should trigger for both rising and falling values. It would be great if I could tell if it was a rise or fall in the action but thatâs more of a nice to have than must have.
Using the new conditions, the sensor value has just changed from 20933 to 21263 (which should have triggered) but it didnât trigger, trace says it failed a condition.