How to plot day ahead prices in Grafana

Is anyone able to plot in Grafana the current day ahead prices for electricity?

I’m using Influxdb.

The hourly prices are stored as attributes in the entity for the “today average price”, but I don’t know how to use attributes in Grafana.

It seems Home assistant stores in Influxdb only the entity value and not the attributes, is it correct?

Yes that’s correct. You’ll have to create template sensors from the attributes.

Actually all attributes are stored in InfluxDB.
I will check how to extract them using Flux, since I have InfluxDB v2 which likely allows it.

Nope. Only the state.

Not true.

I run this query on Grafana:

SELECT first("prices_str") FROM "€/kWh" WHERE ("entity_id"::tag = 'current_electricity_market_price') AND $timeFilter GROUP BY time(1d) fill(null)

and I got (two columns, I post them one after the other and as quotation for practical reasons):

Time:
23/03/2026, 01:00:00

First:
[{‘from’: datetime.datetime(2026, 3, 22, 23, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 0, 0, tzinfo=tzutc()), ‘price’: 0.12251}, {‘from’: datetime.datetime(2026, 3, 23, 0, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 1, 0, tzinfo=tzutc()), ‘price’: 0.12084}, {‘from’: datetime.datetime(2026, 3, 23, 1, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 2, 0, tzinfo=tzutc()), ‘price’: 0.12097}, {‘from’: datetime.datetime(2026, 3, 23, 2, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 3, 0, tzinfo=tzutc()), ‘price’: 0.11966}, {‘from’: datetime.datetime(2026, 3, 23, 3, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 4, 0, tzinfo=tzutc()), ‘price’: 0.12543}, {‘from’: datetime.datetime(2026, 3, 23, 4, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 5, 0, tzinfo=tzutc()), ‘price’: 0.14252}, {‘from’: datetime.datetime(2026, 3, 23, 5, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 6, 0, tzinfo=tzutc()), ‘price’: 0.17483}, {‘from’: datetime.datetime(2026, 3, 23, 6, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 7, 0, tzinfo=tzutc()), ‘price’: 0.18474}, {‘from’: datetime.datetime(2026, 3, 23, 7, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 8, 0, tzinfo=tzutc()), ‘price’: 0.14784}, {‘from’: datetime.datetime(2026, 3, 23, 8, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 9, 0, tzinfo=tzutc()), ‘price’: 0.10681}, {‘from’: datetime.datetime(2026, 3, 23, 9, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 10, 0, tzinfo=tzutc()), ‘price’: 0.07596}, {‘from’: datetime.datetime(2026, 3, 23, 10, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 11, 0, tzinfo=tzutc()), ‘price’: 0.0452}, {‘from’: datetime.datetime(2026, 3, 23, 11, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 12, 0, tzinfo=tzutc()), ‘price’: 0.04671}, {‘from’: datetime.datetime(2026, 3, 23, 12, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 13, 0, tzinfo=tzutc()), ‘price’: 0.06637}, {‘from’: datetime.datetime(2026, 3, 23, 13, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 14, 0, tzinfo=tzutc()), ‘price’: 0.08541}, {‘from’: datetime.datetime(2026, 3, 23, 14, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 15, 0, tzinfo=tzutc()), ‘price’: 0.102}, {‘from’: datetime.datetime(2026, 3, 23, 15, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 16, 0, tzinfo=tzutc()), ‘price’: 0.12346}, {‘from’: datetime.datetime(2026, 3, 23, 16, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 17, 0, tzinfo=tzutc()), ‘price’: 0.1729}, {‘from’: datetime.datetime(2026, 3, 23, 17, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 18, 0, tzinfo=tzutc()), ‘price’: 0.2495}, {‘from’: datetime.datetime(2026, 3, 23, 18, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 19, 0, tzinfo=tzutc()), ‘price’: 0.2389}, {‘from’: datetime.datetime(2026, 3, 23, 19, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 20, 0, tzinfo=tzutc()), ‘price’: 0.1995}, {‘from’: datetime.datetime(2026, 3, 23, 20, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 21, 0, tzinfo=tzutc()), ‘price’: 0.16809}, {‘from’: datetime.datetime(2026, 3, 23, 21, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 22, 0, tzinfo=tzutc()), ‘price’: 0.15219}, {‘from’: datetime.datetime(2026, 3, 23, 22, 0, tzinfo=tzutc()), ‘till’: datetime.datetime(2026, 3, 23, 23, 0, tzinfo=tzutc()), ‘price’: 0.13706}]

I don’t think that InfluxQL (so, Influxdb v1) language allows to process it further, but using Flux maybe it’s possible.

Flux query to do it:

import "array"
import "strings"
import "regexp"
import "date"

pad2 = (s) => if strings.strlen(v: s) == 1 then "0" + s else s

fromToRFC3339 = (entry) => {
    fromPart = regexp.findString(r: /'from': datetime\.datetime\([^)]+\)/, v: entry)

    cleaned = strings.replaceAll(
        v: strings.replaceAll(
            v: fromPart,
            t: "'from': datetime.datetime(",
            u: "",
        ),
        t: ", tzinfo=tzutc())",
        u: "",
    )

    parts = strings.split(v: cleaned, t: ", ")

    return
        parts[0] + "-" +
        pad2(s: parts[1]) + "-" +
        pad2(s: parts[2]) + "T" +
        pad2(s: parts[3]) + ":" +
        pad2(s: parts[4]) + ":00Z"
}

entryToPrice = (entry) => {
    pricePart = regexp.findString(r: /'price': [0-9.]+/, v: entry)
    return float(v: strings.replaceAll(v: pricePart, t: "'price': ", u: ""))
}

raw =
    from(bucket: "home_assistant/autogen")
        |> range(start: today(), stop: date.add(d: 1d, to: today()))
        |> filter(fn: (r) =>
            r._measurement == "€/kWh" and
            r.entity_id == "current_electricity_market_price" and
            r._field == "prices_str"
        )
        |> first()

rawValues = raw |> findColumn(fn: (key) => true, column: "_value")
pricesStr = rawValues[0]

body = strings.replaceAll(
    v: strings.replaceAll(v: pricesStr, t: "[", u: ""),
    t: "]",
    u: "",
)

entries = strings.split(v: body, t: "}, {")

rows = array.map(
    arr: entries,
    fn: (x) => ({
        _time: time(v: fromToRFC3339(entry: x)),
        _value: entryToPrice(entry: x),
    }),
)

array.from(rows: rows)
    |> rename(columns: {_value: "price"})
    |> keep(columns: ["_time", "price"])