Making automation based on comparing two entities

Guys,

I’m dumb in manner of writing automations in pure YAML. That’s why I’m asking you.

What I want to achive is to HA sent me an mobile notification whenever I should open or close my window depending of what is a difference between my room temperature and outside temperature. This applies only to summer.

Writing in human but understable to IT guys language I want to achive this:

O - outside temp
R - room temp

FIRST RULE:

IF O > R 
THEN
NOTIFICATION: Close window


SECOND RULE:
IF O < R
BUT R > 22
NOTIFICATION: Open window


THIRD RULE:
IF O < R
BUT R < 20
THEN
NOTIFICATION: Close window

Of course I know I have to replace “O” and “R” with my respective entity names. That’s obvious :slight_smile:
I also understand I have to set proper action under “NOTIFICATION: something” but I know how to do that. It’s just wrote this way to understand the goal. The only thing I’m struggle with is the part with "compare one entity to another ".

Of course don’t look at exact numbers under temperature - they are just example :wink:

You can absolutely do this without writing any yaml, using the automation editor. For your automation you will want to use Numeric state triggers and a Choose action.

The basic configuration
trigger:
  - platform: numeric_state
    entity_id: O
    above: R
    for: '00:05:00'
    id: hot_outside
  - platform: numeric_state
    entity_id: O
    below: R
    for: '00:05:00'
    id: cool_outside
condition: []
action:
  - choose:
    -  alias: "First Rule"
       conditions:
        - condition: trigger
          id: hot_outside
      sequence:
        - service: notify.XXXX
          data:
            message: Close the window
    - alias: "Second Rule"
      conditions:
        - condition: trigger
          id: cool_outside
        - condition: numeric_state
          entity_id: R
          above: 22
      sequence:
        - service: notify.XXXX
          data:
            message: Open the window
    - alias: "Third Rule"
      conditions:
        - condition: trigger
          id: cool_outside
        - condition: numeric_state
          entity_id: R
          below: 20
      sequence:
        - service: notify.XXXX
          data:
            message: Close the window

I posted another example a couple days ago that incorporates window sensors, presence, and some other factors.

1 Like

Have you tried just using the automation editor? Why are you trying to do it in yaml, just because?

You know what you want clearly since you specced it out. Just use the UI editor to make it. Then if you really want to see the yaml click the 3 dots at the top and switch to yaml view, it’ll show you the yaml version of what you made.

OK - actually I thought it’s not possible using automation editor. That’s why I asked how to do it in YAML. Honestly I didn’t found any function in editor to compare two entities. But maybe I’m simply blind. Which option should I choose in editor to compare two entities?

In the triggers section of the automation editor, use the “Trigger Type” pull down menu to select Numeric State.

I understand that I have to use Numeric State but there is no anything like:

IF entity1 > entity2

There’s only something like:

IF entity1 > NUMBER or < NUMBER

as screenshot shows.

You can enter the entity_id of the second entity in the Above or Below fields.

3 Likes

Ahhhh… that makes sense. And a lot of difference :slight_smile: Thank you very much for your reply. I wasn’t aware of that. Will try that.

However - is it possible to do in editor something like this:

IF entity1 > entity2 + 2

Meaning if entity1 > entity2 value but plus 2 to it’s value (for example of course)

Or something like:

IF entity1-5 < entity2

Yes, you can modify the state that is being compared (Entity 1) using the Value template field. For your example you would use:

{{ float(state.state) - 2 }}

2 Likes

You’re the boss here. Thank you!

Seems like I’m doing something wrong here. I tried this but this gives me an error:

platform: numeric_state
entity_id: sensor.oczyszczacz_powietrza_biuro_temperature
below: '{{ float(sensor.outdoor_temperature) + 1 }}'

OK - I get it. I cannot do it in automation itself but under Developer options in Template. Still however it throwns an error like this.

ValueError: Template error: float got invalid input 'numeric_sensor.outdoor_temperature' when rendering template '{{ float('numeric_sensor.outdoor_temperature') }}' but no default was specified

OK - after putting this in Developer Tools → Template it says config is OK and shows calculated temperatures:

sensor:
  - platform: template
    sensors:
      office_temp+1:
        friendly_name: "Office temp + 1"
        value_template: "{{(states('sensor.oczyszczacz_powietrza_biuro_temperature')|float) + 1}}"

