Use timestamp output from one query as range for another

New Grafana user here, so go easy on me!

Desired behaviour: When I select a host and cycleNumber (both variables), panels populate with data collected between a given window of time during that cycle. This window of time is defined by “Step”, which increments during each cycle. I’m interested in data between steps 7 and 44.

To do this, I think I need to:

  1. Get the time when cycleNumber changed to the desired value
  2. Get the first time AFTER cycleNumber time when step == 7
  3. Get the first time AFTER cycleNumber time when step == 44
  4. Use the times of step == 7 and 44 to define a range to query other desired data (temperatures, valve states etc)

Step 1 is completed successfully using:

from(bucket: "my_bucket")
  |> range(start: 0) // Query from the first available data
  |> filter(fn: (r) => r["_measurement"] == "data")
  |> filter(fn: (r) => r["host"] =~ /^$host$/) // Taken from a variable
  |> filter(fn: (r) => r["_field"] == "CycleNumber" and r["_value"] == ${CycleNumber_variable}) // Also taken from a variable
  |> keep(columns: ["_time"])

Now, I need to either store this time in a variable or pipe it into queries for steps 2,3 and 4.
Failed attempts at using in a variable:

  • Added to above query |> findRecord(fn: (key) => true, idx: 0) // Extract the time as a record
  • |> findColumn(fn: (key) => true, column: "_time")
  • |> range(start: 0)  // Adjust as needed
    |> filter(fn: (r) => r._measurement == "data")
    |> filter(fn: (r) => r.host == "${host}")
    |> filter(fn: (r) => r._field == "CycleNumber")
    |> filter(fn: (r) => r._value == ${CycleNumber_variable})
    |> sort(columns: ["_time"], desc: false)
    |> limit(n: 1)
    |> map(fn: (r) => ({_value: r._time}))```
    
    

The above and various permutations don’t populate a variable with any value. Is there sometime obvious I’m missing?

Other approach is to try to use blocks in the same query, the first defining a namespace to be used in the second. For example:

time_of_switch = from(bucket: "my_bucket")
  |> range(start: 0)
  |> filter(fn: (r) => r._measurement == "data")
  |> filter(fn: (r) => r.host == "${host}")
  |> filter(fn: (r) => r._field == "cycle_number")
  |> filter(fn: (r) => r._value == int(v: "${cycle_number_variable}"))
  |> sort(columns: ["_time"], desc: false)
  |> limit(n: 1)
  |> keep(columns: ["_time"])
  |> findColumn(fn: (key) => true, column: "_time")

// Step 2: Find the first instance where Step equals 7 after the time_of_switch
from(bucket: "my_bucket")
  |> range(start: time(v: time_of_switch))
  |> filter(fn: (r) => r._measurement == "data")
  |> filter(fn: (r) => r._field == "Step")
  |> filter(fn: (r) => r.host == "${host}")
  |> filter(fn: (r) => r._value == 7)
  |> first()

I’ve also tried various permutations of this, but this only displays the first timestamp from the first block.

Am I barking up the wrong tree or am I close?

This approach seems fine to me. For example, the following code snippet returns data starting from time_of_switch: