I’d like to create an automation which saves the value of a sensor every fix time and maintain last N values in an array, so I can predict future values based on previous day’s ones.
I don’t know if best way of doing it is:
With a sql query at the database.
With a text file (csv).
With an array (I don’t know if it’s possible to maintain an array whose values are stored permanently even HA is restarted).
Definitely don’t know the best way. Perhaps add input_select to the list?
[edit] also wanted to point out. Why don’t you try each option and report back? The “best” for one person is not often the “best” for another who has different requirements.
I’ve created an automation triggered every hour. It maintains a first-in first-out buffer in the input_text. It saves the last 24 values of the sensor, dropping oldest one if 24-spaces buffer is full.
I have to test it, and then my plan is to create a sensor whose values predict an average of the next N-hours temperature based on present and last day temperatures.
I’ll then switch-on or not accumulator heaters within scheduled times based on the value of this sensor compared with a certain threshold.
It prepends the sensor’s value as a list, thereby saving a step or two.
I assume the values you are storing are just short integers, or floats, and 24 of them, plus commas, won’t exceed 255 characters in length (which is the maximum storage capacity of an entity’s state value).
An automation, which every hour updates the last day’s temperatures.
A sensor, which makes an estimation of next hours average temperature based on difference of actual and -24hours temperature and a weighted average of yesterday’s next hours temperatures.
I hope this is helpful for somebody else.
input_text:
fi_fo_buffer:
name: "First in - First out buffer"
min: 0
max: 255
input_number:
window_size:
name: Window size
icon: mdi:arrow-expand-horizontal
initial: 6
min: 1
max: 24
step: 1
sensor:
- platform: template
sensors:
estimated_temperature:
friendly_name: "Estimated temperature based on actual and previous day's values"
value_template: >
{% set data = namespace(values=[], weights=[], products=[]) %}
{# average window size #}
{% set n = states('input_number.window_size') | int %}
{% set len = states('input_text.fi_fo_buffer').split(',') | length %}
{# if buffer is full, estimation can be done #}
{% if len == 25 %}
{% for num in states('input_text.fi_fo_buffer').split(',') %}
{% set data.values = data.values + [num|float] -%}
{% set cont = loop.index0 %}
{# Linear weights #}
{% set data.weights = data.weights + [max((1-(1/n)*(len-cont-1)),0)] %}
{% set data.products = data.products + [(data.values[cont] * data.weights[cont])|round(3)] %}
{% endfor %}
{{ ((data.values|first - data.values|last) + (data.products|sum/data.weights|sum)) | round(2) }}
{% else %}
{# buffer is still not full #}
{{'undefined'}}
{% endif %}
attribute_templates:
number_samples: >
{{ states('input_text.fi_fo_buffer').split(',') | length }}
automation:
- id: update_buffer
alias: "Update first in - first out buffer"
description: "Updates first-in first-out buffer every hour."
trigger:
# run each hour
- platform: time_pattern
minutes: '0'
condition: []
action:
- service: input_text.set_value
target:
entity_id: input_text.fi_fo_buffer
data:
value: >-
{{ ([states('sensor.temperature')] +
states('input_text.fi_fo_buffer').split(',')[0:24]) |
join(',') }}
mode: single