Flux: Solar Production Data Resets at 4pm PST

Version 12.2.0 Self-hosting on RPi4
Trying to collect and display daily total PV production in my dashboard. G-bloc gathers information correctly but resets to 0kWh each day at 4PM PST (Los Angeles, Ca. USA).
Here’s my current G-bloc:

from(bucket: “HHHHH-FFFFFF”)
|> range(start: today(), stop: now())
|> filter(fn: (r) =>
r.\_measurement == “mqtt_consumer” and
r.\_field == “value” and
(r.topic == “solar_assistant/inverter_1/pv_power_1/state” or
r.topic == “solar_assistant/inverter_1/pv_power_2/state”)
)
|> aggregateWindow(every: 1m, fn: mean, createEmpty: true) // createEmpty:true ensures minute buckets exist
|> pivot(rowKey:\[“\_time”\], columnKey:\[“topic”\], valueColumn:“\_value”)
|> map(fn: (r) => ({
\_time: r.\_time,
pv1: if exists r\[“solar_assistant/inverter_1/pv_power_1/state”\] then float(v: r\[“solar_assistant/inverter_1/pv_power_1/state”\]) else 0.0,
pv2: if exists r\[“solar_assistant/inverter_1/pv_power_2/state”\] then float(v: r\[“solar_assistant/inverter_1/pv_power_2/state”\]) else 0.0
}))
|> window(every: 1d, offset: -12h)
|> map(fn: (r) => ({ \_time: r.\_time, \_value: (if (r.pv1 + r.pv2) < 0.0 then 0.0 else (r.pv1 + r.pv2)) \* (1.0 / 60.0) })) // Wh per minute, clamp negatives
|> cumulativeSum(columns: \[“\_value”\])
|> map(fn: (r) => ({ r with \_value: r.\_value / 1000.0 })) // Wh → kWh
|> last()

XXX I’m trying to reset this information daily at midnight and am currently using at offset of -12. This resets at 4AM, which is fine. I can change this easily.

What’s happening is that the daily total resets at 4PM and that excludes some additional PV production, especially in the summertime .

  • What Grafana version and what operating system are you using?

  • What are you trying to achieve?

  • How are you trying to achieve it?

  • What happened?

  • What did you expect to happen?

  • Can you copy/paste the configuration(s) that you are having problems with?

  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.

  • Did you follow any online instructions? If so, what is the URL?

Welcom @martybob to the Grafana forum.

When you open the Time Picker, what is the time shown in the lower left? Does it show Browser Time, United States, PST?

Also, are the timestamps in your Influx data in UTC? That is considered best practice and makes things much easier to troubleshoot.

Grant2, pulling down Time Picker looks to show my correct local time: 2025-12-10 16:49:23 to 2025-12-11 04:49:26

HOWEVER!! I think you nailed it. My Influxdb logs are showing UTC time 8 hrs ahead. (2025-12-11T12:53:32Z) That could be the trick. I’ll have to work out how to get that corrected. Ideas?

Thanks, Marty B.

What tool / software do you use to ingest the data into InfluxDB?

The precise method is Telegraf, Mosquitto, Influxdb then grafana.

So I rewrote the G-bloc to account for UTC on the influx data. I’ll see later today if that works.

1 Like

I pulling data from another solar monitoring app called Solar Assistant. It’s drawing its data from the inverter wireless dongle. I’m using an matt broker that SA allows to get my data via a telegraf.cnfg file that runs on a docker container the Pi. All the 4 main data gathering and reporting programs run as docker containers.

My plan is to be able to pull the data directly from the inverter either wired or wireless and import it into my existing monitoring program.

All in all, I started learning Linux this summer after I hurt my back and couldn’t windsurf and work in my woodshop much. But now, with PT, I’m back up to speed.

So I ended up with a solution and should have thought of this earlier. By assigning my timezone to Los Angeles the 4pm reset solved itself. Here’s the updated query:

import “timezone”

import “date”

import “math”

option location = timezone.location(name: “America/Los_Angeles”)

from(bucket: “solar_data”)

|> range(

  start: date.truncate(t: now(), unit: 1d),

  stop: now()

)

|> filter(fn: (r) =>

r.\_measurement == "mqtt_consumer" and

r.\_field == "value" and

(

  r.topic == "solar_assistant/inverter_1/pv_power_1/state" or

  r.topic == "solar_assistant/inverter_1/pv_power_2/state"

)

)

// 1-minute smoothing

|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)

// PV1 + PV2

|> pivot(rowKey: [“_time”], columnKey: [“topic”], valueColumn: “_value”)

|> map(fn: (r) => ({

  r with

  \_value:

    (if exists r\["solar_assistant/inverter_1/pv_power_1/state"\]

     then float(v: r\["solar_assistant/inverter_1/pv_power_1/state"\])

     else 0.0) +

    (if exists r\["solar_assistant/inverter_1/pv_power_2/state"\]

     then float(v: r\["solar_assistant/inverter_1/pv_power_2/state"\])

     else 0.0)

}))

// Clamp + W → Wh per minute

|> map(fn: (r) => ({

  r with

  \_value: if r.\_value < 0.0 then 0.0 else r.\_value / 60.0

}))

// Sum everything since midnight

|> sum()

// Wh → kWh, 2 decimal places

|> map(fn: (r) => ({

  \_value: math.round(x: (r.\_value / 1000.0) \* 100.0) / 100.0

}))

|> yield(name: “today_kWh”)