WITH pts AS ( SELECT cle, ts, valeur, least(coalesce(lead(ts) OVER (PARTITION BY cle ORDER BY ts), now()), ts + interval '1 hour') AS fin FROM mesure WHERE cle IN ('sensor.victron_consumption_power_l1', 'sensor.victron_evcs_ac_power', 'sensor.victron_grid_power_l1', 'sensor.victron_pv_power_system') AND ts > now() - interval '40 days' ), jours AS ( SELECT d::date AS j, (d::date + time '18:00') AT TIME ZONE 'Europe/Paris' AS s0, (d::date + time '21:30') AT TIME ZONE 'Europe/Paris' AS n0, (d::date + 1 + time '01:24') AT TIME ZONE 'Europe/Paris' AS hc, (d::date + 1 + time '09:00') AT TIME ZONE 'Europe/Paris' AS n1 FROM generate_series(current_date - 35, current_date, interval '1 day') d ), e AS ( SELECT j.j, sum(p.valeur * extract(epoch FROM least(p.fin, j.n0) - greatest(p.ts, j.s0))) FILTER (WHERE p.cle = 'sensor.victron_consumption_power_l1' AND p.fin > j.s0 AND p.ts < j.n0) AS c_soir, sum(p.valeur * extract(epoch FROM least(p.fin, j.n0) - greatest(p.ts, j.s0))) FILTER (WHERE p.cle = 'sensor.victron_evcs_ac_power' AND p.fin > j.s0 AND p.ts < j.n0) AS v_soir, sum(p.valeur * extract(epoch FROM least(p.fin, j.hc) - greatest(p.ts, j.n0))) FILTER (WHERE p.cle = 'sensor.victron_consumption_power_l1' AND p.fin > j.n0 AND p.ts < j.hc) AS c_hc, sum(p.valeur * extract(epoch FROM least(p.fin, j.hc) - greatest(p.ts, j.n0))) FILTER (WHERE p.cle = 'sensor.victron_evcs_ac_power' AND p.fin > j.n0 AND p.ts < j.hc) AS v_hc, sum(p.valeur * extract(epoch FROM least(p.fin, j.n1) - greatest(p.ts, j.n0))) FILTER (WHERE p.cle = 'sensor.victron_consumption_power_l1' AND p.fin > j.n0 AND p.ts < j.n1) AS c_nuit, sum(p.valeur * extract(epoch FROM least(p.fin, j.n1) - greatest(p.ts, j.n0))) FILTER (WHERE p.cle = 'sensor.victron_evcs_ac_power' AND p.fin > j.n0 AND p.ts < j.n1) AS v_nuit, sum(p.valeur * extract(epoch FROM least(p.fin, j.n1) - greatest(p.ts, j.n0))) FILTER (WHERE p.cle = 'sensor.victron_grid_power_l1' AND p.fin > j.n0 AND p.ts < j.n1) AS r_nuit, sum(p.valeur * extract(epoch FROM least(p.fin, j.n1) - greatest(p.ts, j.n0))) FILTER (WHERE p.cle = 'sensor.victron_pv_power_system' AND p.fin > j.n0 AND p.ts < j.n1) AS pv_nuit FROM jours j JOIN pts p ON p.fin > j.s0 AND p.ts < j.n1 GROUP BY j.j ), nuits AS ( SELECT j.j, j.n0, j.n1, round(((coalesce(c_soir,0) - coalesce(v_soir,0)) / 3.6e6)::numeric, 2) AS soiree_kwh, round(((coalesce(c_hc,0) - coalesce(v_hc,0)) / 3.6e6)::numeric, 2) AS maison_hc_kwh, round(((coalesce(c_nuit,0) - coalesce(v_nuit,0)) / 3.6e6)::numeric, 2) AS maison_nuit_kwh, round((coalesce(v_nuit,0) / 3.6e6)::numeric, 2) AS voiture_kwh, round((coalesce(r_nuit,0) / 3.6e6)::numeric, 2) AS reseau_kwh, round((coalesce(pv_nuit,0) / 3.6e6)::numeric, 2) AS pv_avant_9h_kwh, (SELECT valeur FROM mesure WHERE cle = 'sensor.victron_battery_soc' AND ts <= j.n0 AND valeur > 0 ORDER BY ts DESC LIMIT 1) AS soc_2130, (SELECT valeur FROM mesure WHERE cle = 'sensor.victron_battery_soc' AND ts <= j.hc AND valeur > 0 ORDER BY ts DESC LIMIT 1) AS soc_0124, (SELECT valeur FROM mesure WHERE cle = 'sensor.victron_battery_soc' AND ts <= j.n1 AND valeur > 0 ORDER BY ts DESC LIMIT 1) AS soc_9h FROM jours j JOIN e ON e.j = j.j WHERE j.n1 <= now() AND j.j >= date '2026-09-04' )