Calculate seconds starting at hh:00:00, hh:15:00, .. until now

I’m trying to calculate the number of seconds since the last hour, 15 minutes after the hour, …

So I have an input_datetime where I can store this:

  - alias: Begin van huidige kwartier
    trigger:
      - platform: time_pattern
        minutes: "/15" 
    action:
      - service: input_datetime.set_datetime
        entity_id: input_datetime.start_huidig_kwartier
        data_template:
          datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"

So, on 00, 15, 30 and 45 minutes exactly, the current time is stored. This in working.

Okay, now the more difficult part. In Devtools, Templates I did a test:

{{ (now() - now().replace(hour=state_attr('input_datetime.start_huidig_kwartier', 'hour'), minute=state_attr('input_datetime.start_huidig_kwartier', 'minute'), second=state_attr('input_datetime.start_huidig_kwartier', 'second'))) }}

At 21:32:22 this results in 0:03:22.999988; lets call this ‘piekseconds’
Looks good.

But now I’m stuck. I need to make calculations with it.

I have a sensor (sensor.fluvius_verbruik_energy_kwartier_piek), a float ranging between 0 and 10.

My calculation (and eventually my new sensor that I want to create) is this:

sensor.fluvius_verbruik_energy_kwartier_piek / piekseconds * 900

How do I do that? Since ‘piekseconds’ is a string (I think ?), and I don’t need the complete string, but as in this example: 203 (seconds) 3x60+22+1 (when rounding up).

So my first step is now: convert this (0:03:22.999988) to an integer (203).

Any help much appreciated.

Try as_timestamp for datetime calculation:

{{ (as_timestamp( now() ) - as_timestamp( now().replace(hour=now().hour-1) ))|round(1)|int }}
This gives (current time - 1-hour ago time) = the integer 3600 seconds.

your input_datetime should have a “timestamp” attribute.

you can use that attribute to calculate the seconds since that timestamp value:

{{ as_timestamp(now()) - state_attr('input_datetime.start_huidig_kwartier', 'timestamp') }}

this will count the seconds since the input_datetime time. Which should be updated every 15 minutes via the automation.

so every 15 minutes the value should start back at 0 and count up to 900. It’s limited by the sensors update interval tho. But I can’t remember what that update interval limit is - maybe every minute?

This, together with the initial automation is what I needed.
Thank you all, for pointing me in the right direction !

  - platform: template
    sensors:
      fluvius_verbruik_energy_kwartier_piek_prognose:
        value_template: "{{ ( states('sensor.fluvius_verbruik_energy_kwartier_piek') | float(0) / (as_timestamp(now()) - state_attr('input_datetime.start_huidig_kwartier', 'timestamp') ) * 900) }}"
        unit_of_measurement: "kWh"
        device_class: energy
        icon_template: mdi:calculator
        friendly_name: "Kwartier piek prognose"

Final result
Schermafbeelding 2022-12-16 om 09.20.37

-15: my previous peak
nu: current peak, keeps counting up until 00:14:59 (screenshot after about 5 minutes)
+15: estimation (as calculated above)
day and month peak

Now I can use this estimation to decide whether to shut down an appliance or not to stay under a desired peak. (insight: our energy bill depends on not only how much we use, but also on how much we use within 15 minutes, starting at 00m, 15m, …)

Thank you so much !

Hi, I’m trying to achieve the same as you.
Note that you can get the seconds since the last full quarter of an hour with this simple formula:
{{ as_timestamp(now())%900 }}

=> Modulo of current timestamp divided by 900

This has the added bonus that it will still work even if your system has just been reset and missed saving the start_huidig_kwartier.

1 Like

Hi Ward

Thanks !
Now I have

  - platform: template
    sensors:
      fluvius_verbruik_energy_kwartier_piek_prognose:
        value_template: >
          {% if (as_timestamp(now())%900) < 30 %} 
            0
          {% else %}
            {{ (states('sensor.fluvius_verbruik_energy_kwartier_piek') | float(0)) / (as_timestamp(now())%900 | float(0)) * 900 }}
          {% endif %}
        unit_of_measurement: "kWh"
        device_class: energy
        icon_template: mdi:calculator
        friendly_name: "Kwartier piek prognose"

This also eliminates the need for the automation that sets the timestamp of every quarter hour (the one in my opening post).
And also that in the first 30 seconds the average sometimes is 7 or 8kwh, while this normalizes thereafter.
So now I have the sensor return 0 for the first 30 seconds

If you are interested, you can reduce the template to this:

- platform: template
    sensors:
      fluvius_verbruik_energy_kwartier_piek_prognose:
        value_template: >
          {% set t = now().timestamp() % 900 %} 
          {{ states('sensor.fluvius_verbruik_energy_kwartier_piek') | float(0) / t * 900 if t >= 30 else 0 }}
        unit_of_measurement: "kWh"
        device_class: energy
        icon_template: mdi:calculator
        friendly_name: "Kwartier piek prognose"
1 Like

Great idea to flatten out the peaks! I was looking for something like this, thanks!