Skip to content

Commit 240fb49

Browse files
committed
feat: ocpp 2.1 (wip)
1 parent 6ecb834 commit 240fb49

File tree

105 files changed

+10221
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+10221
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// The authorization functional block contains OCPP 2.1 authorization-related features. It contains different ways of authorizing a user, online and/or offline .
2+
package authorization
3+
4+
import "github.com/lorenzodonini/ocpp-go/ocpp"
5+
6+
// Needs to be implemented by a CSMS for handling messages part of the OCPP 2.1 Authorization profile.
7+
type CSMSHandler interface {
8+
// OnAuthorize is called on the CSMS whenever an AuthorizeRequest is received from a charging station.
9+
OnAuthorize(chargingStationID string, request *AuthorizeRequest) (confirmation *AuthorizeResponse, err error)
10+
}
11+
12+
// Needs to be implemented by Charging stations for handling messages part of the OCPP 2.1 Authorization profile.
13+
type ChargingStationHandler interface {
14+
// OnClearCache is called on a charging station whenever a ClearCacheRequest is received from the CSMS.
15+
OnClearCache(request *ClearCacheRequest) (confirmation *ClearCacheResponse, err error)
16+
}
17+
18+
const ProfileName = "authorization"
19+
20+
var Profile = ocpp.NewProfile(
21+
ProfileName,
22+
AuthorizeFeature{},
23+
ClearCacheFeature{},
24+
)

