Input number automation oddity

I’m setting up a couple of input_numbers, one to set the time for a fan, and one to turn on a humidifier for a portion of the fan time. In other words, the humidifier time would always be <= the fan time. I’ve set up automation so that when I place the slider for the humidifier above the fan time, the fan time will be increased to match, and when the fan time is set below the humidifier time, the humidifier time is decreased to match. This is obviously to prevent the mister from running when the fan is off.

This works great, except when it doesn’t. It only seems to work about 80% of the time. Other times the automation doesn’t look like it kicks in. No errors in the logs.

I’m very new (1 week) to home assistant and am a bit stumped on how to track this down.

Does anyone have any pointers on how I can debug this? I’ve read in different places that debugging automation is “difficult”, and when you have something that works as you think it should, but intermittently fails, it makes it even more of a head-scratcher.

- alias: 'Synch RH time and fan time'
  trigger:
    platform: state
    entity_id: input_number.fr_humidifier_time
  condition:
    condition: template
    value_template: '{{ states("input_number.fr_humidifier_time") > states("input_number.fr_fan_time") }}'
  action:
    service: input_number.set_value
    data_template:
      entity_id: input_number.fr_fan_time
      value: "{{ states('input_number.fr_humidifier_time') | int(0) }}"

- alias: 'Synch fan time and RH time'
  trigger:
    platform: state
    entity_id: input_number.fr_fan_time
  condition:
    condition: template
    value_template: '{{ states("input_number.fr_humidifier_time") > states("input_number.fr_fan_time") }}'
  action:
    service: input_number.set_value
    data_template:
      entity_id: input_number.fr_humidifier_time
      value: "{{ states('input_number.fr_fan_time') | int(0) }}"
input_number:
  fr_fan_time:
    name: Fan Time
    initial: 70
    min: 0
    max: 120
    step: 10
    unit_of_measurement: Sec
    icon: mdi:timer
  fr_humidifier_time:
    name: RH Time
    initial: 10
    min: 0
    max: 120
    step: 5
    unit_of_measurement: Sec
    icon: mdi:timer

Home Assistant 0.103.6 running straight on ubuntu 18.04 (no docker, no hass.io), python 3.6.9, aarch64 odroid c2.

Thanks!

You should maybe convert the strings to a number before comparing them.

value_template: '{{ (states("input_number.fr_humidifier_time") | int) > (states("input_number.fr_fan_time") | int) }}'

Though, with python, this shouldn’t matter since both would be strings, and would still be comparable. Maybe JINJA2 does something slightly different.

Also, techincally there is no need to specify int(0) as 0 is the default value already if there is an error. But it doesn’t hurt I suppose to make it explicit that is what you would want.

EDIT:

Actually, it might be because you’re looking at the state? It could be because the state hasn’t actually changed yet (i.e. states(‘input_number.fr_humidifier_time’) is currently in the process of changing.

In this case, instead of setting the number to the current state, set the number to the trigger.to_state.state (the state it is going to be when everything is finished).

value: “{{ trigger.to_state.state | int }}”

But I don’t think HA works this way…and using the state variable should be fine. I mean, it had to change to trigger this automation in the first place!

Just out of curiosity why are the step increments different?

Oh, and you can do this in a single automation if you don’t want to maintain 2 separate ones.

- alias: 'Sync RH time and fan time'
  trigger:
    # If either of these changes
    - platform: state
      entity_id: input_number.fr_humidifier_time
    - platform: state
      entity_id: input_number.fr_fan_time
  condition:
    condition: template
    # ONLY humidifier is > fan time
    value_template: '{{ states("input_number.fr_humidifier_time") | int > states("input_number.fr_fan_time") | int}}'
  action:
    service: input_number.set_value
    data_template:
      # Change the opposite one depending on which one changed.
      entity_id: "input_number.{{ 'fr_fan_time' if trigger.object_id is 'fr_humidifier_time' else 'fr_humidifier_time' }}"
      # Set it equal to the resulting state
      value: "{{ trigger.to_state.state | int }}"

That was exactly it. When the RH was above 100, it was doing a string compare and failing the condition. It’s obvious now. Forehead slapped. Thanks for the very fast reply.

1 Like

Thanks Jim, that will simplify things. Still learning…

micque, I’m not sure if it will ultimately be needed, but I wanted more fine-grained countrol over how long the mister was active to adjust the humitity level. This may not be needed in practise.

Me too. I have so many automations and things that I eventually get to combining once I learn more and more about how to template and yaml syntaxes.

Having multiple things is fine until some point in the future you want to disable the syncing and now you have to turn off X different automations. or you need to update X automations. The important part is getting it to work first. THEN optimize later :slight_smile:

1 Like

It might cause some strange slider behavior since you are tying the two together with different increment possibilities.

I couldn’t agree more. I’m a long-time programmer, and when learning something new I always take the approach of “get something, ANYTHING, working, then, once working, get it working better.” The “better” part includes trimming things down and decluttering. :slight_smile:

micque, indeed. I will make them the same then. It was just a passing thought when I did it that way. Thanks!

For this:

      entity_id: "input_number.{{ 'fr_fan_time' if trigger.object_id is 'fr_humidifier_time' else 'fr_humidifier_time' }}"

It’s complaining:

expected token 'name', got 'string') for dictionary value @ data['action'][0]['data_template']['entity_id']. Got None.

Is jinja not substituting properly or something?

I do find it odd that “input_number” would return a string. It violates the “principle of least surprise”, at least at my novice level…

Whoops. Should be ‘==’ not ‘is’.

"input_number.{{ 'fr_fan_time' if trigger.object_id == 'fr_humidifier_time' else 'fr_humidifier_time' }}"

Closer. I’ve been over it and over it and it all looks correct, but still something’s not right. It works if I adjust the fan time below the humidifier, but not if I adjust the humidifier above the fan time. Anything obvious that you can see?

Whoops again. It should be trigger.to_state.object_id.

trigger.object_id is returning None, so it will always evaluate to fr_humidifier_time :frowning:

"input_number.{{ 'fr_fan_time' if trigger.to_state.object_id == 'fr_humidifier_time' else 'fr_humidifier_time' }}"

Bingo! Works perfectly. I appreciate your help with this, it would have taken me a while to debug. Learned a lot from this in a short time.

1 Like

HA always stores values as text even if it came from an integer, will be used as an integer or has an integer destination.
Same for floats.
‘Some’ functions return ‘non-string’ objects, for example ‘some’ datetimes and ‘some’ array elements but ALWAYS assume something is going to bite you in the ass and ALWAYS test.

It just saves time in the long run, the templating tool is a godsend

1 Like