All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 24s
Confirmed against Sungrow's own docs and live-tested against a real battery plant: SOC and charge/discharge power live at the *device* level (getDeviceRealTimeData against the hybrid inverter's ps_key, device_type 14), not in the plant-aggregate points used elsewhere in this client -- querying them via the plant-level endpoint just returns null. Battery status is fetched once per live "today" poll (not backfilled historically) and stored in three new nullable columns, self-migrated on startup since there's no Alembic here. Also fixes the dashboard's self-consumption line to derive from load - import rather than generation - export, which overstated "solar -> house" for battery systems (a chunk of that gap was going into charging, not the house). The live flow diagram now shows a Battery node (SOC + charge/discharge) that stays hidden entirely for solar-only plants like Kallangur. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
32 lines
1.1 KiB
Python
32 lines
1.1 KiB
Python
from datetime import datetime
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class IntervalDataPoint(BaseModel):
|
|
ts: datetime
|
|
generation_kwh: float
|
|
load_kwh: float
|
|
import_kwh: float
|
|
export_kwh: float
|
|
resolution_minutes: int
|
|
# Only populated for plants with a battery (from a live device-level
|
|
# poll, not backfillable historical data) -- None for solar-only plants
|
|
# and for every historical/backfilled point.
|
|
battery_soc_percent: float | None = None
|
|
battery_charge_w: float | None = None
|
|
battery_discharge_w: float | None = None
|
|
|
|
def as_row(self, source: str) -> dict:
|
|
return {
|
|
"ts": self.ts,
|
|
"source": source,
|
|
"generation_kwh": self.generation_kwh,
|
|
"load_kwh": self.load_kwh,
|
|
"import_kwh": self.import_kwh,
|
|
"export_kwh": self.export_kwh,
|
|
"resolution_minutes": self.resolution_minutes,
|
|
"battery_soc_percent": self.battery_soc_percent,
|
|
"battery_charge_w": self.battery_charge_w,
|
|
"battery_discharge_w": self.battery_discharge_w,
|
|
}
|