Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync gridx_extensions #19

Merged
merged 50 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
983d863
Add IsConnected utility method for charge points
lorenzodonini Nov 16, 2022
564c732
fix: use go-routines in handle functions to prevent blocking the unde…
tretmar Nov 16, 2022
956223d
Make SampledValue.Value field not required
lorenzodonini Dec 11, 2022
e66011a
v1.6: Change ChargingProfileStatus value from NotImplemented to NotSu…
lorenzodonini Dec 24, 2022
b542323
v2.0.1: Fix incorrect IdTokenType
lorenzodonini Dec 24, 2022
2fa5412
v2.0.1: Fix csms example after merging #163
lorenzodonini Dec 24, 2022
8c6098d
Use correct name to validate ClearChargingProfileConfirmation
Feb 23, 2023
0195c3f
Add debug logs for raw json messages
lorenzodonini Feb 4, 2023
70f4614
EscapeHTML configuration for json.Marshal
Feb 7, 2023
fc83394
Remove newline from encoded json byte array
lorenzodonini Mar 12, 2023
0374c84
Fix property constraint violation on ConfigurationKey nil values
lorenzodonini Mar 14, 2023
3c24b0d
Remove incorrect validation for IdToken in RequestStartTransactionReq…
lorenzodonini Mar 17, 2023
5869d11
feature to add a custom client validation handler before connected
dwibudut Feb 20, 2023
404fb1f
add/implement SetCheckClientHandler method on MockWebsocketServer
dwibudut Mar 21, 2023
7652fcf
fix/replace with direct func type arg on implement method SetCheckCli…
dwibudut Mar 21, 2023
fc3ab08
implement method `SetNewChargingStationValidationHandler` on ocpp1.6 …
dwibudut Mar 23, 2023
7d6d270
Add handler
shiv3 Feb 27, 2023
22b4f86
Add router to non tls server
shiv3 Mar 22, 2023
b979d02
Fix goimport
shiv3 Mar 22, 2023
3facaad
Fix CallError marshaling of empty fields
lorenzodonini Apr 7, 2023
c3dee61
Add send response error handling function
lorenzodonini Apr 7, 2023
3fbe338
Add error handling function for server SendResponse
lorenzodonini Apr 7, 2023
0ae68c7
Improve error handling and rewrite tests
lorenzodonini Apr 8, 2023
dfa368e
Convert v1.6 core listeners to pointer receiver
lorenzodonini Apr 8, 2023
830bc32
Fix v1.6 error handling in sendResponse functions
lorenzodonini Apr 8, 2023
9490eba
Add v1.6 tests for new error handling
lorenzodonini Apr 8, 2023
3430e25
Fix v2.0.1 error handling in sendResponse functions
lorenzodonini Apr 8, 2023
3ec1db9
Add v2.0.1 tests for new error handling
lorenzodonini Apr 8, 2023
782920b
Fix broken tests
lorenzodonini Apr 8, 2023
c38d419
resolves issues/173 checking and handling invalid message property fo…
sc-atompower Apr 17, 2023
3ecaf00
reverted go.mod
sc-atompower Apr 17, 2023
0c73967
Fix SetVariableStatus validation tag
lorenzodonini May 19, 2023
34d3b60
fix messagesinqueue json
May 10, 2023
e034d39
Change messageinqueue to messagesinqueue
May 19, 2023
c34f6ad
Fix validation override between v1.6 and v2.0.1
lorenzodonini Jun 11, 2023
694d985
fix certificateType on CertificateSignedRequest & GetInstalledCertifi…
dwibudut Jun 29, 2023
69eec62
add another FirmwareStatus type on FirmwareStatusNotification (suppor…
dwibudut Jun 29, 2023
118355f
Fix deadlock on double client stop
lorenzodonini Jul 3, 2023
290c89e
Override FormatViolation error code for v2.0.1
lorenzodonini Jul 4, 2023
2fef296
Add tests for FormatViolation value
lorenzodonini Jul 8, 2023
3760b41
Add hook for custom handling of invalid messages
lorenzodonini Jul 30, 2023
d0d7f6d
change serial number validate max to 40
Jul 25, 2023
ff45def
Serial number in OCS Request need to be change as well
Jul 26, 2023
139992c
add IdTokenType MacAddress
dwibudut Jul 27, 2023
fa5b59a
add key16 and key201 to resetType and resetStatus
Aug 17, 2023
f0af2ad
check type on action in call and add test
Aug 24, 2023
c686786
Fix assertion for invalid TLS certificate test
lorenzodonini Sep 3, 2023
607bfeb
Merge pull request #18 from grid-x/sync-fork
hsteidl Mar 5, 2024
ae287d7
Merge branch 'master' into sync-gridx_extensions
hsteidl Mar 5, 2024
add4e73
refactor(*): fix merge problems
hsteidl Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/1.6/cp/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ func (handler *ChargePointHandler) OnCancelReservation(request *reservation.Canc
func (handler *ChargePointHandler) OnSetChargingProfile(request *smartcharging.SetChargingProfileRequest) (confirmation *smartcharging.SetChargingProfileConfirmation, err error) {
//TODO: handle logic
logDefault(request.GetFeatureName()).Warn("no set charging profile logic implemented yet")
return smartcharging.NewSetChargingProfileConfirmation(smartcharging.ChargingProfileStatusNotImplemented), nil
return smartcharging.NewSetChargingProfileConfirmation(smartcharging.ChargingProfileStatusNotSupported), nil
}

func (handler *ChargePointHandler) OnClearChargingProfile(request *smartcharging.ClearChargingProfileRequest) (confirmation *smartcharging.ClearChargingProfileConfirmation, err error) {
Expand Down
2 changes: 1 addition & 1 deletion example/2.0.1/csms/csms_sim.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func exampleRoutine(chargingStationID string, handler *CSMSHandler) {
time.Sleep(2 * time.Second)
// Reserve a connector
reservationID := 42
clientIDTokenType := types.IdTokenTypeKeyCode
clientIDTokenType := types.IdToken{IdToken: "1234", Type: types.IdTokenTypeKeyCode}
clientIdTag := "l33t"
connectorID := 1
expiryDate := types.NewDateTime(time.Now().Add(1 * time.Hour))
Expand Down
23 changes: 19 additions & 4 deletions ocpp1.6/central_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ocpp16

import (
"fmt"
"reflect"

"github.com/lorenzodonini/ocpp-go/internal/callbackqueue"
"github.com/lorenzodonini/ocpp-go/ocpp"
Expand Down Expand Up @@ -360,6 +361,10 @@ func (cs *centralSystem) SetSmartChargingHandler(handler smartcharging.CentralSy
cs.smartChargingHandler = handler
}

func (cs *centralSystem) SetNewChargingStationValidationHandler(handler ws.CheckClientHandler) {
cs.server.SetNewClientValidationHandler(handler)
}

func (cs *centralSystem) SetNewChargePointHandler(handler ChargePointConnectionHandler) {
cs.server.SetNewClientHandler(func(chargePoint ws.Channel) {
handler(chargePoint)
Expand Down Expand Up @@ -399,30 +404,40 @@ func (cs *centralSystem) SendRequestAsync(clientId string, request ocpp.Request,
}

func (cs *centralSystem) Start(listenPort int, listenPath string) {
// Overriding some protocol-specific values in the lower layers globally
ocppj.FormationViolation = ocppj.FormatViolationV16
// Start server
cs.server.Start(listenPort, listenPath)
}

func (cs *centralSystem) sendResponse(chargePointId string, confirmation ocpp.Response, err error, requestId string) {
// send error response
if err != nil {
cs.error(fmt.Errorf("error handling request: %w", err))
err := cs.server.SendError(chargePointId, requestId, ocppj.InternalError, "Error handling request", nil)
// Send error response
err = cs.server.SendError(chargePointId, requestId, ocppj.InternalError, err.Error(), nil)
if err != nil {
// Error while sending an error. Will attempt to send a default error instead
cs.server.HandleFailedResponseError(chargePointId, requestId, err, "")
// Notify client implementation
err = fmt.Errorf("error replying cp %s to request %s with 'internal error': %w", chargePointId, requestId, err)
cs.error(err)
}
return
}

if confirmation == nil {
if confirmation == nil || reflect.ValueOf(confirmation).IsNil() {
err = fmt.Errorf("empty confirmation to %s for request %s", chargePointId, requestId)
// Sending a dummy error to server instead, then notify client implementation
_ = cs.server.SendError(chargePointId, requestId, ocppj.GenericError, err.Error(), nil)
cs.error(err)
return
}

// send confirmation response
err = cs.server.SendResponse(chargePointId, requestId, confirmation)
if err != nil {
// Error while sending an error. Will attempt to send a default error instead
cs.server.HandleFailedResponseError(chargePointId, requestId, err, confirmation.GetFeatureName())
// Notify client implementation
err = fmt.Errorf("error replying cp %s to request %s: %w", chargePointId, requestId, err)
cs.error(err)
}
Expand Down
29 changes: 22 additions & 7 deletions ocpp1.6/charge_point.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ocpp16

import (
"fmt"
"reflect"
"sync"

"github.com/lorenzodonini/ocpp-go/internal/callbackqueue"
Expand Down Expand Up @@ -297,35 +298,45 @@ func (cp *chargePoint) clearCallbacks(invokeCallback bool) {
}

func (cp *chargePoint) sendResponse(confirmation ocpp.Response, err error, requestId string) {
// send error response
if err != nil {
err = cp.client.SendError(requestId, ocppj.ProtocolError, err.Error(), nil)
// Send error response
err = cp.client.SendError(requestId, ocppj.InternalError, err.Error(), nil)
if err != nil {
err = fmt.Errorf("replying cs to request %s with 'protocol error': %w", requestId, err)
// Error while sending an error. Will attempt to send a default error instead
cp.client.HandleFailedResponseError(requestId, err, "")
// Notify client implementation
err = fmt.Errorf("replying to request %s with 'internal error' failed: %w", requestId, err)
cp.error(err)
}

return
}

if confirmation == nil {
if confirmation == nil || reflect.ValueOf(confirmation).IsNil() {
err = fmt.Errorf("empty confirmation to request %s", requestId)
// Sending a dummy error to server instead, then notify client implementation
_ = cp.client.SendError(requestId, ocppj.GenericError, err.Error(), nil)
cp.error(err)
return
}

// send confirmation response
err = cp.client.SendResponse(requestId, confirmation)
if err != nil {
err = fmt.Errorf("replying cs to request %s: %w", requestId, err)
// Error while sending an error. Will attempt to send a default error instead
cp.client.HandleFailedResponseError(requestId, err, confirmation.GetFeatureName())
// Notify client implementation
err = fmt.Errorf("failed responding to request %s: %w", requestId, err)
cp.error(err)
}
}

func (cp *chargePoint) Start(centralSystemUrl string) error {
// Overriding some protocol-specific values in the lower layers globally
ocppj.FormationViolation = ocppj.FormatViolationV16
// Start client
cp.stopC = make(chan struct{}, 1)
// Async response handler receives incoming responses/errors and triggers callbacks
err := cp.client.Start(centralSystemUrl)
// Async response handler receives incoming responses/errors and triggers callbacks
if err == nil {
go cp.asyncCallbackHandler()
}
Expand All @@ -343,6 +354,10 @@ func (cp *chargePoint) Stop() {
}
}

func (cp *chargePoint) IsConnected() bool {
return cp.client.IsConnected()
}

func (cp *chargePoint) notImplementedError(requestId string, action string) {
err := cp.client.SendError(requestId, ocppj.NotImplemented, fmt.Sprintf("no handler for action %v implemented", action), nil)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion ocpp1.6/core/get_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const GetConfigurationFeatureName = "GetConfiguration"
type ConfigurationKey struct {
Key string `json:"key" validate:"required,max=50"`
Readonly bool `json:"readonly"`
Value *string `json:"value,omitempty" validate:"max=500"`
Value *string `json:"value,omitempty" validate:"omitempty,max=500"`
}

// The field definition of the GetConfiguration request payload sent by the Central System to the Charge Point.
Expand Down
5 changes: 3 additions & 2 deletions ocpp1.6/core/remote_start_transaction.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package core

import (
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
"reflect"

"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
)

// -------------------- Remote Start Transaction (CS -> CP) --------------------
Expand All @@ -19,7 +20,7 @@ type RemoteStartTransactionRequest struct {
// This field definition of the RemoteStartTransaction confirmation payload, sent by the Charge Point to the Central System in response to a RemoteStartTransactionRequest.
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
type RemoteStartTransactionConfirmation struct {
Status types.RemoteStartStopStatus `json:"status" validate:"required,remoteStartStopStatus"`
Status types.RemoteStartStopStatus `json:"status" validate:"required,remoteStartStopStatus16"`
}

// Central System can request a Charge Point to start a transaction by sending a RemoteStartTransactionRequest.
Expand Down
5 changes: 3 additions & 2 deletions ocpp1.6/core/remote_stop_transaction.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package core

import (
"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
"reflect"

"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
)

// -------------------- Remote Stop Transaction (CS -> CP) --------------------
Expand All @@ -17,7 +18,7 @@ type RemoteStopTransactionRequest struct {
// This field definition of the RemoteStopTransaction confirmation payload, sent by the Charge Point to the Central System in response to a RemoteStopTransactionRequest.
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
type RemoteStopTransactionConfirmation struct {
Status types.RemoteStartStopStatus `json:"status" validate:"required,remoteStartStopStatus"`
Status types.RemoteStartStopStatus `json:"status" validate:"required,remoteStartStopStatus16"`
}

// Central System can request a Charge Point to stop a transaction by sending a RemoteStopTransactionRequest to Charge Point with the identifier of the transaction.
Expand Down
15 changes: 8 additions & 7 deletions ocpp1.6/core/reset.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package core

import (
"reflect"

"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
"gopkg.in/go-playground/validator.v9"
"reflect"
)

// -------------------- Reset (CS -> CP) --------------------
Expand Down Expand Up @@ -45,13 +46,13 @@ func isValidResetStatus(fl validator.FieldLevel) bool {

// The field definition of the Reset request payload sent by the Central System to the Charge Point.
type ResetRequest struct {
Type ResetType `json:"type" validate:"required,resetType"`
Type ResetType `json:"type" validate:"required,resetType16"`
}

// This field definition of the Reset confirmation payload, sent by the Charge Point to the Central System in response to a ResetRequest.
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
type ResetConfirmation struct {
Status ResetStatus `json:"status" validate:"required,resetStatus"`
Status ResetStatus `json:"status" validate:"required,resetStatus16"`
}

// The Central System SHALL send a ResetRequest for requesting a Charge Point to reset itself.
Expand All @@ -62,8 +63,8 @@ type ResetConfirmation struct {
// At receipt of a soft reset, the Charge Point SHALL stop ongoing transactions gracefully and send StopTransactionRequest for every ongoing transaction.
// It should then restart the application software (if possible, otherwise restart the processor/controller).
// At receipt of a hard reset the Charge Point SHALL restart (all) the hardware, it is not required to gracefully stop ongoing transaction.
//If possible the Charge Point sends a StopTransactionRequest for previously ongoing transactions after having restarted and having been accepted by the Central System via a BootNotificationConfirmation.
//This is a last resort solution for a not correctly functioning Charge Points, by sending a "hard" reset, (queued) information might get lost.
// If possible the Charge Point sends a StopTransactionRequest for previously ongoing transactions after having restarted and having been accepted by the Central System via a BootNotificationConfirmation.
// This is a last resort solution for a not correctly functioning Charge Points, by sending a "hard" reset, (queued) information might get lost.
type ResetFeature struct{}

func (f ResetFeature) GetFeatureName() string {
Expand Down Expand Up @@ -97,6 +98,6 @@ func NewResetConfirmation(status ResetStatus) *ResetConfirmation {
}

func init() {
_ = types.Validate.RegisterValidation("resetType", isValidResetType)
_ = types.Validate.RegisterValidation("resetStatus", isValidResetStatus)
_ = types.Validate.RegisterValidation("resetType16", isValidResetType)
_ = types.Validate.RegisterValidation("resetStatus16", isValidResetStatus)
}
7 changes: 4 additions & 3 deletions ocpp1.6/smartcharging/clear_charging_profile.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package smartcharging

import (
"reflect"

"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
"gopkg.in/go-playground/validator.v9"
"reflect"
)

// -------------------- Clear Charging Profile (CS -> CP) --------------------
Expand Down Expand Up @@ -32,14 +33,14 @@ func isValidClearChargingProfileStatus(fl validator.FieldLevel) bool {
type ClearChargingProfileRequest struct {
Id *int `json:"id,omitempty" validate:"omitempty"`
ConnectorId *int `json:"connectorId,omitempty" validate:"omitempty,gte=0"`
ChargingProfilePurpose types.ChargingProfilePurposeType `json:"chargingProfilePurpose,omitempty" validate:"omitempty,chargingProfilePurpose"`
ChargingProfilePurpose types.ChargingProfilePurposeType `json:"chargingProfilePurpose,omitempty" validate:"omitempty,chargingProfilePurpose16"`
StackLevel *int `json:"stackLevel,omitempty" validate:"omitempty,gte=0"`
}

// This field definition of the ClearChargingProfile confirmation payload, sent by the Charge Point to the Central System in response to a ClearChargingProfileRequest.
// In case the request was invalid, or couldn't be processed, an error will be sent instead.
type ClearChargingProfileConfirmation struct {
Status ClearChargingProfileStatus `json:"status" validate:"required,chargingProfileStatus"`
Status ClearChargingProfileStatus `json:"status" validate:"required,clearChargingProfileStatus"`
}

// If the Central System wishes to clear some or all of the charging profiles that were previously sent the Charge Point,
Expand Down
5 changes: 3 additions & 2 deletions ocpp1.6/smartcharging/get_composite_schedule.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package smartcharging

import (
"reflect"

"github.com/lorenzodonini/ocpp-go/ocpp1.6/types"
"gopkg.in/go-playground/validator.v9"
"reflect"
)

// -------------------- Get Composite Schedule (CS -> CP) --------------------
Expand Down Expand Up @@ -32,7 +33,7 @@ func isValidGetCompositeScheduleStatus(fl validator.FieldLevel) bool {
type GetCompositeScheduleRequest struct {
ConnectorId int `json:"connectorId" validate:"gte=0"`
Duration int `json:"duration" validate:"gte=0"`
ChargingRateUnit types.ChargingRateUnitType `json:"chargingRateUnit,omitempty" validate:"omitempty,chargingRateUnit"`
ChargingRateUnit types.ChargingRateUnitType `json:"chargingRateUnit,omitempty" validate:"omitempty,chargingRateUnit16"`
}

// This field definition of the GetCompositeSchedule confirmation payload, sent by the Charge Point to the Central System in response to a GetCompositeScheduleRequest.
Expand Down
8 changes: 4 additions & 4 deletions ocpp1.6/smartcharging/set_charging_profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ const SetChargingProfileFeatureName = "SetChargingProfile"
type ChargingProfileStatus string

const (
ChargingProfileStatusAccepted ChargingProfileStatus = "Accepted"
ChargingProfileStatusRejected ChargingProfileStatus = "Rejected"
ChargingProfileStatusNotImplemented ChargingProfileStatus = "NotImplemented"
ChargingProfileStatusAccepted ChargingProfileStatus = "Accepted"
ChargingProfileStatusRejected ChargingProfileStatus = "Rejected"
ChargingProfileStatusNotSupported ChargingProfileStatus = "NotSupported"
)

func isValidChargingProfileStatus(fl validator.FieldLevel) bool {
status := ChargingProfileStatus(fl.Field().String())
switch status {
case ChargingProfileStatusAccepted, ChargingProfileStatusRejected, ChargingProfileStatusNotImplemented:
case ChargingProfileStatusAccepted, ChargingProfileStatusRejected, ChargingProfileStatusNotSupported:
return true
default:
return false
Expand Down
Loading
Loading