Count driving only and include charging losses

This commit is contained in:
TCFDONMEZ
2026-10-08 15:51:38 +03:00
parent 050fe84d6a
commit ae036b9d65
16 changed files with 104 additions and 41 deletions
+5 -3
View File
@@ -27,11 +27,12 @@ export default async function ChargingPage() {
return (
<Shell active="/charging" title="Şarj" subtitle={`${sessions.length} DC seans`}>
<div className="tiles">
<Tile label="Toplam alınan" value={precise(total.energyKwh)} unit="kWh" tone="gold" />
<Tile label="Bataryaya giren net" value={precise(total.energyKwh)} unit="kWh" tone="gold" />
<Tile label="Şebekeden alınan (+%10)" value={precise(total.gridEnergyKwh)} unit="kWh" tone="gold" />
<Tile label="Toplam ödenen" value={money(total.cost)} tone="gold" />
<Tile
label="Ortalama birim"
value={total.energyKwh > 0 ? money(total.cost / total.energyKwh) : "—"}
value={total.gridEnergyKwh > 0 ? money(total.cost / total.gridEnergyKwh) : "—"}
note="kWh başına"
tone="teal"
/>
@@ -78,7 +79,8 @@ export default async function ChargingPage() {
<Row label="Başlangıç" value={dateTime(session.startedAt)} />
<Row label="Bitiş" value={dateTime(session.endedAt)} />
<Row label="Ölçülen süre" value={duration(session.durationSeconds)} />
<Row label="Alınan enerji" value={`${precise(session.energyKwh)} kWh`} />
<Row label="Bataryaya giren net" value={`${precise(session.energyKwh)} kWh`} />
<Row label="Şebekeden alınan (+%10)" value={`${precise(session.gridEnergyKwh ?? session.energyKwh * 1.1)} kWh`} />
<Row label="Kazanılan doluluk" value={gained === null ? "—" : `%${num(gained)}`} />
<Row label="Tepe güç" value={peak > 0 ? `${num(peak)} kW` : "—"} />
<Row label="Ortalama güç" value={average > 0 ? `${num(average)} kW` : "—"} />
+5 -4
View File
@@ -36,8 +36,8 @@ export default async function OverviewPage() {
>
<div className="tiles">
<Tile
label="Toplam alınan"
value={precise(charge.energyKwh)}
label="Şebekeden alınan"
value={precise(charge.gridEnergyKwh)}
unit="kWh"
note={`${charge.sessions} DC şarj`}
tone="gold"
@@ -45,7 +45,7 @@ export default async function OverviewPage() {
<Tile
label="Ödenen"
value={money(charge.cost)}
note={charge.energyKwh > 0 ? `${money(charge.cost / charge.energyKwh)}/kWh ort.` : undefined}
note={charge.gridEnergyKwh > 0 ? `${money(charge.cost / charge.gridEnergyKwh)}/kWh ort.` : undefined}
tone="gold"
/>
<Tile label="Son 30 gün" value={num(recent.km)} unit="km" note={efficiency(recent.kwh, recent.km)} tone="teal" />
@@ -68,7 +68,8 @@ export default async function OverviewPage() {
<h2 className="card-title">Son şarj</h2>
<div className="rows">
<Row label="Tarih" value={dateTime(lastSession.startedAt)} />
<Row label="Alınan enerji" value={`${precise(lastSession.energyKwh)} kWh`} />
<Row label="Bataryaya giren net" value={`${precise(lastSession.energyKwh)} kWh`} />
<Row label="Şebekeden alınan (+%10)" value={`${precise(lastSession.gridEnergyKwh ?? lastSession.energyKwh * 1.1)} kWh`} />
<Row
label="Doluluk"
value={
+3 -1
View File
@@ -47,6 +47,7 @@ export async function loadOverview(dayLimit = 60, sessionLimit = 60): Promise<Ov
export interface ChargeTotals {
energyKwh: number;
gridEnergyKwh: number;
cost: number;
sessions: number;
seconds: number;
@@ -58,6 +59,7 @@ export function sumCharging(sessions: ChargingSession[]): ChargeTotals {
return sessions.reduce<ChargeTotals>(
(total, session) => ({
energyKwh: total.energyKwh + session.energyKwh,
gridEnergyKwh: total.gridEnergyKwh + (session.gridEnergyKwh ?? session.energyKwh * 1.1),
cost: total.cost + session.totalCost,
sessions: total.sessions + 1,
seconds: total.seconds + session.durationSeconds,
@@ -68,7 +70,7 @@ export function sumCharging(sessions: ChargingSession[]): ChargeTotals {
: 0),
peakKw: Math.max(total.peakKw, ...session.curve.map((point) => point.powerKw), 0),
}),
{ energyKwh: 0, cost: 0, sessions: 0, seconds: 0, socGained: 0, peakKw: 0 },
{ energyKwh: 0, gridEnergyKwh: 0, cost: 0, sessions: 0, seconds: 0, socGained: 0, peakKw: 0 },
);
}
+2
View File
@@ -41,6 +41,8 @@ export interface ChargingSession {
endedAt: Date;
durationSeconds: number;
energyKwh: number;
chargingLossPercent: number;
gridEnergyKwh: number;
pricePerKwh: number;
totalCost: number;
startSocPercent?: number;
+9 -3
View File
@@ -49,15 +49,21 @@ export function validateChargingSession(body: unknown, pathSessionId: string): C
});
const startSocPercent = record.startSocPercent;
const endSocPercent = record.endSocPercent;
const energyKwh = bounded(record.energyKwh, 0, 1000, "energyKwh");
const pricePerKwh = bounded(record.pricePerKwh, 0, 1_000_000, "pricePerKwh");
const chargingLossPercent = 10;
const gridEnergyKwh = energyKwh * 1.1;
return {
installationId: validateUuid(record.installationId, "installationId"),
sessionId,
startedAt: validateDate(record.startedAt, "startedAt"),
endedAt: validateDate(record.endedAt, "endedAt"),
durationSeconds: bounded(record.durationSeconds, 0, 604800, "durationSeconds"),
energyKwh: bounded(record.energyKwh, 0, 1000, "energyKwh"),
pricePerKwh: bounded(record.pricePerKwh, 0, 1_000_000, "pricePerKwh"),
totalCost: bounded(record.totalCost, 0, 1_000_000_000, "totalCost"),
energyKwh,
chargingLossPercent,
gridEnergyKwh,
pricePerKwh,
totalCost: gridEnergyKwh * pricePerKwh,
...(startSocPercent === undefined ? {} : { startSocPercent: bounded(startSocPercent, 0, 100, "startSocPercent") }),
...(endSocPercent === undefined ? {} : { endSocPercent: bounded(endSocPercent, 0, 100, "endSocPercent") }),
curve,