ocpp2.1/authorization/authorize.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package authorization
2+
3+
import (
4+
"reflect"
5+
6+
"gopkg.in/go-playground/validator.v9"
7+
8+
"github.com/lorenzodonini/ocpp-go/ocpp2.1/types"
9+
)
10+
11+
// -------------------- Authorize (CS -> CSMS) --------------------
12+
13+
const AuthorizeFeatureName = "Authorize"
14+
15+
// The Certificate status information.
16+
type AuthorizeCertificateStatus string
17+
18+
const (
19+
CertificateStatusAccepted AuthorizeCertificateStatus = "Accepted"
20+
CertificateStatusSignatureError AuthorizeCertificateStatus = "SignatureError"
21+
CertificateStatusCertificateExpired AuthorizeCertificateStatus = "CertificateExpired"
22+
CertificateStatusCertificateRevoked AuthorizeCertificateStatus = "CertificateRevoked"
23+
CertificateStatusNoCertificateAvailable AuthorizeCertificateStatus = "NoCertificateAvailable"
24+
CertificateStatusCertChainError AuthorizeCertificateStatus = "CertChainError"
25+
CertificateStatusContractCancelled AuthorizeCertificateStatus = "ContractCancelled"
26+
)
27+
28+
func isValidAuthorizeCertificateStatus(fl validator.FieldLevel) bool {
29+
status := AuthorizeCertificateStatus(fl.Field().String())
30+
switch status {
31+
case CertificateStatusAccepted, CertificateStatusCertChainError, CertificateStatusCertificateExpired, CertificateStatusSignatureError, CertificateStatusNoCertificateAvailable, CertificateStatusCertificateRevoked, CertificateStatusContractCancelled:
32+
return true
33+
default:
34+
return false
35+
}
36+
}
37+
38+
// The field definition of the Authorize request payload sent by the Charging Station to the CSMS.
39+
type AuthorizeRequest struct {
40+
Certificate string `json:"certificate,omitempty" validate:"max=5500"`
41+
IdToken types.IdToken `json:"idToken" validate:"required"`
42+
CertificateHashData []types.OCSPRequestDataType `json:"iso15118CertificateHashData,omitempty" validate:"max=4,dive"`
43+
}
44+
45+
// This field definition of the Authorize response payload, sent by the Charging Station to the CSMS in response to an AuthorizeRequest.
46+
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
47+
type AuthorizeResponse struct {
48+
CertificateStatus AuthorizeCertificateStatus `json:"certificateStatus,omitempty" validate:"omitempty,authorizeCertificateStatus21"`
49+
IdTokenInfo types.IdTokenInfo `json:"idTokenInfo" validate:"required"`
50+
}
51+
52+
// Before the owner of an electric vehicle can start or stop charging, the Charging Station has to authorize the operation.
53+
// Upon receipt of an AuthorizeRequest, the CSMS SHALL respond with an AuthorizeResponse.
54+
// This response payload SHALL indicate whether or not the idTag is accepted by the CSMS.
55+
// If the CSMS accepts the idToken then the response payload MUST include an authorization status value indicating acceptance or a reason for rejection.
56+
//
57+
// A Charging Station MAY authorize identifier locally without involving the CSMS, as described in Local Authorization List.
58+
//
59+
// The Charging Station SHALL only supply energy after authorization.
60+
type AuthorizeFeature struct{}
61+
62+
func (f AuthorizeFeature) GetFeatureName() string {
63+
return AuthorizeFeatureName
64+
}
65+
66+
func (f AuthorizeFeature) GetRequestType() reflect.Type {
67+
return reflect.TypeOf(AuthorizeRequest{})
68+
}
69+
70+
func (f AuthorizeFeature) GetResponseType() reflect.Type {
71+
return reflect.TypeOf(AuthorizeResponse{})
72+
}
73+
74+
func (r AuthorizeRequest) GetFeatureName() string {
75+
return AuthorizeFeatureName
76+
}
77+
78+
func (c AuthorizeResponse) GetFeatureName() string {
79+
return AuthorizeFeatureName
80+
}
81+
82+
// Creates a new AuthorizeRequest, containing all required fields. There are no optional fields for this message.
83+
func NewAuthorizationRequest(idToken string, tokenType types.IdTokenType) *AuthorizeRequest {
84+
return &AuthorizeRequest{IdToken: types.IdToken{IdToken: idToken, Type: tokenType}}
85+
}
86+
87+
// Creates a new AuthorizeResponse. There are no optional fields for this message.
88+
func NewAuthorizationResponse(idTokenInfo types.IdTokenInfo) *AuthorizeResponse {
89+
return &AuthorizeResponse{IdTokenInfo: idTokenInfo}
90+
}
91+
92+
func init() {
93+
_ = types.Validate.RegisterValidation("authorizeCertificateStatus21", isValidAuthorizeCertificateStatus)
94+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package authorization
2+
3+
import (
4+
"reflect"
5+
6+
"gopkg.in/go-playground/validator.v9"
7+
8+
"github.com/lorenzodonini/ocpp-go/ocpp2.1/types"
9+
)
10+
11+
// -------------------- Clear Cache (CSMS -> CS) --------------------
12+
13+
const ClearCacheFeatureName = "ClearCache"
14+
15+
// Status returned in response to ClearCacheRequest.
16+
type ClearCacheStatus string
17+
18+
const (
19+
ClearCacheStatusAccepted ClearCacheStatus = "Accepted"
20+
ClearCacheStatusRejected ClearCacheStatus = "Rejected"
21+
)
22+
23+
func isValidClearCacheStatus(fl validator.FieldLevel) bool {
24+
status := ClearCacheStatus(fl.Field().String())
25+
switch status {
26+
case ClearCacheStatusAccepted, ClearCacheStatusRejected:
27+
return true
28+
default:
29+
return false
30+
}
31+
}
32+
33+
// The field definition of the ClearCache request payload sent by the CSMS to the Charging Station.
34+
type ClearCacheRequest struct {
35+
}
36+
37+
// This field definition of the ClearCache response payload, sent by the Charging Station to the CSMS in response to a ClearCacheRequest.
38+
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
39+
type ClearCacheResponse struct {
40+
Status ClearCacheStatus `json:"status" validate:"required,cacheStatus21"`
41+
StatusInfo *types.StatusInfo `json:"statusInfo,omitempty" validate:"omitempty"`
42+
}
43+
44+
// CSMS can request a Charging Station to clear its Authorization Cache.
45+
// The CSMS SHALL send a ClearCacheRequest payload for clearing the Charging Station’s Authorization Cache.
46+
// Upon receipt of a ClearCacheRequest, the Charging Station SHALL respond with a ClearCacheResponse payload.
47+
// The response payload SHALL indicate whether the Charging Station was able to clear its Authorization Cache.
48+
type ClearCacheFeature struct{}
49+
50+
func (f ClearCacheFeature) GetFeatureName() string {
51+
return ClearCacheFeatureName
52+
}
53+
54+
func (f ClearCacheFeature) GetRequestType() reflect.Type {
55+
return reflect.TypeOf(ClearCacheRequest{})
56+
}
57+
58+
func (f ClearCacheFeature) GetResponseType() reflect.Type {
59+
return reflect.TypeOf(ClearCacheResponse{})
60+
}
61+
62+
func (r ClearCacheRequest) GetFeatureName() string {
63+
return ClearCacheFeatureName
64+
}
65+
66+
func (c ClearCacheResponse) GetFeatureName() string {
67+
return ClearCacheFeatureName
68+
}
69+
70+
// Creates a new ClearCacheRequest, which doesn't contain any required or optional fields.
71+
func NewClearCacheRequest() *ClearCacheRequest {
72+
return &ClearCacheRequest{}
73+
}
74+
75+
// Creates a new ClearCacheResponse, containing all required fields. There are no optional fields for this message.
76+
func NewClearCacheResponse(status ClearCacheStatus) *ClearCacheResponse {
77+
return &ClearCacheResponse{Status: status}
78+
}
79+
80+
func init() {
81+
_ = types.Validate.RegisterValidation("cacheStatus21", isValidClearCacheStatus)
82+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// The availability functional block contains OCPP 2.0 features for notifying the CSMS of availability and status changes.
2+
// A CSMS can also instruct a charging station to change its availability.
3+
package availability
4+
5+
import "github.com/lorenzodonini/ocpp-go/ocpp"
6+
7+
// Needs to be implemented by a CSMS for handling messages part of the OCPP 2.0 Availability profile.
8+
type CSMSHandler interface {
9+
// OnHeartbeat is called on the CSMS whenever a HeartbeatResponse is received from a charging station.
10+
OnHeartbeat(chargingStationID string, request *HeartbeatRequest) (response *HeartbeatResponse, err error)
11+
// OnStatusNotification is called on the CSMS whenever a StatusNotificationRequest is received from a charging station.
12+
OnStatusNotification(chargingStationID string, request *StatusNotificationRequest) (response *StatusNotificationResponse, err error)
13+
}
14+
15+
// Needs to be implemented by Charging stations for handling messages part of the OCPP 2.0 Availability profile.
16+
type ChargingStationHandler interface {
17+
// OnChangeAvailability is called on a charging station whenever a ChangeAvailabilityRequest is received from the CSMS.
18+
OnChangeAvailability(request *ChangeAvailabilityRequest) (response *ChangeAvailabilityResponse, err error)
19+
}
20+
21+
const ProfileName = "availability"
22+
23+
var Profile = ocpp.NewProfile(
24+
ProfileName,
25+
ChangeAvailabilityFeature{},
26+
HeartbeatFeature{},
27+
StatusNotificationFeature{},
28+
)
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package availability
2+
3+
import (
4+
"reflect"
5+
6+
"gopkg.in/go-playground/validator.v9"
7+
8+
"github.com/lorenzodonini/ocpp-go/ocpp2.1/types"
9+
)
10+
11+
// -------------------- Change Availability (CSMS -> CS) --------------------
12+
13+
const ChangeAvailabilityFeatureName = "ChangeAvailability"
14+
15+
// Requested availability change in ChangeAvailabilityRequest.
16+
type OperationalStatus string
17+
18+
const (
19+
OperationalStatusInoperative OperationalStatus = "Inoperative"
20+
OperationalStatusOperative OperationalStatus = "Operative"
21+
)
22+
23+
func isValidOperationalStatus(fl validator.FieldLevel) bool {
24+
status := OperationalStatus(fl.Field().String())
25+
switch status {
26+
case OperationalStatusInoperative, OperationalStatusOperative:
27+
return true
28+
default:
29+
return false
30+
}
31+
}
32+
33+
// Status returned in response to ChangeAvailabilityRequest
34+
type ChangeAvailabilityStatus string
35+
36+
const (
37+
ChangeAvailabilityStatusAccepted ChangeAvailabilityStatus = "Accepted"
38+
ChangeAvailabilityStatusRejected ChangeAvailabilityStatus = "Rejected"
39+
ChangeAvailabilityStatusScheduled ChangeAvailabilityStatus = "Scheduled"
40+
)
41+
42+
func isValidChangeAvailabilityStatus(fl validator.FieldLevel) bool {
43+
status := ChangeAvailabilityStatus(fl.Field().String())
44+
switch status {
45+
case ChangeAvailabilityStatusAccepted, ChangeAvailabilityStatusRejected, ChangeAvailabilityStatusScheduled:
46+
return true
47+
default:
48+
return false
49+
}
50+
}
51+
52+
// The field definition of the ChangeAvailability request payload sent by the CSMS to the Charging Station.
53+
type ChangeAvailabilityRequest struct {
54+
OperationalStatus OperationalStatus `json:"operationalStatus" validate:"required,operationalStatus"`
55+
Evse *types.EVSE `json:"evse,omitempty" validate:"omitempty"`
56+
}
57+
58+
// This field definition of the ChangeAvailability response payload, sent by the Charging Station to the CSMS in response to a ChangeAvailabilityRequest.
59+
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
60+
type ChangeAvailabilityResponse struct {
61+
Status ChangeAvailabilityStatus `json:"status" validate:"required,changeAvailabilityStatus"`
62+
StatusInfo *types.StatusInfo `json:"statusInfo,omitempty" validate:"omitempty"`
63+
}
64+
65+
// CSMS can request a Charging Station to change its availability.
66+
// A Charging Station is considered available (“operative”) when it is charging or ready for charging.
67+
// A Charging Station is considered unavailable when it does not allow any charging.
68+
// The CSMS SHALL send a ChangeAvailabilityRequest for requesting a Charging Station to change its availability.
69+
// The CSMS can change the availability to available or unavailable.
70+
type ChangeAvailabilityFeature struct{}
71+
72+
func (f ChangeAvailabilityFeature) GetFeatureName() string {
73+
return ChangeAvailabilityFeatureName
74+
}
75+
76+
func (f ChangeAvailabilityFeature) GetRequestType() reflect.Type {
77+
return reflect.TypeOf(ChangeAvailabilityRequest{})
78+
}
79+
80+
func (f ChangeAvailabilityFeature) GetResponseType() reflect.Type {
81+
return reflect.TypeOf(ChangeAvailabilityResponse{})
82+
}
83+
84+
func (r ChangeAvailabilityRequest) GetFeatureName() string {
85+
return ChangeAvailabilityFeatureName
86+
}
87+
88+
func (c ChangeAvailabilityResponse) GetFeatureName() string {
89+
return ChangeAvailabilityFeatureName
90+
}
91+
92+
// Creates a new ChangeAvailabilityRequest, containing all required fields. Optional fields may be set afterwards.
93+
func NewChangeAvailabilityRequest(operationalStatus OperationalStatus) *ChangeAvailabilityRequest {
94+
return &ChangeAvailabilityRequest{OperationalStatus: operationalStatus}
95+
}
96+
97+
// Creates a new ChangeAvailabilityResponse, containing all required fields. Optional fields may be set afterwards.
98+
func NewChangeAvailabilityResponse(status ChangeAvailabilityStatus) *ChangeAvailabilityResponse {
99+
return &ChangeAvailabilityResponse{Status: status}
100+
}
101+
102+
func init() {
103+
_ = types.Validate.RegisterValidation("operationalStatus", isValidOperationalStatus)
104+
_ = types.Validate.RegisterValidation("changeAvailabilityStatus", isValidChangeAvailabilityStatus)
105+
}

0 commit comments

Comments
 (0)