Help with a trigger toward action setting an input_text

Hi

I am trying to make a sensor that updates every 24 hrs and checks if the value the last day is larger than the ones it has initialized each month and if so replaces the lowest value and hopefully retains its value on restarts.

I have struggled to get this to work starting with a trigger sensor and failing to get it to initialize I figured it could be solved to use an action to set the value of a input_text instead so what I have now is:

  1. updates every 24hrs
  2. checks the value in an input_text
  3. converts the value from string to list to dictionary for processing
  4. compares the current days value against the input_text values
  5. output the value (this is where it works in the template editor but not when I am putting it into config.yaml :frowning: ).

My current guess is it is a scope issue … that this variable setup worked in a template sensor to move values to the sensor, maybe it doesn’t get to the action for the input_text?

my yaml (trigger no longer with sensor but action input_text that also does not work) (but the action part works in template designer, but so did it when it was a sensor :S … so maybe there is something else?):

Summary
  - trigger:
    - trigger: time
      at: "01:10:00"
    - trigger: state
      entity_id:
        - input_button.trigger_to_test
      from: null
      to: null
    action:
      sequence:
        - variables:
            results: >
              {% set ev = states.sensor.value_each_day.state | float %}
              {% set evts = as_timestamp(states.sensor.value_each_day.last_updated)  %}
              {% if states.input_text.monthly_peak_values.state in ["[]",'', ""]  %}
                {% set in_dict =
                  { -0.0001:  '1 as_timestamp( states.sensor.*.lastupdated)',
                    -0.001:   '2 as_timestamp( states.sensor.*.lastupdated)',
                    -0.01:    '3 as_timestamp( states.sensor.*.lastupdated)' } %}
                {% else %}
                  {% set in_dict = dict.from_keys(states.input_text.monthly_peak_values.state)  %}
              {% endif %}
              {% set in_eid = in_dict.get(in_dict.keys() | sort()
                | select('<=', ev | float(0))
                | first, false ) %}
              {% set ns = namespace( kvps=[], d={}, l=[] ) %}
              {% if in_eid != false %}
                {%- for key, value in in_dict | dictsort() %}
                  {% if in_eid == in_dict[key] %}
                    {% set ns.kvps = ns.kvps + [(ev, evts)] %}
                    {% set ns.l = ns.l + [[ev, evts]] %}
                  {% else %}
                    {% set ns.kvps = ns.kvps + [(key, value)] %}
                    {% set ns.l = ns.l + [[key, value]] %}
                  {% endif %}
                {% endfor %}
                {% set ns.d = dict.from_keys(ns.kvps) %}
              {% else %}
                {% set ns.d = in_dict.copy() %}
              {% endif %}
              {# result  to send, example:
              data: '[[1.52, 1741481785.820026], [-0.001, '2 as_timestamp( states.sensor.*.lastupdated)'], [-0.0001, '1 as_timestamp( states.sensor.*.lastupdated)']]' #}
              data: '{{ ns.l |list  }}'
              {% set av = dict.from_keys(ns.kvps  | selectattr( 0, 'gt', 0.001 ) | list) %}
              result_average: '{{ av | average | float }}'
        - action: input_text.set_value
          target:
            entity_id: input_text.monthly_peak_values
          data:
            value: '{{ data }}'


input_text:
  monthly_peak_values :
    name: monthly peak values
    initial: "[]"
    max: 255

any ideas what I am maybe doing wrong?

I’m not following.
Could you perhaps explain it like:

Value is 10.
Update is 15.
This happens…

It’s probably me that just doesn’t get it.

Like Hellis81, it isn’t exactly clear to me what you are actually trying to do… but one thing you are doing wrong is using a variable data that has no value. As configured in your example there is only one variable i.e. results… and it doesn’t return a dictionary, just a dictionary-shaped string.

If this is a sensor, where is the sensor portion of the configuration? That is a required component… the configuration will not be loaded if it is missing.

Also, the sequence key isn’t necessary.

value I expect to get into the input_text is:

'[[1.52, 1741554961.717553], [-0.001, '2 as_timestamp( states.sensor.*.lastupdated)'], [-0.0001, '1 as_timestamp( states.sensor.*.lastupdated)']]'

what I get is
“”

I get what I expect in the template designer but moving it to the config has not worked first as a sensor and now I was trying using an input_text which I thought was better in that I could at least initialize it.

@Didgeridrew I put in a sensor again, it has been there originally but it has not helped me gain what I expect. I also removed the sequence I included it as I was trying to figure out why the action seemed to not get the value that I get in the template designer.
by data having no value is this because of scoping as that is what I was guessing. Originally I had data in the sensor, but it relied on the value of it to calculate it (i believe)
could it be to use the text_input to feel the sensor attribute “data” with the stringified list?

Post the current configuration… there’s no point in us discussing something we can’t see.

No, it’s from it not being a variable with an assigned value.

sure, thanks for taking a look!

  - trigger:
    - trigger: time
      at: "01:10:00"
    - trigger: state
      entity_id:
        - input_button.7_trigger
      from: null
      to: null
    action:
	- variables:
		results: >
		  {% set ev = states.sensor.value_each_day.state | float %}
		  {% set evts = as_timestamp(states.sensor.value_each_day.last_updated)  %}
		  {% if states.input_text.monthly_peak_values.state in ["[]",'', ""]  %}
			{% set in_dict =
			  { -0.0001:  '1 as_timestamp( states.sensor.*.lastupdated)',
				-0.001:   '2 as_timestamp( states.sensor.*.lastupdated)',
				-0.01:    '3 as_timestamp( states.sensor.*.lastupdated)' } %}
			{% else %}
			  {% set in_dict = dict.from_keys(states.input_text.monthly_peak_values.state)  %}
		  {% endif %}
		  {% set in_eid = in_dict.get(in_dict.keys() | sort()
			| select('<=', ev | float(0))
			| first, false ) %}
		  {% set ns = namespace( kvps=[], d={}, l=[] ) %}
		  {% if in_eid != false %}
			{%- for key, value in in_dict | dictsort() %}
			  {% if in_eid == in_dict[key] %}
				{% set ns.kvps = ns.kvps + [(ev, evts)] %}
				{% set ns.l = ns.l + [[ev, evts]] %}
			  {% else %}
				{% set ns.kvps = ns.kvps + [(key, value)] %}
				{% set ns.l = ns.l + [[key, value]] %}
			  {% endif %}
			{% endfor %}
			{% set ns.d = dict.from_keys(ns.kvps) %}
		  {% else %}
			{% set ns.d = in_dict.copy() %}
		  {% endif %}
		  {# result  to send, example:
		  example data: '[[1.52, 1741481785.820026], [-0.001, '2 as_timestamp( states.sensor.*.lastupdated)'], [-0.0001, '1 as_timestamp( states.sensor.*.lastupdated)']]' #}
		  data: '{{ ns.l |list  }}'
		  {% set av = dict.from_keys(ns.kvps  | selectattr( 0, 'gt', 0.001 ) | list) %}
		  result_average: '{{ av | average | float }}'
	- action: input_text.set_value
	  target:
		entity_id: input_text.monthly_peak_values
	  data:
		value: '{{ data }}'
   sensor:
      - name: "peaks per month"
        unique_id: a90012sREDACTED
        state: '{{ result_average }}'

input_text:
  monthly_peak_values :
    name: monthly peak values
    initial: "[]"
    max: 255

Note i have left in the dictionary in the loops but it is not used in the results.

Same issue… you don’t have a variable result_average that has an assigned value. If you want results to return a functional dictionary instead of a dictionary-shaped string, you need to set it up to do that:

...
{% set av = dict.from_keys(ns.kvps  | selectattr( 0, 'gt', 0.001 ) | list) %}
{{ {"data": ns.l |list, "result_average": av | average | float } }}

Then you use the proper variable notation like results.result_average for your sensor state(s).

As far as I can tell there is no reason to use an Input text… just add another entry under the sensor key for monthly peak values.

Don’t leave anything in the template that isn’t used, it will just cause trouble… if not now, then in 6 months or a year when you need to make adjustments and you can’t remember what it all does.

thanks for this, it really helped in the end and gave me some great lessons learned. thank you.

lessons learned where I went wrong

I think you meant and I didn’t at first understand was that the scope was wrong not having a ‘results’ - the things I was trying to pass were within the scope of results and they needed to take results and pass it on as I understand as this is working. I also had tried so many things that I had made some type mistakes making things hard in the end to debug.

anyway, here is working code, cleaned up and with the orphan dictionary removed
input needed : sensor.peak_per_day >> a sensor where the peak each day is registered
ouput is in terms of a list and average value in the sensor
notes:
a. number of items in the dictionary “in_dict” will provide the number of values it will save… so it shows 3 but it couild be 5 if you add 2 more - set values appropriately.
b. there is no check (currently) when it is run multiple times a day so it can fill the values with the same value
c. shift in time / day (there is probably a better way to do this) : the trigger is at 01:00 not 00:00 as the peak is finally calculated with the saved value of the last hour at 01:00. Similarly i reset the values on the 2nd each month in the first if in the code as the 1st of each month will include the full last day of the previous month,

  - trigger:
    - trigger: time
      at: "01:10:00"
    - trigger: state
      entity_id:
        - input_button.manual_trigger_for_this_top_values_per_month
      from: null
      to: null
    action: 
      - variables:
          results: >
            {% set ev = states.sensor.peak_per_day.state | float %} 
            {% set evts = as_timestamp(states.sensor.peak_per_day.last_updated)  %}
            {% if states.sensor.peaks_per_month.attributes.data in ["[]", "", [] ] or (now().strftime("%d") | int) == 2 %}  %}
              {% set in_dict =
                { -0.0001:  '1 as_timestamp( states.sensor.*.lastupdated)',
                  -0.001:   '2 as_timestamp( states.sensor.*.lastupdated)',
                  -0.01:    '3 as_timestamp( states.sensor.*.lastupdated)' } %}
              {% else %}
                {% set in_dict = dict.from_keys(states.sensor.peaks_per_month.attributes.data)  %}
            {% endif %}
            {% set in_eid = in_dict.get(in_dict.keys() | sort()
              | select('<=', ev | float(0))
              | first, -1 ) %}
            {% set ns = namespace( kvps=[], d={}, l=[] ) %}
            {%- for key, value in in_dict | dictsort() %}
              {% if in_eid == in_dict[key] %}
                {% set ns.kvps = ns.kvps + [(ev, evts)] %}
                {% set ns.l = ns.l + [[ev, evts]] %}
              {% else %}
                {% set ns.kvps = ns.kvps + [(key, value)] %}
                {% set ns.l = ns.l + [[key, value]] %}
              {% endif %}
            {% endfor %}
            {% set av = dict.from_keys(ns.kvps  | selectattr( 0, 'gt', 0.001 ) | list) %}
            {{ ns.l | list,  av | average | float }}
            {# results to send, like: 
            ([[1.34, 1741602374.850404], [-0.001, '2 as_timestamp( states.sensor.*.lastupdated)'], [-0.0001, '1 as_timestamp( states.sensor.*.lastupdated)']], 1.34) #}
            
          datas: '{{ results[0] | list }}'
          result_average: '{{ results[1] }}'

    sensor:
    - name: "peaks per month"
      unique_id: 17d7a988-----unique_id_here
      state: '{{ result_average }}'
      attributes:
        data: '{{ datas }}'

thanks again!