feat!: generic defaults, dashboard fallback, PV filter fix (v1.3.0)

- Replace all hardcoded Tianpu/天普 defaults with generic "EMS Platform"
- Add energy_today fallback: query raw energy_data when daily summary empty
- Fix PV device filter to include sungrow_inverter device type
- Update APP_NAME, CUSTOMER default, SECRET_KEY, SMTP, Celery, email templates

BREAKING: CUSTOMER default changed from "tianpu" to "default"
Existing deployments with CUSTOMER=tianpu in .env are unaffected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Du Wenbo
2026-04-06 22:02:38 +08:00
parent 1636dea8f1
commit 60e7f08d7e
15 changed files with 61 additions and 29 deletions

View File

@@ -26,7 +26,7 @@ async def get_overview(db: AsyncSession = Depends(get_db), user: User = Depends(
)
device_stats = {row[0]: row[1] for row in device_stats_q.all()}
# 今日能耗汇总
# 今日能耗汇总 (from daily summary table)
daily_q = await db.execute(
select(
EnergyDailySummary.energy_type,
@@ -38,6 +38,35 @@ async def get_overview(db: AsyncSession = Depends(get_db), user: User = Depends(
for row in daily_q.all():
energy_summary[row[0]] = {"consumption": row[1] or 0, "generation": row[2] or 0}
# 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)
latest_energy_q = await db.execute(
select(
EnergyData.device_id,
func.max(EnergyData.value).label("max_energy"),
).where(
and_(
EnergyData.timestamp >= today_start,
EnergyData.data_type == "daily_energy",
)
).group_by(EnergyData.device_id)
)
total_gen = sum(row[1] or 0 for row in latest_energy_q.all())
if total_gen > 0:
energy_summary["electricity"] = {"consumption": 0, "generation": round(total_gen, 2)}
# 今日碳排放
carbon_q = await db.execute(
select(func.sum(CarbonEmission.emission), func.sum(CarbonEmission.reduction))
@@ -134,7 +163,10 @@ async def get_load_curve(
async def _get_pv_device_ids(db: AsyncSession):
result = await db.execute(
select(Device.id).where(Device.device_type == "pv_inverter", Device.is_active == True)
select(Device.id).where(
Device.device_type.in_(["pv_inverter", "sungrow_inverter"]),
Device.is_active == True,
)
)
return [r[0] for r in result.fetchall()]