Skip to content

Commit

Permalink
feat: stub set network profile
Browse files Browse the repository at this point in the history
  • Loading branch information
subnova committed Mar 19, 2024
1 parent 305060e commit 5850a72
Show file tree
Hide file tree
Showing 7 changed files with 329 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ fileignoreconfig:
checksum: 12cb2bc8ca2fe84231986857696a463e3dff4d5f9cdde9b265899b09bb1f95b0
- filename: manager/ocpp/ocpp201/notify_report_request.go
checksum: 56f5032378467e28dfc09b1c76d8eb7d96d13be2f14408532d9fdb284059178a
- filename: manager/ocpp/ocpp201/set_network_profile_request.go
checksum: 71232daa127770a24dc1fb540294537d431b25e7db12761fef48499a07ddcbfa
- filename: manager/ocpp/ocpp201/set_variables_request.go
checksum: d89e126fff18c8e6ecdc170a86bceb01fd2f46a676cae7178c17d1fa3e642613
- filename: manager/ocpp/ocpp201/transactionevent_request.go
Expand Down
8 changes: 8 additions & 0 deletions manager/handlers/ocpp201/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@ func NewRouter(emitter transport.Emitter,
ResponseSchema: "ocpp201/ResetResponse.json",
Handler: ResetResultHandler{},
},
"SetNetworkProfile": {
NewRequest: func() ocpp.Request { return new(ocpp201.SetNetworkProfileRequestJson) },
NewResponse: func() ocpp.Response { return new(ocpp201.SetNetworkProfileResponseJson) },
RequestSchema: "ocpp201/SetNetworkProfileRequest.json",
ResponseSchema: "ocpp201/SetNetworkProfileResponse.json",
Handler: SetNetworkProfileResultHandler{},
},
"SetVariables": {
NewRequest: func() ocpp.Request { return new(ocpp201.SetVariablesRequestJson) },
NewResponse: func() ocpp.Response { return new(ocpp201.SetVariablesResponseJson) },
Expand Down Expand Up @@ -239,6 +246,7 @@ func NewCallMaker(e transport.Emitter) *handlers.OcppCallMaker {
reflect.TypeOf(&ocpp201.RequestStartTransactionRequestJson{}): "RequestStartTransaction",
reflect.TypeOf(&ocpp201.RequestStopTransactionRequestJson{}): "RequestStopTransaction",
reflect.TypeOf(&ocpp201.ResetRequestJson{}): "Reset",
reflect.TypeOf(&ocpp201.SetNetworkProfileRequestJson{}): "SetNetworkProfile",
reflect.TypeOf(&ocpp201.SetVariablesRequestJson{}): "SetVariables",
reflect.TypeOf(&ocpp201.TriggerMessageRequestJson{}): "TriggerMessage",
reflect.TypeOf(&ocpp201.UnlockConnectorRequestJson{}): "UnlockConnector",
Expand Down
27 changes: 27 additions & 0 deletions manager/handlers/ocpp201/routing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,22 @@ func TestRoutingCallResults(t *testing.T) {
Status: types.ResetStatusEnumTypeScheduled,
},
},
"SetNetworkProfile": {
request: &types.SetNetworkProfileRequestJson{
ConfigurationSlot: 1,
ConnectionData: types.NetworkConnectionProfileType{
MessageTimeout: 30,
OcppCsmsUrl: "https://cs.example.com/",
OcppInterface: types.OCPPInterfaceEnumTypeWired0,
OcppTransport: types.OCPPTransportEnumTypeJSON,
OcppVersion: types.OCPPVersionEnumTypeOCPP20,
SecurityProfile: 2,
},
},
response: &types.SetNetworkProfileResponseJson{
Status: types.SetNetworkProfileStatusEnumTypeFailed,
},
},
"SetVariables": {
request: &types.SetVariablesRequestJson{
SetVariableData: []types.SetVariableDataType{
Expand Down Expand Up @@ -466,6 +482,17 @@ func TestCallMaker(t *testing.T) {
"Reset": &types.ResetRequestJson{
Type: types.ResetEnumTypeImmediate,
},
"SetNetworkProfile": &types.SetNetworkProfileRequestJson{
ConfigurationSlot: 1,
ConnectionData: types.NetworkConnectionProfileType{
MessageTimeout: 30,
OcppCsmsUrl: "https://cs.example.com/",
OcppInterface: types.OCPPInterfaceEnumTypeWired0,
OcppTransport: types.OCPPTransportEnumTypeJSON,
OcppVersion: types.OCPPVersionEnumTypeOCPP20,
SecurityProfile: 2,
},
},
"SetVariables": &types.SetVariablesRequestJson{
SetVariableData: []types.SetVariableDataType{
{
Expand Down
26 changes: 26 additions & 0 deletions manager/handlers/ocpp201/set_network_profile_result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: Apache-2.0

package ocpp201

import (
"context"
"github.com/thoughtworks/maeve-csms/manager/ocpp"
types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)

type SetNetworkProfileResultHandler struct{}

func (h SetNetworkProfileResultHandler) HandleCallResult(ctx context.Context, chargeStationId string, request ocpp.Request, response ocpp.Response, state any) error {
req := request.(*types.SetNetworkProfileRequestJson)
resp := response.(*types.SetNetworkProfileResponseJson)

span := trace.SpanFromContext(ctx)

span.SetAttributes(
attribute.Int("set_network_profile.config_slot", req.ConfigurationSlot),
attribute.String("set_network_profile.status", string(resp.Status)))

return nil
}
48 changes: 48 additions & 0 deletions manager/handlers/ocpp201/set_network_profile_result_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: Apache-2.0

package ocpp201_test

import (
"context"
"github.com/stretchr/testify/require"
"github.com/thoughtworks/maeve-csms/manager/handlers/ocpp201"
types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201"
"github.com/thoughtworks/maeve-csms/manager/testutil"
"testing"
)

func TestSetNetworkProfileResultHandler(t *testing.T) {
handler := ocpp201.SetNetworkProfileResultHandler{}

tracer, exporter := testutil.GetTracer()

ctx := context.Background()

func() {
ctx, span := tracer.Start(ctx, `test`)
defer span.End()

req := &types.SetNetworkProfileRequestJson{
ConfigurationSlot: 1,
ConnectionData: types.NetworkConnectionProfileType{
MessageTimeout: 30,
OcppCsmsUrl: "https://cs.example.com/",
OcppInterface: types.OCPPInterfaceEnumTypeWired0,
OcppTransport: types.OCPPTransportEnumTypeJSON,
OcppVersion: types.OCPPVersionEnumTypeOCPP20,
SecurityProfile: 2,
},
}
resp := &types.SetNetworkProfileResponseJson{
Status: types.SetNetworkProfileStatusEnumTypeAccepted,
}

err := handler.HandleCallResult(ctx, "cs001", req, resp, nil)
require.NoError(t, err)
}()

testutil.AssertSpan(t, &exporter.GetSpans()[0], "test", map[string]any{
"set_network_profile.config_slot": 1,
"set_network_profile.status": "Accepted",
})
}
196 changes: 196 additions & 0 deletions manager/ocpp/ocpp201/set_network_profile_request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// SPDX-License-Identifier: Apache-2.0

package ocpp201

type APNAuthenticationEnumType string

const APNAuthenticationEnumTypeAUTO APNAuthenticationEnumType = "AUTO"
const APNAuthenticationEnumTypeCHAP APNAuthenticationEnumType = "CHAP"
const APNAuthenticationEnumTypeNONE APNAuthenticationEnumType = "NONE"
const APNAuthenticationEnumTypePAP APNAuthenticationEnumType = "PAP"

// APN
// urn:x-oca:ocpp:uid:2:233134
// Collection of configuration data needed to make a data-connection over a
// cellular network.
//
// NOTE: When asking a GSM modem to dial in, it is possible to specify which mobile
// operator should be used. This can be done with the mobile country code (MCC) in
// combination with a mobile network code (MNC). Example: If your preferred network
// is Vodafone Netherlands, the MCC=204 and the MNC=04 which means the key
// PreferredNetwork = 20404 Some modems allows to specify a preferred network,
// which means, if this network is not available, a different network is used. If
// you specify UseOnlyPreferredNetwork and this network is not available, the modem
// will not dial in.
type APNType struct {
// APN. APN. URI
// urn:x-oca:ocpp:uid:1:568814
// The Access Point Name as an URL.
//
Apn string `json:"apn" yaml:"apn" mapstructure:"apn"`

// ApnAuthentication corresponds to the JSON schema field "apnAuthentication".
ApnAuthentication APNAuthenticationEnumType `json:"apnAuthentication" yaml:"apnAuthentication" mapstructure:"apnAuthentication"`

// APN. APN. Password
// urn:x-oca:ocpp:uid:1:568819
// APN Password.
//
ApnPassword *string `json:"apnPassword,omitempty" yaml:"apnPassword,omitempty" mapstructure:"apnPassword,omitempty"`

// APN. APN. User_ Name
// urn:x-oca:ocpp:uid:1:568818
// APN username.
//
ApnUserName *string `json:"apnUserName,omitempty" yaml:"apnUserName,omitempty" mapstructure:"apnUserName,omitempty"`

// CustomData corresponds to the JSON schema field "customData".
CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"`

// APN. Preferred_ Network. Mobile_ Network_ ID
// urn:x-oca:ocpp:uid:1:568822
// Preferred network, written as MCC and MNC concatenated. See note.
//
PreferredNetwork *string `json:"preferredNetwork,omitempty" yaml:"preferredNetwork,omitempty" mapstructure:"preferredNetwork,omitempty"`

// APN. SIMPIN. PIN_ Code
// urn:x-oca:ocpp:uid:1:568821
// SIM card pin code.
//
SimPin *int `json:"simPin,omitempty" yaml:"simPin,omitempty" mapstructure:"simPin,omitempty"`

// APN. Use_ Only_ Preferred_ Network. Indicator
// urn:x-oca:ocpp:uid:1:568824
// Default: false. Use only the preferred Network, do
// not dial in when not available. See Note.
//
UseOnlyPreferredNetwork bool `json:"useOnlyPreferredNetwork,omitempty" yaml:"useOnlyPreferredNetwork,omitempty" mapstructure:"useOnlyPreferredNetwork,omitempty"`
}

// Communication_ Function
// urn:x-oca:ocpp:uid:2:233304
// The NetworkConnectionProfile defines the functional and technical parameters of
// a communication link.
type NetworkConnectionProfileType struct {
// Apn corresponds to the JSON schema field "apn".
Apn *APNType `json:"apn,omitempty" yaml:"apn,omitempty" mapstructure:"apn,omitempty"`

// CustomData corresponds to the JSON schema field "customData".
CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"`

// Duration in seconds before a message send by the Charging Station via this
// network connection times-out.
// The best setting depends on the underlying network and response times of the
// CSMS.
// If you are looking for a some guideline: use 30 seconds as a starting point.
//
MessageTimeout int `json:"messageTimeout" yaml:"messageTimeout" mapstructure:"messageTimeout"`

// Communication_ Function. OCPP_ Central_ System_ URL. URI
// urn:x-oca:ocpp:uid:1:569357
// URL of the CSMS(s) that this Charging Station communicates with.
//
OcppCsmsUrl string `json:"ocppCsmsUrl" yaml:"ocppCsmsUrl" mapstructure:"ocppCsmsUrl"`

// OcppInterface corresponds to the JSON schema field "ocppInterface".
OcppInterface OCPPInterfaceEnumType `json:"ocppInterface" yaml:"ocppInterface" mapstructure:"ocppInterface"`

// OcppTransport corresponds to the JSON schema field "ocppTransport".
OcppTransport OCPPTransportEnumType `json:"ocppTransport" yaml:"ocppTransport" mapstructure:"ocppTransport"`

// OcppVersion corresponds to the JSON schema field "ocppVersion".
OcppVersion OCPPVersionEnumType `json:"ocppVersion" yaml:"ocppVersion" mapstructure:"ocppVersion"`

// This field specifies the security profile used when connecting to the CSMS with
// this NetworkConnectionProfile.
//
SecurityProfile int `json:"securityProfile" yaml:"securityProfile" mapstructure:"securityProfile"`

// Vpn corresponds to the JSON schema field "vpn".
Vpn *VPNType `json:"vpn,omitempty" yaml:"vpn,omitempty" mapstructure:"vpn,omitempty"`
}

type OCPPInterfaceEnumType string

const OCPPInterfaceEnumTypeWired0 OCPPInterfaceEnumType = "Wired0"
const OCPPInterfaceEnumTypeWired1 OCPPInterfaceEnumType = "Wired1"
const OCPPInterfaceEnumTypeWired2 OCPPInterfaceEnumType = "Wired2"
const OCPPInterfaceEnumTypeWired3 OCPPInterfaceEnumType = "Wired3"
const OCPPInterfaceEnumTypeWireless0 OCPPInterfaceEnumType = "Wireless0"
const OCPPInterfaceEnumTypeWireless1 OCPPInterfaceEnumType = "Wireless1"
const OCPPInterfaceEnumTypeWireless2 OCPPInterfaceEnumType = "Wireless2"
const OCPPInterfaceEnumTypeWireless3 OCPPInterfaceEnumType = "Wireless3"

type OCPPTransportEnumType string

const OCPPTransportEnumTypeJSON OCPPTransportEnumType = "JSON"
const OCPPTransportEnumTypeSOAP OCPPTransportEnumType = "SOAP"

type OCPPVersionEnumType string

const OCPPVersionEnumTypeOCPP12 OCPPVersionEnumType = "OCPP12"
const OCPPVersionEnumTypeOCPP15 OCPPVersionEnumType = "OCPP15"
const OCPPVersionEnumTypeOCPP16 OCPPVersionEnumType = "OCPP16"
const OCPPVersionEnumTypeOCPP20 OCPPVersionEnumType = "OCPP20"

type SetNetworkProfileRequestJson struct {
// Slot in which the configuration should be stored.
//
ConfigurationSlot int `json:"configurationSlot" yaml:"configurationSlot" mapstructure:"configurationSlot"`

// ConnectionData corresponds to the JSON schema field "connectionData".
ConnectionData NetworkConnectionProfileType `json:"connectionData" yaml:"connectionData" mapstructure:"connectionData"`

// CustomData corresponds to the JSON schema field "customData".
CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"`
}

func (*SetNetworkProfileRequestJson) IsRequest() {}

type VPNEnumType string

const VPNEnumTypeIKEv2 VPNEnumType = "IKEv2"
const VPNEnumTypeIPSec VPNEnumType = "IPSec"
const VPNEnumTypeL2TP VPNEnumType = "L2TP"
const VPNEnumTypePPTP VPNEnumType = "PPTP"

// VPN
// urn:x-oca:ocpp:uid:2:233268
// VPN Configuration settings
type VPNType struct {
// CustomData corresponds to the JSON schema field "customData".
CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"`

// VPN. Group. Group_ Name
// urn:x-oca:ocpp:uid:1:569274
// VPN group.
//
Group *string `json:"group,omitempty" yaml:"group,omitempty" mapstructure:"group,omitempty"`

// VPN. Key. VPN_ Key
// urn:x-oca:ocpp:uid:1:569276
// VPN shared secret.
//
Key string `json:"key" yaml:"key" mapstructure:"key"`

// VPN. Password. Password
// urn:x-oca:ocpp:uid:1:569275
// VPN Password.
//
Password string `json:"password" yaml:"password" mapstructure:"password"`

// VPN. Server. URI
// urn:x-oca:ocpp:uid:1:569272
// VPN Server Address
//
Server string `json:"server" yaml:"server" mapstructure:"server"`

// Type corresponds to the JSON schema field "type".
Type VPNEnumType `json:"type" yaml:"type" mapstructure:"type"`

// VPN. User. User_ Name
// urn:x-oca:ocpp:uid:1:569273
// VPN User
//
User string `json:"user" yaml:"user" mapstructure:"user"`
}
22 changes: 22 additions & 0 deletions manager/ocpp/ocpp201/set_network_profile_response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: Apache-2.0

package ocpp201

type SetNetworkProfileStatusEnumType string

const SetNetworkProfileStatusEnumTypeAccepted SetNetworkProfileStatusEnumType = "Accepted"
const SetNetworkProfileStatusEnumTypeFailed SetNetworkProfileStatusEnumType = "Failed"
const SetNetworkProfileStatusEnumTypeRejected SetNetworkProfileStatusEnumType = "Rejected"

type SetNetworkProfileResponseJson struct {
// CustomData corresponds to the JSON schema field "customData".
CustomData *CustomDataType `json:"customData,omitempty" yaml:"customData,omitempty" mapstructure:"customData,omitempty"`

// Status corresponds to the JSON schema field "status".
Status SetNetworkProfileStatusEnumType `json:"status" yaml:"status" mapstructure:"status"`

// StatusInfo corresponds to the JSON schema field "statusInfo".
StatusInfo *StatusInfoType `json:"statusInfo,omitempty" yaml:"statusInfo,omitempty" mapstructure:"statusInfo,omitempty"`
}

func (*SetNetworkProfileResponseJson) IsResponse() {}

0 comments on commit 5850a72

Please sign in to comment.