rebuild consumpton baselaline
This commit is contained in:
64
scripts/rebuild_consumption_baseline_stats.sh
Executable file
64
scripts/rebuild_consumption_baseline_stats.sh
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tenký wrapper nad ems.fn_rebuild_consumption_baseline_stats (kanonické API je v PostgreSQL).
|
||||
#
|
||||
# Použití:
|
||||
# export DATABASE_URL='postgres://…/ems'
|
||||
# LOOKBACK_DAYS=14 ./scripts/rebuild_consumption_baseline_stats.sh 2 # jedna lokality (site.id)
|
||||
#
|
||||
# ./scripts/rebuild_consumption_baseline_stats.sh --all # celá tabulka stats + všichni sites
|
||||
#
|
||||
# MCP / psql přímo (doporučeno v SQL-first režimu):
|
||||
# select * from ems.fn_rebuild_consumption_baseline_stats(2, 30);
|
||||
# select * from ems.fn_rebuild_consumption_baseline_stats(null::int, 30);
|
||||
#
|
||||
# DRY_RUN=1 … — jen řádek count (žádné mazání).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ -z "${DATABASE_URL:-}" ]] && [[ -z "${PGHOST:-}" ]]; then
|
||||
echo "Nastav DATABASE_URL nebo PG proměnné." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
LOOKBACK="${LOOKBACK_DAYS:-30}"
|
||||
if ! [[ "$LOOKBACK" =~ ^[0-9]+$ ]] || [[ "$LOOKBACK" -lt 1 ]]; then
|
||||
echo "LOOKBACK_DAYS musí být kladné celé číslo." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PSQL=(psql -v ON_ERROR_STOP=1)
|
||||
if [[ -n "${DATABASE_URL:-}" ]]; then
|
||||
PSQL+=("$DATABASE_URL")
|
||||
else
|
||||
PSQL+=("${PGDATABASE:-ems}")
|
||||
fi
|
||||
|
||||
MODE="${1:?Chybí argument: site_id (číslo) nebo --all}"
|
||||
DRY="${DRY_RUN:-0}"
|
||||
|
||||
if [[ "$MODE" == "--all" ]]; then
|
||||
if [[ "$DRY" == "1" ]] || [[ "$DRY" == "true" ]]; then
|
||||
echo "DRY_RUN: consumption_baseline_stats řádků celkem, sites:"
|
||||
"${PSQL[@]}" -c "
|
||||
select count(*) as stats_rows from ems.consumption_baseline_stats;
|
||||
select count(*) as sites from ems.site;
|
||||
"
|
||||
exit 0
|
||||
fi
|
||||
echo "Volám fn_rebuild_consumption_baseline_stats(null, ${LOOKBACK}) …"
|
||||
"${PSQL[@]}" -c "select * from ems.fn_rebuild_consumption_baseline_stats(null::int, ${LOOKBACK}::int);"
|
||||
else
|
||||
SITE_ID="$MODE"
|
||||
if ! [[ "$SITE_ID" =~ ^[0-9]+$ ]]; then
|
||||
echo "První argument: site_id (číslo) nebo --all." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$DRY" == "1" ]] || [[ "$DRY" == "true" ]]; then
|
||||
"${PSQL[@]}" -c "select count(*) from ems.consumption_baseline_stats where site_id = ${SITE_ID}::int;"
|
||||
exit 0
|
||||
fi
|
||||
echo "Volám fn_rebuild_consumption_baseline_stats(${SITE_ID}, ${LOOKBACK}) …"
|
||||
"${PSQL[@]}" -c "select * from ems.fn_rebuild_consumption_baseline_stats(${SITE_ID}::int, ${LOOKBACK}::int);"
|
||||
fi
|
||||
|
||||
echo "Hotovo. Spusť rolling/denní plán nebo počkej na scheduler."
|
||||
126
scripts/wipe_pv_forecast_prague_day.sh
Executable file
126
scripts/wipe_pv_forecast_prague_day.sh
Executable file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env bash
|
||||
# Odstraní predikované PV intervaly (a navázaný tracking přesnosti) pro jeden kalendářní den v Europe/Prague.
|
||||
#
|
||||
# VAROVÁNÍ (provozní / datová kontinuita)
|
||||
# ────────────────────────────────────────
|
||||
# - Řád v repozitáři je držet historické běhy FVE forecastu pro analýzu a učení delty (@see docs/04-modules/forecast.md).
|
||||
# - Používej jen když vědomě potřebuješ „načisto“ vygenerovat nový forecast (forecast service).
|
||||
# - Fyzický breaker řeší měnič/Deye — skript jen čistí databázi od uloženého PV forecastu.
|
||||
#
|
||||
# Nenahrazuje mazání/load baseline spotřeby (`consumption_baseline_stats` / její výpočet).
|
||||
#
|
||||
# Použití:
|
||||
# export DATABASE_URL='postgres://…/ems'
|
||||
# ./scripts/wipe_pv_forecast_prague_day.sh # dnešní den (Europe/Prague), všechny lokality
|
||||
# ./scripts/wipe_pv_forecast_prague_day.sh 2026-05-02 # konkrétní datum YYYY-MM-DD
|
||||
# ./scripts/wipe_pv_forecast_prague_day.sh 2026-05-02 2 # jen site.id = 2 (např. home-01)
|
||||
#
|
||||
# Šedý režim (jen počty, žádné mazání):
|
||||
# DRY_RUN=1 ./scripts/wipe_pv_forecast_prague_day.sh 2026-05-02 2
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DAY="${1:-$(TZ=Europe/Prague date +%Y-%m-%d)}"
|
||||
SITE_ID="${2:-}"
|
||||
|
||||
if ! [[ "$DAY" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
|
||||
echo "Datum musí být YYYY-MM-DD, dostal jsem: $DAY" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${DATABASE_URL:-}" ]] && [[ -z "${PGHOST:-}" ]]; then
|
||||
echo "Nastav DATABASE_URL nebo standardní PG proměnné (PGHOST, PGUSER, PGDATABASE, …)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PSQL=(psql -v ON_ERROR_STOP=1)
|
||||
if [[ -n "${DATABASE_URL:-}" ]]; then
|
||||
PSQL+=("$DATABASE_URL")
|
||||
else
|
||||
PSQL+=("${PGDATABASE:-ems}")
|
||||
fi
|
||||
|
||||
SITE_CLAUSE=""
|
||||
if [[ -n "$SITE_ID" ]]; then
|
||||
if ! [[ "$SITE_ID" =~ ^[0-9]+$ ]]; then
|
||||
echo "Druhý argument musí být číslo site_id." >&2
|
||||
exit 1
|
||||
fi
|
||||
SITE_CLAUSE="AND r.site_id = ${SITE_ID}::int"
|
||||
fi
|
||||
|
||||
DRY="${DRY_RUN:-0}"
|
||||
|
||||
if [[ "$DRY" == "1" ]] || [[ "$DRY" == "true" ]]; then
|
||||
echo "DRY_RUN: den $DAY (Europe/Prague)${SITE_ID:+ site_id=$SITE_ID}"
|
||||
"${PSQL[@]}" -c "
|
||||
with bounds as (
|
||||
select
|
||||
('${DAY}'::date::text || ' 00:00:00')::timestamp at time zone 'Europe/Prague' as ts_start,
|
||||
(('${DAY}'::date + 1)::text || ' 00:00:00')::timestamp at time zone 'Europe/Prague' as ts_end
|
||||
),
|
||||
targets as (
|
||||
select fi.run_id, fi.pv_array_id, fi.interval_start
|
||||
from ems.forecast_pv_interval fi
|
||||
inner join ems.forecast_pv_run r on r.id = fi.run_id
|
||||
cross join bounds b
|
||||
where fi.interval_start >= b.ts_start
|
||||
and fi.interval_start < b.ts_end
|
||||
${SITE_CLAUSE}
|
||||
)
|
||||
select count(*) as interval_rows_to_delete, count(distinct run_id) as distinct_run_ids
|
||||
from targets;
|
||||
"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Mažu PV forecast intervaly pro den $DAY (Europe/Prague)${SITE_ID:+ site_id=$SITE_ID} …"
|
||||
|
||||
"${PSQL[@]}" -c "
|
||||
begin;
|
||||
|
||||
create temporary table _ems_wipe_pv_forecast_targets (
|
||||
run_id int not null,
|
||||
pv_array_id int not null,
|
||||
interval_start timestamptz not null
|
||||
) on commit drop;
|
||||
|
||||
with bounds as (
|
||||
select
|
||||
('${DAY}'::date::text || ' 00:00:00')::timestamp at time zone 'Europe/Prague' as ts_start,
|
||||
(('${DAY}'::date + 1)::text || ' 00:00:00')::timestamp at time zone 'Europe/Prague' as ts_end
|
||||
)
|
||||
insert into _ems_wipe_pv_forecast_targets (run_id, pv_array_id, interval_start)
|
||||
select fi.run_id, fi.pv_array_id, fi.interval_start
|
||||
from ems.forecast_pv_interval fi
|
||||
inner join ems.forecast_pv_run r on r.id = fi.run_id
|
||||
cross join bounds b
|
||||
where fi.interval_start >= b.ts_start
|
||||
and fi.interval_start < b.ts_end
|
||||
${SITE_CLAUSE};
|
||||
|
||||
delete from ems.forecast_accuracy fa
|
||||
using (select distinct run_id, interval_start from _ems_wipe_pv_forecast_targets) t
|
||||
where fa.run_id = t.run_id
|
||||
and fa.interval_start = t.interval_start;
|
||||
|
||||
delete from ems.forecast_pv_interval fi
|
||||
using _ems_wipe_pv_forecast_targets t
|
||||
where fi.run_id = t.run_id
|
||||
and fi.pv_array_id = t.pv_array_id
|
||||
and fi.interval_start = t.interval_start;
|
||||
|
||||
delete from ems.forecast_pv_run fr
|
||||
where fr.id in (select distinct run_id from _ems_wipe_pv_forecast_targets)
|
||||
and not exists (
|
||||
select 1 from ems.forecast_pv_interval x where x.run_id = fr.id
|
||||
);
|
||||
|
||||
select
|
||||
(select count(*) from _ems_wipe_pv_forecast_targets) as targets_interval_rows,
|
||||
(select count(distinct run_id) from _ems_wipe_pv_forecast_targets) as distinct_run_ids_touched;
|
||||
|
||||
commit;
|
||||
"
|
||||
|
||||
echo "Hotovo. Spusť forecast job / službu v backendu (Open-Meteo běh), aby se řádky ${DAY} doplnily znovu."
|
||||
Reference in New Issue
Block a user