Documentation
¶
Overview ¶
Contains an implementation of OCPP message dispatcher via JSON over WebSocket.
Index ¶
- Constants
- Variables
- func IsErrorCodeValid(fl validator.FieldLevel) bool
- func ParseJsonMessage(dataJson string) []interface{}
- func ParseRawJsonMessage(dataJson []byte) []interface{}
- func SetLogger(logger ocpp.Logger)
- func SetMessageIdGenerator(generator func() string)
- type Call
- type CallError
- type CallResult
- type Client
- func (c *Client) SendError(requestId string, errorCode ocpp.ErrorCode, description string, ...) error
- func (c *Client) SendRequest(request ocpp.Request) error
- func (c *Client) SendResponse(requestId string, response ocpp.Response) error
- func (c *Client) SetErrorHandler(handler func(err *ocpp.Error, details interface{}))
- func (c *Client) SetRequestHandler(handler func(request ocpp.Request, requestId string, action string))
- func (c *Client) SetResponseHandler(handler func(response ocpp.Response, requestId string))
- func (c *Client) Start(serverURL string) error
- func (c *Client) Stop()
- type ClientDispatcher
- type DefaultClientDispatcher
- func (d *DefaultClientDispatcher) AddPendingRequest(requestID string, req ocpp.Request)
- func (d *DefaultClientDispatcher) ClearPendingRequests()
- func (d *DefaultClientDispatcher) CompleteRequest(requestId string)
- func (d *DefaultClientDispatcher) DeletePendingRequest(requestID string)
- func (d *DefaultClientDispatcher) GetPendingRequest(requestID string) (ocpp.Request, bool)
- func (d *DefaultClientDispatcher) HasPendingRequest() bool
- func (d *DefaultClientDispatcher) IsPaused() bool
- func (d *DefaultClientDispatcher) IsRunning() bool
- func (d *DefaultClientDispatcher) Pause()
- func (d *DefaultClientDispatcher) Resume()
- func (d *DefaultClientDispatcher) SendRequest(req interface{}) error
- func (d *DefaultClientDispatcher) SetNetworkClient(client ws.WsClient)
- func (d *DefaultClientDispatcher) SetOnRequestCanceled(cb func(string))
- func (d *DefaultClientDispatcher) SetPendingRequestState(_ PendingRequestState)
- func (d *DefaultClientDispatcher) SetTimeout(timeout time.Duration)
- func (d *DefaultClientDispatcher) Start()
- func (d *DefaultClientDispatcher) Stop()
- type DefaultServerDispatcher
- func (d *DefaultServerDispatcher) AddPendingRequest(requestID string, req ocpp.Request)
- func (d *DefaultServerDispatcher) ClearPendingRequests()
- func (d *DefaultServerDispatcher) CompleteRequest(clientID string, requestID string)
- func (d *DefaultServerDispatcher) DeleteClient(clientID string)
- func (d *DefaultServerDispatcher) DeletePendingRequest(requestID string)
- func (d *DefaultServerDispatcher) GetPendingRequest(requestID string) (ocpp.Request, bool)
- func (d *DefaultServerDispatcher) HasPendingRequest() bool
- func (d *DefaultServerDispatcher) IsRunning() bool
- func (d *DefaultServerDispatcher) SendRequest(clientID string, req RequestBundle) error
- func (d *DefaultServerDispatcher) SetNetworkServer(server ws.WsServer)
- func (d *DefaultServerDispatcher) SetOnRequestCanceled(cb func(string, string))
- func (d *DefaultServerDispatcher) SetPendingRequestState(_ PendingRequestState)
- func (d *DefaultServerDispatcher) Start()
- func (d *DefaultServerDispatcher) Stop()
- type Endpoint
- func (endpoint *Endpoint) AddProfile(profile *ocpp.Profile)
- func (endpoint *Endpoint) CreateCall(request ocpp.Request) (*Call, error)
- func (endpoint *Endpoint) CreateCallError(uniqueId string, code ocpp.ErrorCode, description string, details interface{}) *CallError
- func (endpoint *Endpoint) CreateCallResult(confirmation ocpp.Response, uniqueId string) (*CallResult, error)
- func (endpoint *Endpoint) GetProfile(name string) (*ocpp.Profile, bool)
- func (endpoint *Endpoint) GetProfileForFeature(featureName string) (*ocpp.Profile, bool)
- func (endpoint *Endpoint) ParseMessage(arr []interface{}) (Message, *ocpp.Error)
- type FIFOClientQueue
- type FIFOQueueMap
- type Message
- type MessageType
- type PendingRequestState
- type RequestBundle
- type RequestQueue
- type Server
- func (s *Server) SendError(clientID string, requestId string, errorCode ocpp.ErrorCode, ...) error
- func (s *Server) SendRequest(clientID string, request ocpp.Request) error
- func (s *Server) SendResponse(clientID string, requestId string, response ocpp.Response) error
- func (s *Server) SetDisconnectedClientHandler(handler func(clientID string))
- func (s *Server) SetErrorHandler(handler func(clientID string, err *ocpp.Error, details interface{}))
- func (s *Server) SetNewClientHandler(handler func(clientID string))
- func (s *Server) SetRequestHandler(...)
- func (s *Server) SetResponseHandler(handler func(clientID string, response ocpp.Response, requestId string))
- func (s *Server) Start(listenPort int, listenPath string)
- func (s *Server) Stop()
- type ServerDispatcher
- type ServerQueueMap
Constants ¶
const ( NotImplemented ocpp.ErrorCode = "NotImplemented" // Requested Action is not known by receiver. NotSupported ocpp.ErrorCode = "NotSupported" // Requested Action is recognized but not supported by the receiver. InternalError ocpp.ErrorCode = "InternalError" // An internal error occurred and the receiver was not able to process the requested Action successfully. MessageTypeNotSupported ocpp.ErrorCode = "MessageTypeNotSupported" // A message with an Message Type Number received that is not supported by this implementation. ProtocolError ocpp.ErrorCode = "ProtocolError" // Payload for Action is incomplete. SecurityError ocpp.ErrorCode = "SecurityError" // During the processing of Action a security issue occurred preventing receiver from completing the Action successfully. FormationViolation ocpp.ErrorCode = "FormationViolation" // Payload for Action is syntactically incorrect or not conform the PDU structure for Action. PropertyConstraintViolation ocpp.ErrorCode = "PropertyConstraintViolation" // Payload is syntactically correct but at least one field contains an invalid value. OccurrenceConstraintViolation ocpp.ErrorCode = "OccurrenceConstraintViolation" // Payload for Action is syntactically correct but at least one of the fields violates occurrence constraints. TypeConstraintViolation ocpp.ErrorCode = "TypeConstraintViolation" // Payload for Action is syntactically correct but at least one of the fields violates data type constraints (e.g. “somestring”: 12). GenericError ocpp.ErrorCode = "GenericError" // Any other error not covered by the previous ones. )
Variables ¶
var Validate = validator.New()
The validator, used for validating incoming/outgoing OCPP messages.
Functions ¶
func IsErrorCodeValid ¶
func IsErrorCodeValid(fl validator.FieldLevel) bool
func ParseJsonMessage ¶
func ParseJsonMessage(dataJson string) []interface{}
Unmarshals an OCPP-J json object from a JSON string. Returns the array of elements contained in the message.
func ParseRawJsonMessage ¶
func ParseRawJsonMessage(dataJson []byte) []interface{}
Unmarshals an OCPP-J json object from a byte array. Returns the array of elements contained in the message.
func SetLogger ¶
Sets a custom Logger implementation, allowing the ocpp-j package to log events. By default, a VoidLogger is used, so no logs will be sent to any output.
The function panics, if a nil logger is passed.
func SetMessageIdGenerator ¶
func SetMessageIdGenerator(generator func() string)
SetMessageIdGenerator sets a lambda function for generating unique IDs for new messages. The function is invoked automatically when creating a new Call.
Settings this overrides the default behavior, which is:
fmt.Sprintf("%v", rand.Uint32())
Types ¶
type Call ¶
type Call struct { Message `validate:"-"` MessageTypeId MessageType `json:"messageTypeId" validate:"required,eq=2"` UniqueId string `json:"uniqueId" validate:"required,max=36"` Action string `json:"action" validate:"required,max=36"` Payload ocpp.Request `json:"payload" validate:"required"` }
An OCPP-J Call message, containing an OCPP Request.
func (*Call) GetMessageTypeId ¶
func (call *Call) GetMessageTypeId() MessageType
func (*Call) GetUniqueId ¶
func (*Call) MarshalJSON ¶
type CallError ¶
type CallError struct { Message MessageTypeId MessageType `json:"messageTypeId" validate:"required,eq=4"` UniqueId string `json:"uniqueId" validate:"required,max=36"` ErrorCode ocpp.ErrorCode `json:"errorCode" validate:"errorCode"` ErrorDescription string `json:"errorDescription" validate:"required"` ErrorDetails interface{} `json:"errorDetails" validate:"omitempty"` }
An OCPP-J CallError message, containing an OCPP Error.
func (*CallError) GetMessageTypeId ¶
func (callError *CallError) GetMessageTypeId() MessageType
func (*CallError) GetUniqueId ¶
func (*CallError) MarshalJSON ¶
type CallResult ¶
type CallResult struct { Message MessageTypeId MessageType `json:"messageTypeId" validate:"required,eq=3"` UniqueId string `json:"uniqueId" validate:"required,max=36"` Payload ocpp.Response `json:"payload" validate:"required"` }
An OCPP-J CallResult message, containing an OCPP Response.
func (*CallResult) GetMessageTypeId ¶
func (callResult *CallResult) GetMessageTypeId() MessageType
func (*CallResult) GetUniqueId ¶
func (callResult *CallResult) GetUniqueId() string
func (*CallResult) MarshalJSON ¶
func (callResult *CallResult) MarshalJSON() ([]byte, error)
type Client ¶
The endpoint initiating the connection to an OCPP server, in an OCPP-J topology. During message exchange, the two roles may be reversed (depending on the message direction), but a client struct remains associated to a charge point/charging station.
func NewClient ¶
func NewClient(id string, wsClient ws.WsClient, dispatcher ClientDispatcher, stateHandler PendingRequestState, profiles ...*ocpp.Profile) *Client
Creates a new Client endpoint. Requires a unique client ID, a websocket client, a struct for queueing/dispatching requests, a state handler and a list of supported profiles (optional).
You may create a simple new server by using these default values:
s := ocppj.NewClient(ws.NewClient(), nil, nil)
func (*Client) SendError ¶
func (c *Client) SendError(requestId string, errorCode ocpp.ErrorCode, description string, details interface{}) error
Sends an OCPP Error to the server. The requestID parameter is required and identifies the previously received request.
Returns an error in the following cases:
- message validation fails (error is malformed)
- a network error occurred
func (*Client) SendRequest ¶
Sends an OCPP Request to the server. The protocol is based on request-response and cannot send multiple messages concurrently. To guarantee this, outgoing messages are added to a queue and processed sequentially.
Returns an error in the following cases:
- the client wasn't started
- message validation fails (request is malformed)
- the endpoint doesn't support the feature
- the output queue is full
func (*Client) SendResponse ¶
Sends an OCPP Response to the server. The requestID parameter is required and identifies the previously received request.
Returns an error in the following cases:
- message validation fails (response is malformed)
- the endpoint doesn't support the feature
- a network error occurred
func (*Client) SetErrorHandler ¶
Registers a handler for incoming error messages.
func (*Client) SetRequestHandler ¶
func (c *Client) SetRequestHandler(handler func(request ocpp.Request, requestId string, action string))
Registers a handler for incoming requests.
func (*Client) SetResponseHandler ¶
Registers a handler for incoming responses.
func (*Client) Start ¶
Connects to the given serverURL and starts running the I/O loop for the underlying connection. The write routine runs on a separate goroutine, while the read routine runs on the caller's routine. This means, the function is blocking for as long as the Client is connected to the Server.
Whenever the connection is ended, the function returns.
Call this function in a separate goroutine, to perform other operations on the main thread.
An error may be returned, if the connection failed or if it broke unexpectedly.
type ClientDispatcher ¶
type ClientDispatcher interface { // Starts the dispatcher. Depending on the implementation, this may // start a dedicated goroutine or simply allocate the necessary state. Start() // Sets the maximum timeout to be considered after sending a request. // If a response to the request is not received within the specified period, the request // is discarded and an error is returned to the caller. // // The timeout is reset upon a disconnection/reconnection. // // This function must be called before starting the dispatcher, otherwise it may lead to unexpected behavior. SetTimeout(timeout time.Duration) // Returns true, if the dispatcher is currently running, false otherwise. // If the dispatcher is paused, the function still returns true. IsRunning() bool // Returns true, if the dispatcher is currently paused, false otherwise. // If the dispatcher is not running at all, the function will still return false. IsPaused() bool // Dispatches a request. Depending on the implementation, this may first queue a request // and process it later, asynchronously, or write it directly to the networking layer. // // If no network client was set, or the request couldn't be processed, an error is returned. SendRequest(req interface{}) error // Notifies the dispatcher that a request has been completed (i.e. a response was received). // The dispatcher takes care of removing the request marked by the requestID from // the pending requests. It will then attempt to process the next queued request. CompleteRequest(requestID string) // Sets a callback to be invoked when a request gets canceled, due to network timeouts. // // Calling Stop on the dispatcher will not trigger this callback. // // If no callback is set, a request will still be removed from the dispatcher when a timeout occurs. SetOnRequestCanceled(cb func(string)) // Sets the network client, so the dispatcher may send requests using the networking layer directly. // // This needs to be set before calling the Start method. If not, sending requests will fail. SetNetworkClient(client ws.WsClient) // Sets the state manager for pending requests in the dispatcher. // // The state should only be accessed by the dispatcher while running. SetPendingRequestState(stateHandler PendingRequestState) // Stops a running dispatcher. This will clear all state and empty the internal queues. // // If an onRequestCanceled callback is set, it won't be triggered by stopping the dispatcher. Stop() // Notifies that an external event (typically network-related) should pause // the dispatcher. Internal timers will be stopped an no further requests // will be set to pending. You may keep enqueuing requests. // Use the Resume method for re-starting the dispatcher. Pause() // Undoes a previous pause operation, restarting internal timers and the // regular request flow. // // If there was a pending request before pausing the dispatcher, a response/timeout // for this request shall be awaited anew. Resume() }
ClientDispatcher contains the state and logic for handling outgoing messages on a client endpoint. This allows the ocpp-j layer to delegate queueing and processing logic to an external entity.
The dispatcher writes outgoing messages directly to the networking layer, using a previously set websocket client.
A PendingRequestState needs to be passed to the dispatcher, before starting it. The dispatcher is in charge of managing pending requests while handling the request flow.
type DefaultClientDispatcher ¶
type DefaultClientDispatcher struct {
// contains filtered or unexported fields
}
DefaultClientDispatcher is a default implementation of the ClientDispatcher interface.
The dispatcher implements the PendingRequestState as well for simplicity. Access to pending requests is thread-safe.
func NewDefaultClientDispatcher ¶
func NewDefaultClientDispatcher(queue RequestQueue) *DefaultClientDispatcher
NewDefaultClientDispatcher creates a new DefaultClientDispatcher struct.
func (*DefaultClientDispatcher) AddPendingRequest ¶
func (d *DefaultClientDispatcher) AddPendingRequest(requestID string, req ocpp.Request)
func (*DefaultClientDispatcher) ClearPendingRequests ¶
func (d *DefaultClientDispatcher) ClearPendingRequests()
func (*DefaultClientDispatcher) CompleteRequest ¶
func (d *DefaultClientDispatcher) CompleteRequest(requestId string)
func (*DefaultClientDispatcher) DeletePendingRequest ¶
func (d *DefaultClientDispatcher) DeletePendingRequest(requestID string)
func (*DefaultClientDispatcher) GetPendingRequest ¶
func (d *DefaultClientDispatcher) GetPendingRequest(requestID string) (ocpp.Request, bool)
func (*DefaultClientDispatcher) HasPendingRequest ¶
func (d *DefaultClientDispatcher) HasPendingRequest() bool
func (*DefaultClientDispatcher) IsPaused ¶
func (d *DefaultClientDispatcher) IsPaused() bool
func (*DefaultClientDispatcher) IsRunning ¶
func (d *DefaultClientDispatcher) IsRunning() bool
func (*DefaultClientDispatcher) Pause ¶
func (d *DefaultClientDispatcher) Pause()
func (*DefaultClientDispatcher) Resume ¶
func (d *DefaultClientDispatcher) Resume()
func (*DefaultClientDispatcher) SendRequest ¶
func (d *DefaultClientDispatcher) SendRequest(req interface{}) error
func (*DefaultClientDispatcher) SetNetworkClient ¶
func (d *DefaultClientDispatcher) SetNetworkClient(client ws.WsClient)
func (*DefaultClientDispatcher) SetOnRequestCanceled ¶
func (d *DefaultClientDispatcher) SetOnRequestCanceled(cb func(string))
func (*DefaultClientDispatcher) SetPendingRequestState ¶
func (d *DefaultClientDispatcher) SetPendingRequestState(_ PendingRequestState)
func (*DefaultClientDispatcher) SetTimeout ¶
func (d *DefaultClientDispatcher) SetTimeout(timeout time.Duration)
func (*DefaultClientDispatcher) Start ¶
func (d *DefaultClientDispatcher) Start()
func (*DefaultClientDispatcher) Stop ¶
func (d *DefaultClientDispatcher) Stop()
type DefaultServerDispatcher ¶
type DefaultServerDispatcher struct {
// contains filtered or unexported fields
}
DefaultServerDispatcher is a default implementation of the ServerDispatcher interface.
The dispatcher implements the PendingRequestState as well for simplicity. Access to pending requests is thread-safe.
func NewDefaultServerDispatcher ¶
func NewDefaultServerDispatcher(queueMap ServerQueueMap) *DefaultServerDispatcher
NewDefaultServerDispatcher creates a new DefaultServerDispatcher struct.
func (*DefaultServerDispatcher) AddPendingRequest ¶
func (d *DefaultServerDispatcher) AddPendingRequest(requestID string, req ocpp.Request)
func (*DefaultServerDispatcher) ClearPendingRequests ¶
func (d *DefaultServerDispatcher) ClearPendingRequests()
func (*DefaultServerDispatcher) CompleteRequest ¶
func (d *DefaultServerDispatcher) CompleteRequest(clientID string, requestID string)
func (*DefaultServerDispatcher) DeleteClient ¶
func (d *DefaultServerDispatcher) DeleteClient(clientID string)
func (*DefaultServerDispatcher) DeletePendingRequest ¶
func (d *DefaultServerDispatcher) DeletePendingRequest(requestID string)
func (*DefaultServerDispatcher) GetPendingRequest ¶
func (d *DefaultServerDispatcher) GetPendingRequest(requestID string) (ocpp.Request, bool)
func (*DefaultServerDispatcher) HasPendingRequest ¶
func (d *DefaultServerDispatcher) HasPendingRequest() bool
func (*DefaultServerDispatcher) IsRunning ¶
func (d *DefaultServerDispatcher) IsRunning() bool
func (*DefaultServerDispatcher) SendRequest ¶
func (d *DefaultServerDispatcher) SendRequest(clientID string, req RequestBundle) error
func (*DefaultServerDispatcher) SetNetworkServer ¶
func (d *DefaultServerDispatcher) SetNetworkServer(server ws.WsServer)
func (*DefaultServerDispatcher) SetOnRequestCanceled ¶
func (d *DefaultServerDispatcher) SetOnRequestCanceled(cb func(string, string))
func (*DefaultServerDispatcher) SetPendingRequestState ¶
func (d *DefaultServerDispatcher) SetPendingRequestState(_ PendingRequestState)
func (*DefaultServerDispatcher) Start ¶
func (d *DefaultServerDispatcher) Start()
func (*DefaultServerDispatcher) Stop ¶
func (d *DefaultServerDispatcher) Stop()
type Endpoint ¶
type Endpoint struct { Profiles []*ocpp.Profile PendingRequestState PendingRequestState }
An OCPP-J endpoint is one of the two entities taking part in the communication. The endpoint keeps state for supported OCPP profiles and current pending requests.
func (*Endpoint) AddProfile ¶
Adds support for a new profile on the endpoint.
func (*Endpoint) CreateCall ¶
Creates a Call message, given an OCPP request. A unique ID for the message is automatically generated. Returns an error in case the request's feature is not supported on this endpoint.
The created call is not automatically scheduled for transmission and is not added to the list of pending requests.
func (*Endpoint) CreateCallError ¶
func (endpoint *Endpoint) CreateCallError(uniqueId string, code ocpp.ErrorCode, description string, details interface{}) *CallError
Creates a CallError message, given the message's unique ID and the error.
func (*Endpoint) CreateCallResult ¶
func (endpoint *Endpoint) CreateCallResult(confirmation ocpp.Response, uniqueId string) (*CallResult, error)
Creates a CallResult message, given an OCPP response and the message's unique ID.
Returns an error in case the response's feature is not supported on this endpoint.
func (*Endpoint) GetProfile ¶
Retrieves a profile for the given profile name. Returns a false flag in case no profile matching the specified name was found.
func (*Endpoint) GetProfileForFeature ¶
Retrieves a profile for a given feature. Returns a false flag in case no profile supporting the specified feature was found.
func (*Endpoint) ParseMessage ¶
Parses an OCPP-J message. The function expects an array of elements, as contained in the JSON message.
Pending requests are automatically cleared, in case the received message is a CallResponse or CallError.
type FIFOClientQueue ¶
type FIFOClientQueue struct {
// contains filtered or unexported fields
}
FIFOClientQueue is a default queue implementation for OCPP-J clients.
func NewFIFOClientQueue ¶
func NewFIFOClientQueue(capacity int) *FIFOClientQueue
NewFIFOClientQueue creates a new FIFOClientQueue with the given capacity.
A FIFOQueue is backed by a linked list, and the capacity represents the maximum capacity of the queue. Passing capacity = 0 will create a queue without a maximum capacity. The capacity cannot change after creation.
func (*FIFOClientQueue) Init ¶
func (q *FIFOClientQueue) Init()
func (*FIFOClientQueue) IsEmpty ¶
func (q *FIFOClientQueue) IsEmpty() bool
func (*FIFOClientQueue) IsFull ¶
func (q *FIFOClientQueue) IsFull() bool
func (*FIFOClientQueue) Peek ¶
func (q *FIFOClientQueue) Peek() interface{}
func (*FIFOClientQueue) Pop ¶
func (q *FIFOClientQueue) Pop() interface{}
func (*FIFOClientQueue) Push ¶
func (q *FIFOClientQueue) Push(element interface{}) error
func (*FIFOClientQueue) Size ¶
func (q *FIFOClientQueue) Size() int
type FIFOQueueMap ¶
type FIFOQueueMap struct {
// contains filtered or unexported fields
}
FIFOQueueMap is a default implementation of ServerQueueMap for OCPP-J servers.
A FIFOQueueMap is backed by a map[string]RequestQueue. When calling the GetOrCreate function, if no entry for a key was found in the map, a new RequestQueue with the given capacity will be created.
func NewFIFOQueueMap ¶
func NewFIFOQueueMap(clientQueueCapacity int) *FIFOQueueMap
NewFIFOQueueMap creates a new FIFOQueueMap, which will automatically create queues with the specified capacity.
Passing capacity = 0 will generate queues without a maximum capacity. The capacity cannot change after creation.
func (*FIFOQueueMap) Add ¶
func (f *FIFOQueueMap) Add(clientID string, queue RequestQueue)
func (*FIFOQueueMap) Get ¶
func (f *FIFOQueueMap) Get(clientID string) (RequestQueue, bool)
func (*FIFOQueueMap) GetOrCreate ¶
func (f *FIFOQueueMap) GetOrCreate(clientID string) RequestQueue
func (*FIFOQueueMap) Init ¶
func (f *FIFOQueueMap) Init()
func (*FIFOQueueMap) Remove ¶
func (f *FIFOQueueMap) Remove(clientID string)
type Message ¶
type Message interface { // Returns the message type identifier of the message. GetMessageTypeId() MessageType // Returns the unique identifier of the message. GetUniqueId() string json.Marshaler }
An OCPP-J message.
type MessageType ¶
type MessageType int
MessageType identifies the type of message exchanged between two OCPP endpoints.
const ( CALL MessageType = 2 CALL_RESULT MessageType = 3 CALL_ERROR MessageType = 4 )
type PendingRequestState ¶
type PendingRequestState interface { // Sets a Request as pending on the endpoint. Requests are considered pending until a response was received. // The function expects a message unique ID and the Request. // If an element with the same requestID exists, it will be overwritten. AddPendingRequest(requestID string, req ocpp.Request) // Retrieves a pending Request, using the message ID. // If no request for the passed message ID is found, a false flag is returned. GetPendingRequest(requestID string) (ocpp.Request, bool) // Deletes a pending Request from the endpoint, using the message ID. DeletePendingRequest(requestID string) // Clears all currently pending requests. Any confirmation/error, // received as a response to a previously sent request, will be ignored. ClearPendingRequests() // Returns true if there currently is at least one pending request, false otherwise. HasPendingRequest() bool }
Contains the pending request state for messages. It is used to separate endpoint logic from state management.
type RequestBundle ¶
RequestBundle is a convenience struct for passing a call object struct and the raw byte data into the queue containing outgoing requests.
type RequestQueue ¶
type RequestQueue interface { // Init puts the queue in its initial state. May be used for initial setup or clearing. Init() // Push appends the given element at the end of the queue. // Returns an error if the operation failed (e.g. the queue is full). Push(element interface{}) error // Peek returns the first element of the queue, without removing it from the data structure. Peek() interface{} // Pop returns the first element of the queue, removing it from the queue. Pop() interface{} // Size returns the current size of the queue. Size() int // IsFull returns true if the queue is currently full, false otherwise. IsFull() bool // IsEmpty returns true if the queue is currently empty, false otherwise. IsEmpty() bool }
RequestQueue can be arbitrarily implemented, as long as it conforms to the Queue interface.
A RequestQueue is used by ocppj client and server to manage outgoing requests. The underlying data structure must be thread-safe, since different goroutines may access it at the same time.
type Server ¶
type Server struct { Endpoint // contains filtered or unexported fields }
The endpoint waiting for incoming connections from OCPP clients, in an OCPP-J topology. During message exchange, the two roles may be reversed (depending on the message direction), but a server struct remains associated to a central system.
func NewServer ¶
func NewServer(wsServer ws.WsServer, dispatcher ServerDispatcher, stateHandler PendingRequestState, profiles ...*ocpp.Profile) *Server
Creates a new Server endpoint. Requires a a websocket server, a structure for queueing/dispatching requests, a state handler and a list of profiles (optional).
You may create a simple new server by using these default values:
s := ocppj.NewServer(ws.NewServer(), nil, nil)
func (*Server) SendError ¶
func (s *Server) SendError(clientID string, requestId string, errorCode ocpp.ErrorCode, description string, details interface{}) error
Sends an OCPP Error to a client, identified by the clientID parameter. The requestID parameter is required and identifies the previously received request.
Returns an error in the following cases:
- message validation fails (error is malformed)
- a network error occurred
func (*Server) SendRequest ¶
Sends an OCPP Request to a client, identified by the clientID parameter.
Returns an error in the following cases:
- the server wasn't started
- message validation fails (request is malformed)
- the endpoint doesn't support the feature
- the output queue is full
func (*Server) SendResponse ¶
Sends an OCPP Response to a client, identified by the clientID parameter. The requestID parameter is required and identifies the previously received request.
Returns an error in the following cases:
- message validation fails (response is malformed)
- the endpoint doesn't support the feature
- a network error occurred
func (*Server) SetDisconnectedClientHandler ¶
Registers a handler for client disconnections.
func (*Server) SetErrorHandler ¶
func (s *Server) SetErrorHandler(handler func(clientID string, err *ocpp.Error, details interface{}))
Registers a handler for incoming error messages.
func (*Server) SetNewClientHandler ¶
Registers a handler for incoming client connections.
func (*Server) SetRequestHandler ¶
func (s *Server) SetRequestHandler(handler func(clientID string, request ocpp.Request, requestId string, action string))
Registers a handler for incoming requests.
func (*Server) SetResponseHandler ¶
func (s *Server) SetResponseHandler(handler func(clientID string, response ocpp.Response, requestId string))
Registers a handler for incoming responses.
func (*Server) Start ¶
Starts the underlying Websocket server on a specified listenPort and listenPath.
The function runs indefinitely, until the server is stopped. Invoke this function in a separate goroutine, to perform other operations on the main thread.
An error may be returned, if the websocket server couldn't be started.
type ServerDispatcher ¶
type ServerDispatcher interface { // Starts the dispatcher. Depending on the implementation, this may // start a dedicated goroutine or simply allocate the necessary state. Start() // Returns true, if the dispatcher is currently running, false otherwise. // If the dispatcher is paused, the function still returns true. IsRunning() bool // Dispatches a request for a specific client. Depending on the implementation, this may first queue // a request and process it later (asynchronously), or write it directly to the networking layer. // // If no network server was set, or the request couldn't be processed, an error is returned. SendRequest(clientID string, req RequestBundle) error // Notifies the dispatcher that a request has been completed (i.e. a response was received), // for a specific client. // The dispatcher takes care of removing the request marked by the requestID from // that client's pending requests. It will then attempt to process the next queued request. CompleteRequest(clientID string, requestID string) // Sets a callback to be invoked when a request gets canceled, due to network timeouts. // // Calling Stop on the dispatcher will not trigger this callback. // // If no callback is set, a request will still be removed from the dispatcher when a timeout occurs. SetOnRequestCanceled(cb func(string, string)) // Sets the network server, so the dispatcher may send requests using the networking layer directly. // // This needs to be set before calling the Start method. If not, sending requests will fail. SetNetworkServer(server ws.WsServer) // Sets the state manager for pending requests in the dispatcher. // // The state should only be accessed by the dispatcher while running. SetPendingRequestState(stateHandler PendingRequestState) // Stops a running dispatcher. This will clear all state and empty the internal queues. // // If an onRequestCanceled callback is set, it won't be triggered by stopping the dispatcher. Stop() // Notifies that an external event (typically network-related) should stop // dispatching requests for a specific client. // // Internal queues for that client will be cleared and no further requests will be accepted. // Undelivered pending requests are also cleared. // The OnRequestCanceled callback will be invoked for each discarded request. DeleteClient(clientID string) }
ServerDispatcher contains the state and logic for handling outgoing messages on a server endpoint. This allows the ocpp-j layer to delegate queueing and processing logic to an external entity.
The dispatcher writes outgoing messages directly to the networking layer, using a previously set websocket server.
A PendingRequestState needs to be passed to the dispatcher, before starting it. The dispatcher is in charge of managing all pending requests to clients, while handling the request flow.
type ServerQueueMap ¶
type ServerQueueMap interface { // Init puts the queue map in its initial state. May be used for initial setup or clearing. Init() // Get retrieves the queue associated to a specific clientID. // If no such element exists, the returned flag will be false. Get(clientID string) (RequestQueue, bool) // GetOrCreate retrieves the queue associated to a specific clientID. // If no such element exists, it is created, added to the map and returned. GetOrCreate(clientID string) RequestQueue // Remove deletes the queue associated to a specific clientID. // If no such element exists, nothing happens. Remove(clientID string) // Add inserts a new RequestQueue into the map structure. // If such element already exists, it will be replaced with the new queue. Add(clientID string, queue RequestQueue) }
ServerQueueMap defines the interface for managing client request queues.
An OCPP-J server may serve multiple clients at the same time, so it will need to provide a queue for each client.