feat: 精确耗电计算(接入充值记录接口)
- 新增 queryISIMSRoomBuyRecord 充值记录获取 + 10分钟缓存 - 日耗电 = 剩余变化 + 当天充值电量(电价0.535元/度) - 月度汇总增加充值次数/电量/金额 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -20,10 +20,12 @@ type record struct {
|
||||
}
|
||||
|
||||
type dailyStat struct {
|
||||
Date string `json:"date"`
|
||||
Surplus float64 `json:"surplus"`
|
||||
Amount float64 `json:"amount"`
|
||||
Usage *float64 `json:"usage"` // nil 表示无前一天基线
|
||||
Date string `json:"date"`
|
||||
Surplus float64 `json:"surplus"`
|
||||
Amount float64 `json:"amount"`
|
||||
Usage *float64 `json:"usage"` // nil 表示无前一天基线
|
||||
Recharge *float64 `json:"recharge"` // 当天充值电量(度), nil=无充值
|
||||
Money *float64 `json:"money"` // 当天充值金额(元), nil=无充值
|
||||
}
|
||||
|
||||
// monthSummary 月度汇总
|
||||
@@ -34,7 +36,9 @@ type monthSummary struct {
|
||||
EndSurplus *float64 `json:"end_surplus"` // 月末末次电量
|
||||
TotalUsage *float64 `json:"total_usage"` // 月总耗电
|
||||
AvgUsage *float64 `json:"avg_usage"` // 日均耗电
|
||||
RechargeDays int `json:"recharge_days"` // 疑似充值天数(电量回升)
|
||||
RechargeDays int `json:"recharge_days"` // 充值天数
|
||||
RechargeKwh *float64 `json:"recharge_kwh"` // 月充值电量(度)
|
||||
RechargeMoney *float64 `json:"recharge_money"` // 月充值金额(元)
|
||||
MaxUsage *float64 `json:"max_usage"` // 单日最大耗电
|
||||
}
|
||||
|
||||
@@ -113,9 +117,10 @@ func getRecords() []record {
|
||||
return records
|
||||
}
|
||||
|
||||
// buildDailyStats 按日期升序生成每日统计(含日耗电 = 前一天剩余 - 当天剩余)
|
||||
// buildDailyStats 按日期升序生成每日统计(含日耗电 = 前一天剩余 - 当天剩余 + 当天充值电量)
|
||||
// 注意: 耗电计算跨月时使用上月末记录作为基线(若存在)
|
||||
func buildDailyStats(records []record, month string) []dailyStat {
|
||||
// rechargeMap: date -> 当天充值电量(度);精确修正充值当天的耗电
|
||||
func buildDailyStats(records []record, month string, rechargeMap map[string]float64) []dailyStat {
|
||||
all := loadHistory()
|
||||
// 若指定月份,额外包含上一月最后一条记录作为基线(不计入本月输出)
|
||||
var prevMonthLast *record
|
||||
@@ -151,13 +156,23 @@ func buildDailyStats(records []record, month string) []dailyStat {
|
||||
for _, r := range target {
|
||||
var usage *float64
|
||||
if prevSurplus != nil {
|
||||
u := round2(*prevSurplus - r.Surplus)
|
||||
// 精确耗电 = 剩余变化 + 当天充值电量
|
||||
u := round2(*prevSurplus - r.Surplus + rechargeMap[r.Date])
|
||||
if u < 0 {
|
||||
u = 0 // 充值/异常归零
|
||||
u = 0 // 极端异常(数据缺口)归零
|
||||
}
|
||||
usage = &u
|
||||
}
|
||||
daily = append(daily, dailyStat{Date: r.Date, Surplus: r.Surplus, Amount: r.Amount, Usage: usage})
|
||||
var recharge, money *float64
|
||||
if kwh, ok := rechargeMap[r.Date]; ok && kwh > 0 {
|
||||
recharge = &kwh
|
||||
m := round2(kwh * unitPrice())
|
||||
money = &m
|
||||
}
|
||||
daily = append(daily, dailyStat{
|
||||
Date: r.Date, Surplus: r.Surplus, Amount: r.Amount,
|
||||
Usage: usage, Recharge: recharge, Money: money,
|
||||
})
|
||||
s := r.Surplus
|
||||
prevSurplus = &s
|
||||
}
|
||||
@@ -203,6 +218,8 @@ func buildMonthSummary(daily []dailyStat, month string) *monthSummary {
|
||||
|
||||
var total float64
|
||||
var max float64
|
||||
var totalRechargeKwh float64
|
||||
var totalRechargeMoney float64
|
||||
rechargeDays := 0
|
||||
countWithUsage := 0
|
||||
for _, d := range daily {
|
||||
@@ -213,14 +230,16 @@ func buildMonthSummary(daily []dailyStat, month string) *monthSummary {
|
||||
}
|
||||
countWithUsage++
|
||||
}
|
||||
// 疑似充值:当天剩余比前一天高
|
||||
}
|
||||
// 充值与最大耗电基于原始升序记录重新精确计算
|
||||
if len(daily) >= 2 {
|
||||
rechargeDays = countRecharges(daily)
|
||||
if d.Recharge != nil {
|
||||
totalRechargeKwh += *d.Recharge
|
||||
rechargeDays++
|
||||
}
|
||||
if d.Money != nil {
|
||||
totalRechargeMoney += *d.Money
|
||||
}
|
||||
}
|
||||
|
||||
var totalP, avgP, maxP, startP, endP *float64
|
||||
var totalP, avgP, maxP, startP, endP, rkwhP, rmoneyP *float64
|
||||
startP, endP = &start, &end
|
||||
totalP = &total
|
||||
if countWithUsage > 0 {
|
||||
@@ -228,26 +247,25 @@ func buildMonthSummary(daily []dailyStat, month string) *monthSummary {
|
||||
avgP = &avg
|
||||
}
|
||||
maxP = &max
|
||||
if totalRechargeKwh > 0 {
|
||||
rkwhP = &totalRechargeKwh
|
||||
}
|
||||
if totalRechargeMoney > 0 {
|
||||
rmoneyP = &totalRechargeMoney
|
||||
}
|
||||
|
||||
return &monthSummary{
|
||||
Month: m,
|
||||
RecordCount: len(daily),
|
||||
StartSurplus: startP,
|
||||
EndSurplus: endP,
|
||||
TotalUsage: totalP,
|
||||
AvgUsage: avgP,
|
||||
RechargeDays: rechargeDays,
|
||||
MaxUsage: maxP,
|
||||
Month: m,
|
||||
RecordCount: len(daily),
|
||||
StartSurplus: startP,
|
||||
EndSurplus: endP,
|
||||
TotalUsage: totalP,
|
||||
AvgUsage: avgP,
|
||||
RechargeDays: rechargeDays,
|
||||
RechargeKwh: rkwhP,
|
||||
RechargeMoney: rmoneyP,
|
||||
MaxUsage: maxP,
|
||||
}
|
||||
}
|
||||
|
||||
// countRecharges 统计疑似充值天数(当天剩余较前一天回升)
|
||||
func countRecharges(daily []dailyStat) int {
|
||||
n := 0
|
||||
for i := 1; i < len(daily); i++ {
|
||||
if daily[i].Surplus > daily[i-1].Surplus {
|
||||
n++
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user