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:
@@ -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()]
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ router = APIRouter(prefix="/settings", tags=["系统设置"])
|
||||
|
||||
# Default settings — used when keys are missing from DB
|
||||
DEFAULTS: dict[str, str] = {
|
||||
"platform_name": "天普零碳园区智慧能源管理平台",
|
||||
"platform_name": "Smart Energy Management Platform",
|
||||
"data_retention_days": "365",
|
||||
"alarm_auto_resolve_minutes": "30",
|
||||
"simulator_interval_seconds": "15",
|
||||
|
||||
Reference in New Issue
Block a user