sensor:
  - platform: template
    sensors:
      office_temp-1:
        friendly_name: "Office temp - 1"
        value_template: "{{(states('sensor.oczyszczacz_powietrza_biuro_temperature')|float) - 1}}"

And result it shows:

sensor:
  - platform: template
    sensors:
      office_temp+1:
        friendly_name: "Office temp + 1"
        value_template: "24.7"

sensor:
  - platform: template
    sensors:
      office_temp-1:
        friendly_name: "Office temp - 1"
        value_template: "22.7"

However when I’m trying to put into configuration.yaml I got this:

nvalid config for [sensor.template]: invalid slug office_temp+1 (try office_temp_1) for dictionary value @ data['sensors']. Got OrderedDict([('office_temp+1', OrderedDict([('friendly_name', 'Office temp + 1'), ('value_template', "{{(states('sensor.oczyszczacz_powietrza_biuro_temperature')|float) + 1}}")]))]). (See ?, line ?).
Invalid config for [sensor.template]: invalid slug office_temp-1 (try office_temp_1) for dictionary value @ data['sensors']. Got OrderedDict([('office_temp-1', OrderedDict([('friendly_name', 'Office temp - 1'), ('value_template', "{{(states('sensor.oczyszczacz_powietrza_biuro_temperature')|float) - 1}}")]))]). (See ?, line ?).

It’s telling you what to do: you can’t use office_temp-1: so it’s suggesting office_temp_1:.


You CAN do it in the automation. The trigger below fires when the "fr. porch temperature" changes to 2 or more degrees above the "living room temperature".





'{{ float(state.state) }}' is referencing a variable, state, created inside the Numeric state trigger. What you typed,
'{{ float('numeric_sensor.outdoor_temperature') }}', is not the same as '{{ float(state.state) }}'.

I should have included a default in my earlier example, but it would have obscured the issue, not solved it… The template with a default can be written either '{{ float(state.state, 0) }}' or {{ state.state | float(0) }}.





The object id of an entity must be a slug… it cannot contain capital letters, spaces, or any punctuation marks other than _.

office_temp+1 and office_temp-1 are not valid slugs, so you cannot use them as the object ids for your sensors. If you want to use template sensors instead of doing it in the automation trigger, use something like office_temp_plus_1 and office_temp_minus_1.

Also, as of 2022.6, defaults for filters like float must be declared. See this post for details on how to apply them.

WORKS!!!

Thank you very much. I did it just in editor just as you showed me and it works!

Thanks again :slight_smile:

Seems like for any reason automation stopped working. Yet yesterday it was working fine. Code was like this:

platform: numeric_state
entity_id: sensor.oczyszczacz_powietrza_biuro_temperature
value_template: '{{ state.state|float(0) - 1 }}'
below: sensor.outdoor_temperature

However I got many false possitive automation starts because sometimes temperature entity is missing it value for few seconds and automation starts. That’s why yesterday I added this to my code and it stopped working completelly:

platform: numeric_state
entity_id: sensor.oczyszczacz_powietrza_biuro_temperature
value_template: '{{ state.state|float(0) - 1 }}'
below: sensor.outdoor_temperature
for:
  hours: 0
  minutes: 1
  seconds: 0

Is FOR cannot be used in such automation? And if - why?

What’s more when I’m trying to test this code in Developer Tools → Templates I got error like this (doesn’t matter if this FOR is included or not):

UndefinedError: 'state' is undefined

Actually there’s second question I have realted to this problem. To measure temperature in my room I simply use Xiaomi purifier. It reads data from Xiaomi cloud every 30 seconds and that’s works very well. However - if I unplug purifier from power then after 30 seconds all entities values related to purifier got value UNKNOWN. Same thing happens randomly sometimes if HA fails to read values from cloud in time. Why HA cannot just use “last known value” if it fails to read it from actual device? Can this be configured somehow?

1 Like

Yes, you can use for: with Numeric State triggers.

The variable state. is a referential variable for the state object of the entity targeted by the trigger. It doen’t exist to be tested in the Developer tools. For testing purposes, you can use states.sensor.oczyszczacz_powietrza_biuro_temperature.state in Developer Tools.

With all these connection and loading issues it might be easier to just use a template trigger so you can filter out non-numeric states:

