-
Notifications
You must be signed in to change notification settings - Fork 23
/
triggers.go
113 lines (107 loc) · 4.16 KB
/
triggers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// SPDX-License-Identifier: Apache-2.0
package sync
import (
"context"
"fmt"
"github.com/thoughtworks/maeve-csms/manager/handlers"
"github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp16"
"github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201"
"github.com/thoughtworks/maeve-csms/manager/store"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"golang.org/x/exp/slog"
"k8s.io/utils/clock"
"time"
)
func SyncTriggers(ctx context.Context,
tracer trace.Tracer,
engine store.Engine,
clock clock.PassiveClock,
v16CallMaker,
dataTransferCallMaker,
v201CallMaker handlers.CallMaker,
runEvery,
retryAfter time.Duration) {
var previousChargeStationId string
for {
select {
case <-ctx.Done():
slog.Info("shutting down sync triggers")
return
case <-time.After(runEvery):
func() {
ctx, span := tracer.Start(ctx, "sync triggers", trace.WithSpanKind(trace.SpanKindInternal),
trace.WithAttributes(attribute.String("sync.trigger.previous", previousChargeStationId)))
defer span.End()
triggerMessages, err := engine.ListChargeStationTriggerMessages(ctx, 50, previousChargeStationId)
if err != nil {
span.RecordError(err)
return
}
if len(triggerMessages) > 0 {
previousChargeStationId = triggerMessages[len(triggerMessages)-1].ChargeStationId
} else {
previousChargeStationId = ""
}
span.SetAttributes(attribute.Int("sync.trigger.count", len(triggerMessages)))
for _, pendingTriggerMessage := range triggerMessages {
func() {
ctx, span := tracer.Start(ctx, "sync trigger", trace.WithSpanKind(trace.SpanKindInternal),
trace.WithAttributes(
attribute.String("chargeStationId", pendingTriggerMessage.ChargeStationId),
attribute.String("sync.trigger.status", string(pendingTriggerMessage.TriggerStatus)),
attribute.String("sync.trigger.message", string(pendingTriggerMessage.TriggerMessage)),
attribute.String("sync.trigger.after", pendingTriggerMessage.SendAfter.Format(time.RFC3339)),
))
defer span.End()
details, err := engine.LookupChargeStationRuntimeDetails(ctx, pendingTriggerMessage.ChargeStationId)
if err != nil {
span.RecordError(err)
return
}
if details == nil {
span.RecordError(fmt.Errorf("no runtime details for charge station"))
return
}
csId := pendingTriggerMessage.ChargeStationId
if clock.Now().After(pendingTriggerMessage.SendAfter) {
span.SetAttributes(attribute.String("sync.trigger.ocpp_version", details.OcppVersion))
err = engine.SetChargeStationTriggerMessage(ctx, csId, &store.ChargeStationTriggerMessage{
TriggerMessage: pendingTriggerMessage.TriggerMessage,
TriggerStatus: store.TriggerStatusPending,
SendAfter: clock.Now().Add(retryAfter),
})
if err != nil {
span.RecordError(err)
return
}
if details.OcppVersion == "1.6" {
if pendingTriggerMessage.TriggerMessage == store.TriggerMessageBootNotification ||
pendingTriggerMessage.TriggerMessage == store.TriggerMessageDiagnosticStatusNotification ||
pendingTriggerMessage.TriggerMessage == store.TriggerMessageFirmwareStatusNotification ||
pendingTriggerMessage.TriggerMessage == store.TriggerMessageHeartbeat ||
pendingTriggerMessage.TriggerMessage == store.TriggerMessageMeterValues ||
pendingTriggerMessage.TriggerMessage == store.TriggerMessageStatusNotification {
err = v16CallMaker.Send(ctx, csId, &ocpp16.TriggerMessageJson{
RequestedMessage: ocpp16.TriggerMessageJsonRequestedMessage(pendingTriggerMessage.TriggerMessage),
})
} else {
err = dataTransferCallMaker.Send(ctx, csId, &ocpp201.TriggerMessageRequestJson{
RequestedMessage: ocpp201.MessageTriggerEnumType(pendingTriggerMessage.TriggerMessage),
})
}
} else {
err = v201CallMaker.Send(ctx, csId, &ocpp201.TriggerMessageRequestJson{
RequestedMessage: ocpp201.MessageTriggerEnumType(pendingTriggerMessage.TriggerMessage),
})
}
if err != nil {
span.RecordError(err)
}
}
}()
}
}()
}
}
}