Use duration literal (v.windowPeriod) for mathematical calculations?

My Raspberry Pi has a light sensor connected to a GPIO port which counts the number of LED impulses on my electricity meter. Each blip is 0.001 kWh or 1 Wh of energy usage. I am plotting this data to show actual current power usage (kW, not kWh), so I have to divide the _value by v.windowPeriod:

from(bucket: "Home")
  |> range(start: v.timeRangeStart, stop:v.timeRangeStop)
  |> filter(fn: (r) => r._measurement == "mqtt.0.electricity.count_Wh"
                   and r._field == "value"
            )
  |> aggregateWindow(every: v.windowPeriod, fn: mean, timeSrc: "_start")
  |> derivative(unit: v.windowPeriod)
  |> keep(columns: ["_measurement", "_time", "_value"])
  |> map(fn: (r) => ({ r with _value: r._value * 12.0 }))

The factor of 12.0 is valid when v.windowPeriod == 5 minutes. But of course when I zoom, this value changes. I cannot use r._value * 60.0 / v.windowPeriod, this gives me an error about “duration”:

 invalid: error @10:57-10:61: expected float but found duration

Using float(v.windowPeriod) to force floats returns

invalid: compilation failed: error at @10:63-10:67:
unexpected token for property key: DURATION (1m0s)

It seems I need a function to convert a duration into a float (in minutes, possibly fractions of minutes) to be able to do calculations with it.

I could not find this anywhere. Does it exist? Or is there another more efficient way to do what I plan?

Thank you!

@Jens, float(v.windowPeriod) should be float(v: v.windowPeriod) (Flux only supports named parameters), however, float() doesn’t support duration values. You’re not out of luck though. You can use int() to convert a duration to the number of nanoseconds in the specified duration, and then use float() to convert the nanosecond integer into a float value (as seconds). So you could do something like:

windowFactor = float(v: int(v: v.windowPeriod) / 1000000000)

from(bucket: "Home")
    |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
    |> filter(fn: (r) => r._measurement == "mqtt.0.electricity.count_Wh" and r._field == "value")
    |> aggregateWindow(every: v.windowPeriod, fn: mean, timeSrc: "_start")
    |> derivative(unit: v.windowPeriod)
    |> keep(columns: ["_measurement", "_time", "_value"])
    |> map(fn: (r) => ({r with _value: r._value * windowFactor}))
2 Likes

Odin bless your for this valuable trick! ^^ My long range queries are performant again. Just replaced multiplication with divide.