T3m3z / spotprices2ha

Simple copy-paste approach to fetch data from api.spot-hinta.fi (see https://spot-hinta.fi) to Home Assistant. Includes simple sensors and UI elements to ease automation work.
MIT License
109 stars 13 forks source link

rank-automation.yaml doesn't work #34

Open velotelo opened 7 months ago

velotelo commented 7 months ago

I'm curious whether I'm doing something wrong, but the rank-automation.yaml doesn't work for me at all.

The automation I've created form that blueprint doesn't ever get triggered automatically and when triggered manually always results in else clause being executed.

Having spent a full day on it, I found the root cause: those input_variables are not accessible inside the value_template of the trigger despite the fact they're defined as trigger_variables (which in theory should work fine). I've tried pretty much all the approaches suggested at https://community.home-assistant.io and I just couldn't find a way to make those variables available.

The only solution I've found was moving all the if-else logic into the action section, subsequently changing the trigger to just rank & price state changes and and also changing trigger_variables to variables. That way all the variables are nicely available and automation works as expected:

variables:
  rank: !input rank
  price: !input price
  on_attribute: !input on_attribute

trigger:
  - platform: state
    entity_id:
      - sensor.shf_rank_now
  - platform: state
    entity_id:
      - sensor.shf_electricity_price_now

action:
  - if:
    - condition: template
      value_template: |-
        {% if on_attribute == "Price OK" %}
          {{ states('sensor.shf_electricity_price_now') | float <= price | float }}
        {% elif on_attribute == "Rank OK" %}
          {{ states('sensor.shf_rank_now')|float <= rank | float }}
        {% elif on_attribute == "Price or Rank OK" %}
          {{ states('sensor.shf_electricity_price_now') | float <= price | float or states('sensor.shf_rank_now')|float <= rank | float }}
        {% elif on_attribute == "Price and Rank OK" %}
          {{ states('sensor.shf_electricity_price_now') | float <= price and states('sensor.shf_rank_now')|float <= rank | float }}
        {% endif %}
    then: !input action_on
    else: !input action_off
zuiker1974 commented 7 months ago

I noticed same thing. Always goes to else.

velotelo commented 7 months ago

I've been running the code I've suggested above for a week now – works like a charm.

zuiker1974 commented 7 months ago

Even with these changes get always if condition false.

velotelo commented 7 months ago

There should be no magic that it works for me flawlessly and doesn't work for you at all... Here's the full updated file I'm using, you can try it out: rank-automation.yaml.zip

zuiker1974 commented 7 months ago

Only rank works with this, but not price. Needs some debugging.

velotelo commented 7 months ago

Both rank and price work for me, but there's another issue with this. Whenever HA gets rebooted, all scripts based on rank-automation.yaml get executed minimum 5 times within 2 seconds because of following events:

  1. Rank changes from unavailable to unavailable
  2. Price changes from unavailable to unavailable
  3. Rank changes from unavailable to value
  4. Price changes from unavailable to value
  5. Price changes from value to same value

"Run" # 1 gets executed and naturally goes to the else clause. "Runs" # 2-5 get terminated, because #1 is being executed.

One fast solution which works with added limitation is setting the trigger to ignore state change to unavailable:

trigger:
  - platform: state
    entity_id:
      - sensor.shf_rank_now
      - sensor.shf_electricity_price_now
    not_to: unavailable

With this fix in place only events 3 and 4 from above result in script triggering, with # 3 going through all conditions and performing as expected and # 4 getting terminated. Interestingly, event 5 also disappeared with this fix. However, if entity state becomes unavailable for some legit reason (i.e. not because of just executed reboot), that remains not handled by the script, that's the limitation.

Other option I see is modifying the else-clause as so (pseudo code):

    else: |-
      {% if trigger.from_state.state != "unavailable" and trigger.to_state.state != "unavailable" %}
        !input action_off
      {% endif %}

This particular code doesn't work and I'm not sure what am I missing here.

DR00ME commented 4 months ago

Why this is not still fixed? I fought with this problem many hours and now I found this thread.

DR00ME commented 3 months ago

Only rank works with this, but not price. Needs some debugging.

Remember the price is in euros. So for example 4.4c is 0.044 €

osro commented 2 months ago

For me the automation works, but it only when I trigger it manually.