func (endpoint *Endpoint) GetProfile(name string) (*ocpp.Profile, bool) {
	for _, p := range endpoint.Profiles {
		if p.Name == name {
			return p, true
		}
	}
	return nil, false
}
Retrieves a profile for the given profile name.
Returns a false flag in case no profile matching the specified name was found.
package ocppj
import (
	"encoding/json"
	"fmt"
	"math/rand"
	"reflect"
	"gopkg.in/go-playground/validator.v9"
	"github.com/lorenzodonini/ocpp-go/ocpp"
)
var Validate = validator.New()
var log ocpp.Logger = &ocpp.VoidLogger{}
func init() {
	_ = Validate.RegisterValidation("errorCode", IsErrorCodeValid)
}
func SetLogger(logger ocpp.Logger) {
	if logger == nil {
		panic("cannot set a nil logger")
	}
	log = logger
}
type MessageType int
const (
	CALL        MessageType = 2
	CALL_RESULT MessageType = 3
	CALL_ERROR  MessageType = 4
)
type Message interface {
	GetMessageTypeId() MessageType
	GetUniqueId() string
	json.Marshaler
}
var messageIdGenerator = func() string {
	return fmt.Sprintf("%v", rand.Uint32())
}
func SetMessageIdGenerator(generator func() string) {
	if generator != nil {
		messageIdGenerator = generator
	}
}
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"`
}
func (call *Call) GetMessageTypeId() MessageType {
	return call.MessageTypeId
}
func (call *Call) GetUniqueId() string {
	return call.UniqueId
}
func (call *Call) MarshalJSON() ([]byte, error) {
	fields := make([]interface{}, 4)
	fields[0] = int(call.MessageTypeId)
	fields[1] = call.UniqueId
	fields[2] = call.Action
	fields[3] = call.Payload
	return json.Marshal(fields)
}
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"`
}
func (callResult *CallResult) GetMessageTypeId() MessageType {
	return callResult.MessageTypeId
}
func (callResult *CallResult) GetUniqueId() string {
	return callResult.UniqueId
}
func (callResult *CallResult) MarshalJSON() ([]byte, error) {
	fields := make([]interface{}, 3)
	fields[0] = int(callResult.MessageTypeId)
	fields[1] = callResult.UniqueId
	fields[2] = callResult.Payload
	return json.Marshal(fields)
}
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"`
}
func (callError *CallError) GetMessageTypeId() MessageType {
	return callError.MessageTypeId
}
func (callError *CallError) GetUniqueId() string {
	return callError.UniqueId
}
func (callError *CallError) MarshalJSON() ([]byte, error) {
	fields := make([]interface{}, 5)
	fields[0] = int(callError.MessageTypeId)
	fields[1] = callError.UniqueId
	fields[2] = callError.ErrorCode
	fields[3] = callError.ErrorDescription
	fields[4] = callError.ErrorDetails
	return ocppMessageToJson(fields)
}
const (
	NotImplemented                ocpp.ErrorCode = "NotImplemented"                 
	NotSupported                  ocpp.ErrorCode = "NotSupported"                   
	InternalError                 ocpp.ErrorCode = "InternalError"                  
	MessageTypeNotSupported       ocpp.ErrorCode = "MessageTypeNotSupported"        
	ProtocolError                 ocpp.ErrorCode = "ProtocolError"                  
	SecurityError                 ocpp.ErrorCode = "SecurityError"                  
	FormationViolation            ocpp.ErrorCode = "FormationViolation"             
	PropertyConstraintViolation   ocpp.ErrorCode = "PropertyConstraintViolation"    
	OccurrenceConstraintViolation ocpp.ErrorCode = "OccurrenceConstraintViolation"  
	TypeConstraintViolation       ocpp.ErrorCode = "TypeConstraintViolation"        
	GenericError                  ocpp.ErrorCode = "GenericError"                   
)
func IsErrorCodeValid(fl validator.FieldLevel) bool {
	code := ocpp.ErrorCode(fl.Field().String())
	switch code {
	case NotImplemented, NotSupported, InternalError, MessageTypeNotSupported, ProtocolError, SecurityError, FormationViolation, PropertyConstraintViolation, OccurrenceConstraintViolation, TypeConstraintViolation, GenericError:
		return true
	}
	return false
}
func ParseRawJsonMessage(dataJson []byte) ([]interface{}, error) {
	var arr []interface{}
	err := json.Unmarshal(dataJson, &arr)
	if err != nil {
		return nil, err
	}
	return arr, nil
}
func ParseJsonMessage(dataJson string) ([]interface{}, error) {
	rawJson := []byte(dataJson)
	return ParseRawJsonMessage(rawJson)
}
func ocppMessageToJson(message interface{}) ([]byte, error) {
	jsonData, err := json.Marshal(message)
	if err != nil {
		return nil, err
	}
	jsonData[0] = '['
	jsonData[len(jsonData)-1] = ']'
	return jsonData, nil
}
func getValueLength(value interface{}) int {
	switch value.(type) {
	case int:
		return value.(int)
	case string:
		return len(value.(string))
	default:
		return 0
	}
}
func occurenceViolation(fieldError validator.FieldError, messageId, feature string) *ocpp.Error {
	description := fmt.Sprintf("Field %s required but not found", fieldError.Namespace())
	if feature != "" {
		description = fmt.Sprintf("%s for feature %s", description, feature)
	}
	return ocpp.NewError(OccurrenceConstraintViolation, description, messageId)
}
func propertyConstraintViolation(fieldError validator.FieldError, details, messageId, feature string) *ocpp.Error {
	description := fmt.Sprintf("Field %s must be %s %s, but was %d", fieldError.Namespace(), details, fieldError.Param(), getValueLength(fieldError.Value()))
	if feature != "" {
		description = fmt.Sprintf("%s for feature %s", description, feature)
	}
	return ocpp.NewError(
		PropertyConstraintViolation,
		description,
		messageId,
	)
}
func errorFromValidation(validationErrors validator.ValidationErrors, messageId string, feature string) *ocpp.Error {
	for _, el := range validationErrors {
		switch el.ActualTag() {
		case "required":
			return occurenceViolation(el, messageId, feature)
		case "max":
			return propertyConstraintViolation(el, "maximum", messageId, feature)
		case "min":
			return propertyConstraintViolation(el, "minimum", messageId, feature)
		case "gte":
			return propertyConstraintViolation(el, ">=", messageId, feature)
		case "gt":
			return propertyConstraintViolation(el, ">", messageId, feature)
		case "lte":
			return propertyConstraintViolation(el, "<=", messageId, feature)
		case "lt":
			return propertyConstraintViolation(el, "<", messageId, feature)
		}
	}
	return ocpp.NewError(GenericError, fmt.Sprintf("%v", validationErrors.Error()), messageId)
}
type Endpoint struct {
	Profiles []*ocpp.Profile
}
func (endpoint *Endpoint) AddProfile(profile *ocpp.Profile) {
	endpoint.Profiles = append(endpoint.Profiles, profile)
}