History UI: small fixes (#29138)

This commit is contained in:
Michael Geers 2026-04-21 10:31:19 +02:00 • committed by GitHub
parent 1d3a963dc8
commit 2fb900c8ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 50 additions and 8 deletions

View file

@ -72,10 +72,14 @@ export default defineComponent({
const color = colors.palette[i % colors.palette.length];
const fill = dimColor(color);
const points = s.data.map((slot) => ({
x: new Date(slot.start).getTime(),
y: slotPower(slot, "import") - slotPower(slot, "export"),
}));
const points = s.data.map((slot) => {
const start = new Date(slot.start).getTime();
const end = new Date(slot.end).getTime();
return {
x: (start + end) / 2,
y: slotPower(slot, "import") - slotPower(slot, "export"),
};
});
return {
label: s.name,
@ -85,7 +89,7 @@ export default defineComponent({
fill: true,
pointRadius: 0,
borderWidth: 1.5,
tension: 0.3,
tension: 0.05,
};
});

View file

@ -1,6 +1,10 @@
<template>
<div class="container px-4 safe-area-inset">
<TopHeader title="History" />
<div class="alert alert-light mb-5">
This page is for development purposes only. Helps verify logged data. A proper
visualization is coming soon, stay tuned.
</div>
<div class="row">
<main class="col-12">
<div v-if="loading" class="my-5 text-center text-muted">loading...</div>

View file

@ -69,8 +69,10 @@ func QueryImportEnergy(from, to time.Time, aggregate string) ([]Series, error) {
addDuration := aggregateDurations[aggregate]
// use Go's tz offset instead of SQLite's 'localtime'
tz := time.Now().Format("-07:00")
// match timezone of stored timestamps for correct SQLite comparison
from = from.Local()
to = to.Local()
tz := from.Format("-07:00")
tx := db.Instance.Table("meters m").
Select(`e.name AS label, strftime('` + format + `', m.ts, '` + tz + `') AS bucket,
@ -223,7 +225,6 @@ func importProfile(entity entity, from time.Time) (*[96]float64, error) {
return nil, err
}
// use Go's tz offset instead of SQLite's 'localtime'
tz := from.Format("-07:00")
rows, err := db.Query(`SELECT min(ts) AS ts, avg(import) AS import

View file

@ -47,6 +47,39 @@ func TestSqliteTimestamp(t *testing.T) {
require.True(t, clock.Now().Equal(time.Time(ts)), "expected %v, got %v", clock.Now().Local(), time.Time(ts).Local())
}
func TestQueryImportEnergyUTCFilter(t *testing.T) {
require.NoError(t, db.NewInstance("sqlite", ":memory:"))
require.NoError(t, SetupSchema())
e := entity{Name: "grid", Group: "grid"}
require.NoError(t, db.Instance.FirstOrCreate(&e).Error)
// insert 4 slots at 16:00, 16:15, 16:30, 16:45 local time
loc := time.Now().Location()
base := time.Date(2026, 4, 15, 16, 0, 0, 0, loc)
for i := range 4 {
ts := base.Add(time.Duration(i) * 15 * time.Minute)
require.NoError(t, persist(e, ts, 0, float64(i+1)))
}
// query with UTC times that cover all 4 slots
// base is 16:00 local, convert to UTC and use a from before and to after
from := base.Add(-time.Hour).UTC()
to := base.Add(time.Hour).UTC()
res, err := QueryImportEnergy(from, to, "15m")
require.NoError(t, err)
require.Len(t, res, 1)
require.Len(t, res[0].Data, 4, "expected all 4 slots, got %d", len(res[0].Data))
var totalExport float64
for _, s := range res[0].Data {
totalExport += s.Export
}
require.InDelta(t, 1+2+3+4, totalExport, 0.001)
}
func TestUpdateProfile(t *testing.T) {
clock := clock.NewMock()