trigger:
  - platform: template
    value_template: >
      {% if states('sensor.oczyszczacz_powietrza_biuro_temperature') | float('unknown') is number and states('sensor.outdoor_temperature') |float('unknown') is number %}
        {{ states('sensor.oczyszczacz_powietrza_biuro_temperature') | float(0) - 1 < states('sensor.outdoor_temperature') |float(0) }}
      {% else %}
        false
      {% endif %}

OK guys - I’ve figured out why it’s not working.

There are two temperatures here:

  • OUTSIDE TEMP
  • ROOM TEMP

And we have two automations for this

First:

platform: numeric_state
entity_id: sensor.oczyszczacz_powietrza_biuro_temperature
value_template: '{{ state.state|float(0) - 1 }}'
below: sensor.outdoor_temperature
for:
  hours: 0
  minutes: 1
  seconds: 0

and second:

platform: numeric_state
entity_id: sensor.oczyszczacz_powietrza_biuro_temperature
value_template: '{{ state.state|float(0) - 1 }}'
above: sensor.outdoor_temperature
for:
  hours: 0
  minutes: 1
  seconds: 0

Of course this are only triggers for those two automations - not whole automiation but that doesn’t matter. Problem is with trigger.

Thing is when I was testing those automations I used Developer Tools → States and was changing state of ROOM TEMP (here as oczyszczacz_powietrza_biuro_temperature). And it worked :slight_smile:

But… I was blindly assuming that this part:

platform: numeric_state
entity_id: sensor.oczyszczacz_powietrza_biuro_temperature
value_template: '{{ state.state|float(0) - 1 }}'
above: sensor.outdoor_temperature

Will trigger automation whenever oczyszczacz_powietrza_biuro_temperature will change or outdoor_temperature will change. In reality tho this trigger is based on checking of oczyszczacz_powietrza_biuro_temperature AGAINST outdoor_temperature so it will not trigger if outdoor_temperature will change. It will only trigger when oczyszczacz_powietrza_biuro_temperature will change.

Now let’s look at some graph, shall we:

obraz_2022-06-06_013608978

(this peak at the end of chart is a result of testing via changing entity value manually - ignore it)

As you can see here ROOM TEMP barely change while OUTSIDE TEMP change a lot. So to make this automation work I have to compare outdoor_temperature AGAINST oczyszczacz_powietrza_biuro_temperature. Not the other way around. Because while it is at is is this automation will trigger only when oczyszczacz_powietrza_biuro_temperature will change (and all other conditions are met as well). So my automation have to look like this:

platform: numeric_state
entity_id: sensor.outdoor_temperature
value_template: '{{ state.state|float(0) - 1 }}'
below: sensor.oczyszczacz_powietrza_biuro_temperature

THEN SOMETHING… doesn’t matter what.

Maybe it will help other people in feature.

COMPARISION: Making trigger based on IF A > B won’t run if B has changed it’s value but not A. It will only run if A has changed it’s value.


Other thing is “why do I even care about opening / closing window during summer if it doesn’t affect room temperature in the manner of cooling it”. Well - it actually doesn’t as I see it now on the graph but there’s sollution for that. Simple fan mounted in the wall in the ventilation flue (ventilation vent chimney) will do the job. It will start based on HA automations sucking air from room outside. Because opened window is the only source of fresh air it will speed up sucking cool air from window. Simple.

For example my room has 22 cubic meters while such fan can transfer 100 cubic meters of air per hour. So if it starts when temp. in room is higher than temp outside and window is opened (checked by ZIGBEE sensor) then it will force air movement from window - across the room - to chimney up to the roof. When temperatures will change or window will be closed fan will power off. Simple as that. Additionally HA will tell me (based on temperatures differences) when to open / close window and will automatically start fan based on that.

Hope this explanation is clear.

I didn’t mount this fan yet but will do in upcomming days. Will let you know about results if someone is interested. Will connect it to some ZIGBEE plug and automate all this as desribed above. Should actually cool down my room very quick once temperature outside will be lower than temperature in room. For now as you see opening window does almost nothing.

Jakub, you are correct… In the Numeric State trigger the relationship between the two sensors is only re-evaluated when the sensor named under the entity_id variable changes.

However, in addition to handling the unknown and unavailable sensor problem, the template variable that I posted will be re-evaluted whenever either of the two sensors change.

EDIT: I missed the fact that you had switched the above to below on first reading.