feat: 推广 V3.5 实时氢耗并完善导出
This commit is contained in:
@@ -30,31 +30,32 @@ type Execer interface {
|
||||
}
|
||||
|
||||
type Writer struct {
|
||||
exec Execer
|
||||
query Queryer
|
||||
loc *time.Location
|
||||
sourceTouchInterval time.Duration
|
||||
projectionInterval time.Duration
|
||||
cacheRetention time.Duration
|
||||
cacheCleanupInterval time.Duration
|
||||
baselineMissTTL time.Duration
|
||||
baselineHitTTL time.Duration
|
||||
maxCacheEntries int
|
||||
lastCacheCleanup time.Time
|
||||
lastCacheCleanupStats cacheCleanupStats
|
||||
cacheEvictions cacheCleanupStats
|
||||
mu sync.Mutex
|
||||
lastTotalMileage map[string]float64
|
||||
lastSourceSeen map[string]time.Time
|
||||
lastProjection map[string]projectionCacheEntry
|
||||
pendingProjection map[string]pendingProjectionEntry
|
||||
baselineCache map[string]sourceBaselineCacheEntry
|
||||
mileageKeysByPrefix map[string]map[string]struct{}
|
||||
projectionKeysByPrefix map[string]map[string]struct{}
|
||||
baselineKeysByPrefix map[string]map[string]struct{}
|
||||
lastGPSAccumulation map[string]time.Time
|
||||
hydrogenTankCapacities map[string]float64
|
||||
gpsAccumulationInterval time.Duration
|
||||
exec Execer
|
||||
query Queryer
|
||||
loc *time.Location
|
||||
sourceTouchInterval time.Duration
|
||||
projectionInterval time.Duration
|
||||
cacheRetention time.Duration
|
||||
cacheCleanupInterval time.Duration
|
||||
baselineMissTTL time.Duration
|
||||
baselineHitTTL time.Duration
|
||||
maxCacheEntries int
|
||||
lastCacheCleanup time.Time
|
||||
lastCacheCleanupStats cacheCleanupStats
|
||||
cacheEvictions cacheCleanupStats
|
||||
mu sync.Mutex
|
||||
lastTotalMileage map[string]float64
|
||||
lastSourceSeen map[string]time.Time
|
||||
lastProjection map[string]projectionCacheEntry
|
||||
pendingProjection map[string]pendingProjectionEntry
|
||||
baselineCache map[string]sourceBaselineCacheEntry
|
||||
mileageKeysByPrefix map[string]map[string]struct{}
|
||||
projectionKeysByPrefix map[string]map[string]struct{}
|
||||
baselineKeysByPrefix map[string]map[string]struct{}
|
||||
lastGPSAccumulation map[string]time.Time
|
||||
hydrogenTankCapacities map[string]float64
|
||||
hydrogenEnergyParameters map[string]HydrogenRealtimeParameters
|
||||
gpsAccumulationInterval time.Duration
|
||||
}
|
||||
|
||||
type MetricSample struct {
|
||||
@@ -151,26 +152,27 @@ func NewWriter(exec Execer, loc *time.Location) *Writer {
|
||||
loc = time.FixedZone("Asia/Shanghai", 8*3600)
|
||||
}
|
||||
writer := &Writer{
|
||||
exec: exec,
|
||||
loc: loc,
|
||||
sourceTouchInterval: time.Minute,
|
||||
projectionInterval: 15 * time.Second,
|
||||
cacheRetention: defaultCacheRetention,
|
||||
cacheCleanupInterval: defaultCacheCleanupInterval,
|
||||
baselineMissTTL: defaultBaselineMissTTL,
|
||||
baselineHitTTL: defaultBaselineHitTTL,
|
||||
maxCacheEntries: defaultMaxCacheEntries,
|
||||
lastTotalMileage: map[string]float64{},
|
||||
lastSourceSeen: map[string]time.Time{},
|
||||
lastProjection: map[string]projectionCacheEntry{},
|
||||
pendingProjection: map[string]pendingProjectionEntry{},
|
||||
baselineCache: map[string]sourceBaselineCacheEntry{},
|
||||
mileageKeysByPrefix: map[string]map[string]struct{}{},
|
||||
projectionKeysByPrefix: map[string]map[string]struct{}{},
|
||||
baselineKeysByPrefix: map[string]map[string]struct{}{},
|
||||
lastGPSAccumulation: map[string]time.Time{},
|
||||
hydrogenTankCapacities: map[string]float64{},
|
||||
gpsAccumulationInterval: defaultGPSAccumulationInterval,
|
||||
exec: exec,
|
||||
loc: loc,
|
||||
sourceTouchInterval: time.Minute,
|
||||
projectionInterval: 15 * time.Second,
|
||||
cacheRetention: defaultCacheRetention,
|
||||
cacheCleanupInterval: defaultCacheCleanupInterval,
|
||||
baselineMissTTL: defaultBaselineMissTTL,
|
||||
baselineHitTTL: defaultBaselineHitTTL,
|
||||
maxCacheEntries: defaultMaxCacheEntries,
|
||||
lastTotalMileage: map[string]float64{},
|
||||
lastSourceSeen: map[string]time.Time{},
|
||||
lastProjection: map[string]projectionCacheEntry{},
|
||||
pendingProjection: map[string]pendingProjectionEntry{},
|
||||
baselineCache: map[string]sourceBaselineCacheEntry{},
|
||||
mileageKeysByPrefix: map[string]map[string]struct{}{},
|
||||
projectionKeysByPrefix: map[string]map[string]struct{}{},
|
||||
baselineKeysByPrefix: map[string]map[string]struct{}{},
|
||||
lastGPSAccumulation: map[string]time.Time{},
|
||||
hydrogenTankCapacities: map[string]float64{},
|
||||
hydrogenEnergyParameters: map[string]HydrogenRealtimeParameters{},
|
||||
gpsAccumulationInterval: defaultGPSAccumulationInterval,
|
||||
}
|
||||
if query, ok := exec.(Queryer); ok {
|
||||
writer.query = query
|
||||
@@ -197,6 +199,25 @@ func (w *Writer) HydrogenTankCapacityLiters(vin string) (float64, bool) {
|
||||
return capacity, ok
|
||||
}
|
||||
|
||||
func (w *Writer) ReloadHydrogenRealtimeParameters(ctx context.Context) (int, error) {
|
||||
date := time.Now().In(w.loc).Format("2006-01-02")
|
||||
parameters, err := LoadHydrogenRealtimeParameters(ctx, w.query, date)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
w.mu.Lock()
|
||||
w.hydrogenEnergyParameters = parameters
|
||||
w.mu.Unlock()
|
||||
return len(parameters), nil
|
||||
}
|
||||
|
||||
func (w *Writer) HydrogenRealtimeParameters(vin string) HydrogenRealtimeParameters {
|
||||
vin = strings.ToUpper(strings.TrimSpace(vin))
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
return normalizeHydrogenRealtimeParameters(w.hydrogenEnergyParameters[vin])
|
||||
}
|
||||
|
||||
func (w *Writer) SetSourceTouchInterval(interval time.Duration) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
@@ -315,6 +336,11 @@ func (w *Writer) EnsureSchema(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, statement := range HydrogenRealtimeAlterSQL {
|
||||
if _, err := w.exec.ExecContext(ctx, statement); err != nil && !isIgnorableSchemaChangeError(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -333,7 +359,8 @@ func (w *Writer) AppendWithResult(ctx context.Context, env envelope.FrameEnvelop
|
||||
w.maybeCleanupCaches(seenAt)
|
||||
identity, hasSource := NewSourceIdentityFromEnvelope(env)
|
||||
capacityLiters, _ := w.HydrogenTankCapacityLiters(env.VIN)
|
||||
hydrogen, err := AppendHydrogenStream(ctx, w.exec, env, w.loc, time.Now(), capacityLiters)
|
||||
hydrogenParams := w.HydrogenRealtimeParameters(env.VIN)
|
||||
hydrogen, err := AppendHydrogenV35Realtime(ctx, w.exec, env, w.loc, time.Now(), capacityLiters, hydrogenParams)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user