fix forecast graf
This commit is contained in:
@@ -1025,7 +1025,13 @@ async def get_site_forecast_pv(
|
|||||||
JOIN ems.asset_pv_array apa
|
JOIN ems.asset_pv_array apa
|
||||||
ON apa.id = fpr.pv_array_id AND apa.site_id = fpr.site_id
|
ON apa.id = fpr.pv_array_id AND apa.site_id = fpr.site_id
|
||||||
WHERE fpr.site_id = $1
|
WHERE fpr.site_id = $1
|
||||||
AND fpi.interval_start::date = $2::date
|
AND (
|
||||||
|
fpi.interval_start
|
||||||
|
AT TIME ZONE COALESCE(
|
||||||
|
(SELECT timezone FROM ems.site WHERE id = $1),
|
||||||
|
'Europe/Prague'
|
||||||
|
)
|
||||||
|
)::date = $2::date
|
||||||
AND fpr.status = 'ok'
|
AND fpr.status = 'ok'
|
||||||
ORDER BY fpi.interval_start, fpr.pv_array_id, fpr.created_at DESC
|
ORDER BY fpi.interval_start, fpr.pv_array_id, fpr.created_at DESC
|
||||||
) latest
|
) latest
|
||||||
|
|||||||
@@ -244,22 +244,20 @@ export function useDashboardData(siteId: number | null) {
|
|||||||
|
|
||||||
const forecastBySlot = new Map<string, { a: number; b: number }>()
|
const forecastBySlot = new Map<string, { a: number; b: number }>()
|
||||||
const forecastDays: ForecastDayTotal[] = []
|
const forecastDays: ForecastDayTotal[] = []
|
||||||
const today = todayPrague
|
const weekDates = Array.from({ length: 7 }, (_, d) => pragueAddCalendarDays(todayPrague, d))
|
||||||
|
const forecastFetchDates = [...new Set([...dates, ...weekDates])].sort()
|
||||||
const forecastResults = await Promise.all(
|
const forecastResults = await Promise.all(
|
||||||
Array.from({ length: 7 }, (_, d) => {
|
forecastFetchDates.map((ymd) =>
|
||||||
const ymd = pragueAddCalendarDays(today, d)
|
getSiteForecastPv(siteId, ymd)
|
||||||
return getSiteForecastPv(siteId, ymd)
|
|
||||||
.then((fc) => ({ ymd, fc }))
|
.then((fc) => ({ ymd, fc }))
|
||||||
.catch(() => ({ ymd, fc: null as Awaited<ReturnType<typeof getSiteForecastPv>> | null }))
|
.catch(() => ({ ymd, fc: null as Awaited<ReturnType<typeof getSiteForecastPv>> | null })),
|
||||||
}),
|
),
|
||||||
)
|
)
|
||||||
for (const { ymd, fc } of forecastResults) {
|
const forecastByYmd = new Map(forecastResults.map((r) => [r.ymd, r.fc]))
|
||||||
if (!fc) {
|
const addForecastToByStart = (
|
||||||
forecastDays.push({ date: ymd, label: ymd, kwh: 0 })
|
fc: NonNullable<Awaited<ReturnType<typeof getSiteForecastPv>>>,
|
||||||
continue
|
byStart: Map<string, { a: number; b: number }>,
|
||||||
}
|
) => {
|
||||||
let kwh = 0
|
|
||||||
const byStart = new Map<string, { a: number; b: number }>()
|
|
||||||
for (const x of fc.pv_a ?? []) {
|
for (const x of fc.pv_a ?? []) {
|
||||||
const t = new Date(x.interval_start).getTime()
|
const t = new Date(x.interval_start).getTime()
|
||||||
const p = Number(x.power_w ?? 0)
|
const p = Number(x.power_w ?? 0)
|
||||||
@@ -274,12 +272,23 @@ export function useDashboardData(siteId: number | null) {
|
|||||||
cur.b += p
|
cur.b += p
|
||||||
byStart.set(slotTimeKey(t), cur)
|
byStart.set(slotTimeKey(t), cur)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for (const { fc } of forecastResults) {
|
||||||
|
if (!fc) continue
|
||||||
|
addForecastToByStart(fc, forecastBySlot)
|
||||||
|
}
|
||||||
|
for (const ymd of weekDates) {
|
||||||
|
const fc = forecastByYmd.get(ymd) ?? null
|
||||||
|
if (!fc) {
|
||||||
|
forecastDays.push({ date: ymd, label: ymd, kwh: 0 })
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const byStart = new Map<string, { a: number; b: number }>()
|
||||||
|
addForecastToByStart(fc, byStart)
|
||||||
|
let kwh = 0
|
||||||
for (const [, v] of byStart) {
|
for (const [, v] of byStart) {
|
||||||
kwh += ((v.a + v.b) * 0.25) / 1000
|
kwh += ((v.a + v.b) * 0.25) / 1000
|
||||||
}
|
}
|
||||||
for (const [k, v] of byStart) {
|
|
||||||
forecastBySlot.set(k, v)
|
|
||||||
}
|
|
||||||
const label = new Date(ymd + 'T12:00:00Z').toLocaleDateString('cs-CZ', {
|
const label = new Date(ymd + 'T12:00:00Z').toLocaleDateString('cs-CZ', {
|
||||||
weekday: 'short',
|
weekday: 'short',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
|
|||||||
Reference in New Issue
Block a user