Search code examples
prometheus

Calculate time based cost from meter reading in Prometheus


I have data from my electricity meter being read into Prometheus, which is an increasing counter showing the total amount of kilowatt hours used since the meter was installed. I would like to calculate the cost of the electricity, which changes depending on the hour of the day.

The main issue for me is that I have four hours of cheap electricity over night (12:30am-4:30am), and more expensive the rest of the time. This means it's not a simple multiplication, and I don't think I can use a recording rule.

Is there a simple way to calculate a new "cost" metric, based on this input?


Solution

  • Depending on what exactly you are expecting from this query, I can imagine this be solved in two major ways.

    Visualization

    If you plan to visualize said cost with Grafana (or alike), you can use query

    increase(my_metric[1m]) * 3
       and on() ((hour()==0 and minute()>30) or (hour()==4 and minute()<=30) or hour()>0<4)
    or increase(my_metric[1m]) * 9
    

    with resolution equal to 1 minute. And then setup panel to show total sum over displayed period.

    For example, if you'll setup dashboard over time range now/d, now you'll see cost for current day from midnight.

    Recording rule

    If you want full history form some moment in the past, you can use recording rules.

    It this case, expression for your recording rule should look something like this:

    my_cost offset 1m + (increase(my_metric[1m]) * 3  and on() ((hour()==0 and minute()>30) or (hour()==4 and minute()<=30) or hour()>0<4) or increase(my_metric[1m]) * 9) 
     or vector(0)
    

    Notice, that 1m used here must be equal to evaluation interval of your rule.


    Explanation:

    • Expressions like (hour()==0 and minute()>30) check the time, and return result (and subsequently allow first part of expression to return result) only if time is in expected range (Here - [00:00 - 00:30]).
    • Multipliers 3 and 9 are examples of tariffs over preferential and usual time. You obviously will need to replace with you values.
    • Recording rule way requires my_cost offset 1m to emulates behavior of counter. And or vector(0) - to start said counter from 0 when no previous value exists. Notice that my_cost is expected name of your rule, and when applying, you should replace it with your actual rule name.

    Notice also, that Prometheus by default operates in UTC, so you most likely will be required to correct hour values to those in UTC.