-
Notifications
You must be signed in to change notification settings - Fork 58
-
I have a sensor that normally returns a value, but once in an while is ́unavailable ́. Therefore I get Exceptions errors in my log like the one here:
Exception in <file.nas1.NAS_drive_temperature @state_trigger()> line 1: float(sensor.nas1_drive_1_temperature) >= 60 or float(sensor.nas1_drive_2_temperature) >= 60 ^ ValueError: could not convert string to float: 'unavailable'
The goal is to watch for over temperature, so nothing breaks, but it ends up in my log file.
In HA the template float and int conversion do have a default value, that would be nice to have in pyscript, but this might be difficult to implement.
Instead, the current state_trigger function can catch any ValueError exception, and the new default value will be taken. The new code could look like this:
@state_trigger("float(sensor.nas1_temperature) >= 60", default=False)
In this case any failed conversion will result in False, and thus no triggering.
In case you define default = True, the state_trigger is triggered and you have to deal with this in your code.
@state_trigger("float(sensor.nas1_temperature) >= 60", default=True)
def NAS_cpu_temperature(default=None):
if default: # a ValueError was thrown during conversion
if sensor.nas1_temperature == 'unavailable':
# do something
Is this doable? Maybe we should also get access to what exception was thrown?
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment 5 replies
-
Yes, it's not possible to directly catch exceptions in the trigger expression. I don't think having a default that applies to all exceptions is a good idea - there could be exceptions that you do want reported as errors.
One solution is to put any logic you want, including a try...except
, in a separate function and simply call it from the trigger expression. This gives you the full flexibility to handle exceptions in whatever manner you wish. You should pass the entity as an argument so that @state_trigger
can pick up which entity(ies) to watch.
A simpler approach is to just make your expression more robust to the various values the entity can take. If "unavailable"
is the only non-numeric value, then you could do this:
@state_trigger("sensor.nas1_temperature == 'unavailable' or float(sensor.nas1_temperature) >= 60")
if you do want to trigger when it's "unavailable"
, or if not:
@state_trigger("sensor.nas1_temperature != 'unavailable' and float(sensor.nas1_temperature) >= 60")
Beta Was this translation helpful? Give feedback.
All reactions
-
As I describe in #550, alas, 'unavailable'
is not the only non-numeric value, and not in ('unavailable', 'unknown', 'null', None, 'none', 'None')
is the check I use :( This makes the state triggers barely readable.
Beta Was this translation helpful? Give feedback.
All reactions
-
I'd recommend making complex trigger expressions a function that you call, or write your own float conversion function that traps exceptions.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 1
-
I think I will keep it simple like this:
errors = ['unavailable', 'unknown', 'null', None, 'none', 'None']
@state_trigger(sensor.nas1_temperature)
def NAS_cpu_temperature2():
if sensor.nas1_temperature not in errors and float(sensor.nas1_temperature) >= 60:
# do something
Beta Was this translation helpful? Give feedback.
All reactions
-
👎 1
-
How about the following:
errors = ['unavailable', 'unknown', 'null', None, 'none', 'None']
def HAfloat(str_value, default):
if str_value in errors:
return default
return float(str_value)
It will catch the special cases from HA, and for the rest uses the normal float function.
Than in the trigger statements you change float(xxx)
to HAfloat(xxx, your_default_value)
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 3
-
Alternatively, rather than use a deafult value, I return a NaN value since float('nan') < 0
, float('nan') > 0
, and float('nan') == 0
all return false. So something like this:
def myfloat(val): if val in ["unavailable", "unknown", "null", None, "none", "None"]: return float("nan") else: return float(val)
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 2