Trying to make template sensor to record data at regular intervals - now() in template not automatically getting evaluated?

Hey all,

I want to preface this by saying that I am quite new to coding in home assistant and I fully expect this to be some stupid mistake on my end, but I genuinely cannot figure out what is wrong. Any help would be greatly appreciated!

So, a few days ago, I got myself some Bluetooth-based plant sensors and thought it would be fun to integrate them with Home Assistant. These sensors are the Xiaomi HHCC Flower Care sensors and after setting them up in the manufacturer’s app, I added them to Home Assistant using the Xiaomi BLE integration. That part was a piece of cake. One issue I have with the sensors is that they will occasionally become unavailable in Home Assistant for minutes to hours at a time and then somehow return back to normal. This is weird because it normally only happens to one sensor at a time, it is not always the same sensor, and all sensors work fine with the manufacturer’s app even when they’re unavailable in Home Assistant. However, this is a very strange problem for me to fix another time - today, I would like to focus on something hopefully far more tractable.

So as you can imagine, I wanted to make some graphs from the sensor data, so that I can e.g. see how a plant’s soil moisture develops over time after I water it. I have InfluxDB set up to record all sensors and use Grafana for visualisation (but please note I am not an expert in either!).

As anyone reading this is probably aware, regardless of how often a sensor broadcasts information, InfluxDB refuses to store consecutive identical values, meaning that in the case of moisture, the graph will be sparsely populated because only changes are recorded. So, since I would prefer to have a dataset where, in the absence of change, the current measured value is still recorded at a regular interval, I set out to find a way to trick Home Assistant and InfluxDB into doing this. I found two solutions online that I tried to implement, because I was not sure which one would work better. Both of these are using template sensors.

Solution 1 - adding an attribute that automatically changes every X minutes
Using code from this topic, I assembled the following template sensor (inside template.yaml, which is included in configuration.yaml):

- sensor:
      - name: "plant sensor 3 moisture continuous"
        device_class: moisture
        unit_of_measurement: "%"
        state: "{{ states('sensor.plant_sensor_3_moisture') }}"        
        unique_id: plant_sensor_3_moisture_db
        attributes:
          update_now: "{{ (now().minute / 5) | round(0) }}"

In my understanding, the template sensor should be updated every time the actual moisture value from the sensor changes, as well as every time the update_now attribute changes (i.e. every 5 minutes). I expected this to cause both Home Assistant and InfluxDB to record a data point at least every 5 minutes, but if the moisture were to change more frequently than that, all data points should be recorded. However, as you can see, the sensor hasn’t updated since 7:13 this morning (I am only showing the history in HA, but InfluxDB also has no data points beyond 7:13 am):

The “real” sensor has also been at 30% since that time (with one extra update apparently saved in HA at 10:01 AM, but also at 30%), so it seems that this template sensor does not update (or at least is not saved as a new data point) when only the update_now attribute changes. Which I find really confusing because, in my understanding, that was literally the entire point of the other discussion linked above.

Solution 2 - using a time_pattern trigger for the template sensor
Using some other code snippets from the discussion linked above as well as the template integration documentation, I made the following template sensor:

- trigger:
      - platform: time_pattern
        minutes: "/2"
  sensor:      
      - name: "plant sensor 3 moisture continuous time_pattern"
        device_class: moisture
        unit_of_measurement: "%"
        state: "{{ states('sensor.plant_sensor_3_moisture') }}"        
        unique_id: plant_sensor_3_moisture_2min_time_pattern

I expected this would simply save a data point every 2 minutes, regardless of anything else. This would not be as good as what I thought solution 1 would achieve, but realistically, 2-minute resolution should be okay for a graph like this even if the real sensor’s reported value changes more frequently.
Once again, Home Assistant and InfluxDB have no recent data from this sensor, but since it only checks the sensor every 2 minutes, it already stopped recording at 7:06 am. I wanted to also add a screenshot of this, but it turns out new users can only embed one media item. So please just imagine the previous graph but with the last data point at 7:06 am.

So my two questions are: What am I doing wrong? And how can I make this work? Any help would be massively appreciated!

I am running Home Assistant OS 12.0 (generic-x86-64) with Core 2024.2.4 and Supervisor 2024.02.0.

You can trick it by adding a small amount of random noise to the signal:

Hey, thanks for the answer! I had indeed stumbled upon another thread that suggested that as a solution, but I personally find that a rather “dirty” solution because I would not be recording the “actual” data. I understand that I can make the noise so minuscule that it is effectively negligible, and I might end up doing that if all else fails.

But the discussions I read suggested (at least to me, did I perhaps misunderstand?) that the solutions I described do work for other people, so I would be extremely curious why they refuse to work for me and how I can fix that.

If a sensor doesn’t change, it isn’t recorded.

Have you tried the time_pattern trigger-based template sensor with a timestamp attribute? Just:

attributes:
  timestamp: "{{ now().isoformat() }}"

should do.

If a sensor doesn’t change, it isn’t recorded.

Yes, I realise that. That was the reason I needed to do all of this in the first place. However, as I understand this merged PR from 2020, the now()-based attribute template should be evaluated (at least?) once a minute even if the sensor state of the underlying “real” sensor remains unchanged, without the need to also set a trigger. And therefore, I expected my solution 1 to do the trick, as this would change a sensor attribute (which should qualify as a change to the sensor). Am I understanding this wrong?

However, I have tried your timestamp-based suggestion and it seems that it does work exactly as I intended. Thanks a lot for that! :slight_smile:

I am still really confused, though - does that mean that the attribute template containing now() does not automatically get evaluated unless the sensor state changes? I would love to figure out why my Home Assistant is not doing this when the documentation (also the templating documentation) says it should - who knows what else is going wrong as a result that I am just not aware of yet…

Edit to add: I am changing the title since you have helped me realise that the issue wasn’t that time_pattern wasn’t triggering, but rather, the triggering alone wasn’t enough to create additional data points if the sensor is unchanged, and for some reason the now() template isn’t getting reevaluated.