Skip to content

Bries Dashboard Voorbeelden

Dit document bevat concrete voorbeelden van Flux queries die gebruikt worden in de Bries dashboards, met uitleg over de implementatie en visualisatie.

Voorbeelden van dashboardpanelen

1. Windsnelheid vs. Voertuigsnelheid paneel

Dit paneel toont zowel de windsnelheid als de voertuigsnelheid in één grafiek, zodat je direct de relatie kunt zien.

// Stap 1: Tijd selectie op basis van RunID
runID = "${RunID}"
bucketName = "Bries"

option startShift = duration(v: "${Start_Verschuiving}")
option endShift = duration(v: "${Eind_Verschuiving}")

minRecord = from(bucket: bucketName)
  |> range(start: -1y)
  |> filter(fn: (r) => r.runID == runID)
  |> keep(columns: ["_time"])
  |> first(column: "_time")
  |> findRecord(fn: (key) => true, idx: 0)

maxRecord = from(bucket: bucketName)
  |> range(start: -1y)
  |> filter(fn: (r) => r.runID == runID)
  |> keep(columns: ["_time"])
  |> last(column: "_time")
  |> findRecord(fn: (key) => true, idx: 0)

minTime = time(v: uint(v: minRecord._time) + uint(v: startShift))
maxTime = time(v: uint(v: maxRecord._time) - uint(v: endShift))

// Stap 2: Windsnelheid ophalen
windspeed = from(bucket: bucketName)
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "Wspeed" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) }))
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Wind speed"}))
  |> yield(name: "windspeed")

// Stap 3: Voertuigsnelheid ophalen
vspeed = from(bucket: bucketName)
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "Vspeed" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) }))
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Vehicle speed"}))
  |> yield(name: "vspeed")

Visualisatie instellingen: - Grafiektype: Time series - X-as: Tijd - Y-as: m/s - Series: Gegroepeerd op _field (Wind speed en Vehicle speed) - Kleuren: Wind speed (blauw), Vehicle speed (groen)

2. TSR (Tip Speed Ratio) berekening en visualisatie

Dit paneel toont de TSR waarde, die de verhouding weergeeft tussen de bladtipsnelheid en de windsnelheid.

// Stap 1: Tijd selectie (zelfde als hierboven)
// ...

// Stap 2: Windsnelheid ophalen
windspeed = from(bucket: "Bries")
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "Wspeed" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) })) 
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Wind speed"}))

// Stap 3: Rotorsnelheid ophalen
rotorspeed = from(bucket: "Bries")
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "Rspeed" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) })) 
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Rotor speed"}))

// Stap 4: TSR berekenen met transformaties
union(tables: [windspeed, rotorspeed])
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({ 
       _time: r._time,
       _field: "TSR",
       _value: (3.14159 * r["Rotor speed"] * 0.94) / (r["Wind speed"] * 30)
     })
  )
  |> yield(name: "TSR")

Visualisatie instellingen: - Grafiektype: Time series - X-as: Tijd - Y-as: TSR (dimensieloos) - Optionele drempelwaarden: - Optimale TSR markering (bijv. lijn bij TSR=4.0)

3. Vermogensberekening dashboard

Dit paneel toont het berekende vermogen van de turbine op basis van rotorsnelheid en koppel.

// Stap 1: Tijd selectie (zelfde als hierboven)
// ...

// Stap 2: Rotorsnelheid ophalen
rotorspeed = from(bucket: "Bries")
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "Rspeed" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) }))
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Rotor speed"}))

// Stap 3: Koppel ophalen
torque = from(bucket: "Bries")
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "Rtorque" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) }))
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Torque"}))

// Stap 4: Torque factor ophalen (indien nodig)
torqueFactor = from(bucket: "Bries")
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "torqueFactor" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) }))
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Torque factor"}))

// Stap 5: Vermogensberekening met transformaties
union(tables: [rotorspeed, torque, torqueFactor])
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => ({ 
       _time: r._time,
       _field: "Power",
       _value: 2 * 3.14159 * r["Rotor speed"] * r["Torque"] * r["Torque factor"] / 60
     })
  )
  |> yield(name: "power")

Visualisatie instellingen: - Grafiektype: Time series - X-as: Tijd - Y-as: Power (Watt) - Optionele aanvullingen: - Moving average overlay om trends duidelijker te maken - Maximale vermogensmarkering

4. Efficiency (λ-CP curve) dashboard

