fix: BigScreen data display, carbon, energy history (v1.6.2)

BigScreen fixes:
- Fix NaN in 今日用电 (normalize energy_today structure)
- Fix 总设备=0 (compute from online+offline)
- Fix energy flow zeros (map total_load→total_power)
- Fix 今日发电=0 (extract from nested energy_today)

Backend fixes (synced from ems-core):
- Carbon overview fallback from energy_data × emission_factors
- Energy history: datetime parsing (was 500)
- Dashboard generation: station-level dedup (93K→14.8K kWh)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Du Wenbo
2026-04-11 09:56:23 +08:00
parent cbdf8f21c5
commit bd51997de1
8 changed files with 145 additions and 43 deletions

View File

@@ -40,28 +40,24 @@ async def get_overview(db: AsyncSession = Depends(get_db), user: User = Depends(
# Fallback: if daily summary is empty, compute from raw energy_data
if not energy_summary:
from sqlalchemy import distinct
fallback_q = await db.execute(
select(
func.sum(EnergyData.value),
).where(
and_(
EnergyData.timestamp >= today_start,
EnergyData.data_type == "daily_energy",
)
).group_by(EnergyData.device_id).order_by(EnergyData.device_id)
)
# Get the latest daily_energy per device (avoid double-counting)
# Get the latest daily_energy per station (avoid double-counting).
# The collector writes station-level daily_energy to individual device rows,
# so multiple devices from the same station share the same value.
# Group by station prefix (first 3 chars of device name, e.g. "AP1", "AP2")
# and take MAX per station to deduplicate.
latest_energy_q = await db.execute(
select(
EnergyData.device_id,
func.substring(Device.name, text("1"), text("3")).label("station"),
func.max(EnergyData.value).label("max_energy"),
).select_from(EnergyData).join(
Device, EnergyData.device_id == Device.id
).where(
and_(
EnergyData.timestamp >= today_start,
EnergyData.data_type == "daily_energy",
Device.device_type.in_(["pv_inverter", "sungrow_inverter"]),
)
).group_by(EnergyData.device_id)
).group_by(text("station"))
)
total_gen = sum(row[1] or 0 for row in latest_energy_q.all())
if total_gen > 0:
@@ -111,7 +107,7 @@ async def get_overview(db: AsyncSession = Depends(get_db), user: User = Depends(
async def get_realtime_data(db: AsyncSession = Depends(get_db), user: User = Depends(get_current_user)):
"""实时功率数据 - 获取最近的采集数据"""
now = datetime.now(timezone.utc)
five_min_ago = now - timedelta(minutes=5)
five_min_ago = now - timedelta(minutes=20)
latest_q = await db.execute(
select(EnergyData).where(