Search code examples
prometheuspromql

Calculating the amount of energy used for a charging session


I'm feeding the current (I in Ampere) and voltage (U in Volt) of a wallbox every 10 seconds into a prometheus instance. The wallbox naturally reports higher current when it is plugged into an electric vehicle and a lower current when its not (some baseline current still persists of course for the wallbox' connectivity functionality).

Now I'm quite new to Prometheus and PromQL and was wondering how I'd go on and actually get aggregated data out from these single points in time, namely I want to get Watt Hours and aggregate further on those.

IIRC electrical work is calculated by W = U x I x t, so my idea was to somehow sum up the individual values up until a total value for an hour, like so:

// somehow get t(0), the first timestamp where values have been reported
// now for each data point we expect that U and I have been constant up until
// this point for simplicity
W(1) = U(1) x I(1) x (t(1) - t(0))
W(2) = U(2) x I(2) x (t(2) - t(1))
W(3) = U(3) x I(3) x (t(3) - t(2))
...
// one hour is comprised of 360 individual values (6 values per minute, 60 minutes per hour)
W(1..360) = W(1) + W(2) + ... W(360)

I guess I need some integral function for that, but I'm unsure if I'm doing the right thing:

sum_over_time(current[10s]) * sum_over_time(voltage[10s])

This gives me basically the same value like current * voltage, so a single electrical work value, but I have no idea how I'd aggregate this further properly.

Any ideas?


Solution

  • The following query should return energy consumption during last hour if current and voltage metrics are collected every 10 seconds:

    sum_over_time(
      (last_over_time(current[20s]) * last_over_time(voltage[20s]))[1h:10s]
    ) * 10
    

    The 10 multiplier is needed in order to calculate the consumed energy per each 10 second interval.

    This promql query uses subquery feature.

    Update: The query returns the energy in Joules, not kWh. The resulting value must be divided by (3600*1000) in order to convert the consumed energy to kWh:

    sum_over_time(
      (last_over_time(current[20s]) * last_over_time(voltage[20s]))[1h:10s]
    ) * 10 / (3600*1000)