Dit meer geavanceerde paneel toont de relatie tussen TSR (λ) en vermogenscoëfficiënt (CP), een belangrijke curve voor turbine-optimalisatie.

// Stap 1-3: Data ophalen (windsnelheid, rotorsnelheid, koppel)
// ...

// Stap 4: TSR en CP berekenen
union(tables: [windspeed, rotorspeed, torque, torqueFactor])
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> map(fn: (r) => {
       // TSR berekening
       TSR = (3.14159 * r["Rotor speed"] * 0.94) / (r["Wind speed"] * 30)

       // Vermogen berekening
       Power = 2 * 3.14159 * r["Rotor speed"] * r["Torque"] * r["Torque factor"] / 60

       // Beschikbaar windvermogen
       // A = π * R² (rotoroppervlak), ρ = 1.225 (luchtdichtheid)
       AvailableWindPower = 0.5 * 1.225 * (3.14159 * pow(v: 0.94, t: 2)) * pow(v: r["Wind speed"], t: 3)

       // Vermogenscoëfficiënt
       CP = Power / AvailableWindPower

       return { 
         _time: r._time,
         TSR: TSR, 
         CP: CP
       }
     })
  |> yield()

Visualisatie instellingen: - Grafiektype: XY scatter plot - X-as: TSR (λ) - Y-as: CP (vermogenscoëfficiënt) - Optionele aanvullingen: - Theoretische Betz-limiet (CP = 0.593) als horizontale lijn - Beste werkingsgebied markeren (meestal rond TSR = 4-5)

5. Pitch hoek vs vermogen dashboard

Dit paneel toont de relatie tussen pitchhoek en geleverd vermogen om de optimale hoek te vinden.

// Stap 1-3: Standaard dataverzameling
// ... (tijd, pitch, rotorsnelheid, koppel)

// Stap 4: Vermogen en pitch combineren
pitch = from(bucket: "Bries")
  |> range(start: minTime, stop: maxTime)
  |> filter(fn: (r) => r._measurement == "pitch" and r.runID == runID)
  |> filter(fn: (r) => r._field == "value")
  |> map(fn: (r) => ({ r with _value: float(v: r._value) }))
  |> aggregateWindow(every: 100ms, fn: mean, createEmpty: true)
  |> fill(column: "_value", usePrevious: true)
  |> map(fn: (r) => ({_value: r._value, _time: r._time, _field: "Pitch angle"}))

// Stap 5: Vermogen berekenen (zoals in voorbeeld 3)
// ...

// Stap 6: Combineren voor analyse
union(tables: [pitch, power])
  |> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
  |> yield()

Visualisatie instellingen: - Grafiektype: XY scatter plot of heatmap - X-as: Pitch angle (graden) - Y-as: Power (Watt)

Tips voor dashboardontwerp

  1. Consistente kleurcodering: Gebruik dezelfde kleuren voor dezelfde metingen in alle panelen.
  2. Windsnelheid: Blauw
  3. Voertuigsnelheid: Groen
  4. Rotor snelheid: Rood
  5. Vermogen: Oranje
  6. TSR: Paars

  7. Tijdsynchronisatie: Zorg ervoor dat alle panelen dezelfde RunID en tijdsperiode gebruiken voor consistente analyse.

  8. Annotaties toevoegen: Gebruik events uit de database om belangrijke momenten tijdens een testrit te markeren.

  9. Overlay van parameters: Combineer meerdere parameters in één grafiek wanneer hun onderlinge relatie belangrijk is.

  10. Ruwe en afgeleide gegevens scheiden: Gebruik aparte secties voor ruwe metingen en berekende waarden.

Een compleet dashboard opzetten

Voor een volledig Bries analyse-dashboard, raden we aan om de volgende panelen op te nemen:

  1. Overzicht sectie
  2. Ruwe windsnelheid en voertuigsnelheid
  3. Rotorsnelheid en pitchhoek
  4. Koppel

  5. Berekende parameters sectie

  6. TSR (Tip Speed Ratio)
  7. Vermogen
  8. Efficiëntie

  9. Correlaties sectie

  10. TSR vs CP curve
  11. Pitch vs Vermogen
  12. Windsnelheid vs Vermogen

  13. Metadata sectie

  14. RunID, datum en tijd
  15. Voertuigtype en bladtype
  16. Pitch mechaniek

Door deze voorbeelden te volgen, kun je snel een uitgebreid dashboard opzetten voor de analyse van windturbinedata van het Bries project.