Skip to content

Commit 7efcc73

Browse files
committed
feat: wip on controllers
1 parent 2d0ea30 commit 7efcc73

33 files changed

Lines changed: 2507 additions & 519 deletions

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/samber/lo v1.47.0
1111
github.com/sirupsen/logrus v1.9.3
1212
github.com/stretchr/testify v1.10.0
13+
github.com/zyedidia/generic v1.2.1
1314
)
1415

1516
require (
@@ -21,6 +22,8 @@ require (
2122
github.com/leodido/go-urn v1.1.0 // indirect
2223
github.com/pmezard/go-difflib v1.0.0 // indirect
2324
github.com/relvacode/iso8601 v1.6.0 // indirect
25+
github.com/segmentio/fasthash v1.0.3 // indirect
26+
golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e // indirect
2427
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 // indirect
2528
golang.org/x/text v0.16.0 // indirect
2629
gopkg.in/go-playground/validator.v9 v9.30.0 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ github.com/relvacode/iso8601 v1.6.0 h1:eFXUhMJN3Gz8Rcq82f9DTMW0svjtAVuIEULglM7QH
3131
github.com/relvacode/iso8601 v1.6.0/go.mod h1:FlNp+jz+TXpyRqgmM7tnzHHzBnz776kmAH2h3sZCn0I=
3232
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
3333
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
34+
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
35+
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
3436
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
3537
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
3638
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -45,6 +47,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
4547
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
4648
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
4749
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
50+
github.com/zyedidia/generic v1.2.1 h1:Zv5KS/N2m0XZZiuLS82qheRG4X1o5gsWreGb0hR7XDc=
51+
github.com/zyedidia/generic v1.2.1/go.mod h1:ly2RBz4mnz1yeuVbQA/VFwGjK3mnHGRj1JuoG336Bis=
52+
golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e h1:iWVPgObh6F4UDtjBLK51zsy5UHTPLQwCmsNjCsbKhQ0=
53+
golang.org/x/exp v0.0.0-20220218215828-6cf2b201936e/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
4854
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4955
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5056
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME=

ocpp_v201/charging_infrastructure.go

Lines changed: 0 additions & 17 deletions
This file was deleted.

ocpp_v201/charging_station.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package ocpp_v201
2+
3+
import "github.com/ChargePi/ocpp-manager/ocpp_v201/component"
4+
5+
type ChargingStation struct {
6+
ID string
7+
components map[component.Name]component.Component // Charging station (top level) specific components
8+
controllerManager Manager
9+
}

ocpp_v201/component/component.go

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,60 @@ package component
33
import "github.com/ChargePi/ocpp-manager/ocpp_v201/variables"
44

55
type Component interface {
6-
// Essentially a component type.
7-
GetName() ComponentName
8-
// Instance ID where a component can be addressed
6+
7+
// GetName Essentially a component type.
8+
GetName() Name
9+
10+
// GetInstanceId returns the unique instance ID of this component.
911
GetInstanceId() string
12+
1013
// RegisterSubComponent registers a sub-component to this component.
1114
RegisterSubComponent(component Component)
15+
1216
// UnregisterSubComponent unregisters a sub-component from this component.
1317
UnregisterSubComponent(component Component)
18+
1419
// GetSubComponents returns all sub-components of this component.
1520
GetSubComponents() []Component
1621

17-
// Required variables for this component
18-
GetRequiredVariables() []variables.Variable
19-
// Suported variables for this component
20-
GetSupportedVariables() []variables.Variable
22+
// GetRequiredVariables returns required variables for this component
23+
GetRequiredVariables() []variables.VariableName
24+
25+
// GetSupportedVariables returns supported variables (both required and optional) for this component
26+
GetSupportedVariables() []variables.VariableName
2127

28+
// GetVariable retrieves a variable by its name.
2229
GetVariable(key variables.VariableName, opts ...GetSetVariableOption) (*variables.Variable, error)
30+
31+
// UpdateVariable updates a variable's attribute with a new value.
2332
UpdateVariable(variable variables.VariableName, attribute string, value interface{}, opts ...GetSetVariableOption) error
33+
34+
// Validate checks if the variable is valid for this component.
2435
Validate(key variables.VariableName) bool
2536
}
2637

27-
type ComponentName string
38+
type Name string
2839

2940
const (
30-
ComponentNameOCPPCommCtrlr ComponentName = "OCPPCommCtrlr"
31-
ComponentNameLocalAuthListCtrlr ComponentName = "LocalAuthListCtrlr"
32-
ComponentNameTxCtrlr ComponentName = "TxCtrlr"
33-
ComponentNameDeviceDataCtrlr ComponentName = "DeviceDataCtrlr"
34-
ComponentNameSecurityCtrlr ComponentName = "SecurityCtrlr"
35-
ComponentNameClockCtrlr ComponentName = "ClockCtrlr"
36-
ComponentNameCustomizationCtrlr ComponentName = "CustomizationCtrlr"
37-
ComponentNameSampledDataCtrlr ComponentName = "SampledDataCtrlr"
38-
ComponentNameAlignedDataCtrlr ComponentName = "AlignedDataCtrlr"
39-
ComponentNameReservationCtrlr ComponentName = "ReservationCtrlr"
40-
ComponentNameSmartChargingCtrlr ComponentName = "SmartChargingCtrlr"
41-
ComponentNameTariffCostCtrlr ComponentName = "TariffCostCtrlr"
42-
ComponentNameMonitoringCtrlr ComponentName = "MonitoringCtrlr"
43-
ComponentNameDisplayMessageCtrlr ComponentName = "DisplayMessageCtrlr"
44-
ComponentNameISO15118Ctrlr ComponentName = "ISO15118Ctrlr"
45-
ComponentNameAuthCtrlr ComponentName = "AuthCtrlr"
46-
ComponentNameAuthCacheCtrlr ComponentName = "AuthCacheCtrlr"
47-
ComponentNameChargingStation ComponentName = "ChargingStation"
48-
ComponentNameEVSE ComponentName = "EVSE"
49-
ComponentNameConnector ComponentName = "Connector"
50-
ComponentNameConnectedEV ComponentName = "ConnectedEV"
41+
ComponentNameOCPPCommCtrlr Name = "OCPPCommCtrlr"
42+
ComponentNameLocalAuthListCtrlr Name = "LocalAuthListCtrlr"
43+
ComponentNameTxCtrlr Name = "TxCtrlr"
44+
ComponentNameDeviceDataCtrlr Name = "DeviceDataCtrlr"
45+
ComponentNameSecurityCtrlr Name = "SecurityCtrlr"
46+
ComponentNameClockCtrlr Name = "ClockCtrlr"
47+
ComponentNameCustomizationCtrlr Name = "CustomizationCtrlr"
48+
ComponentNameSampledDataCtrlr Name = "SampledDataCtrlr"
49+
ComponentNameAlignedDataCtrlr Name = "AlignedDataCtrlr"
50+
ComponentNameReservationCtrlr Name = "ReservationCtrlr"
51+
ComponentNameSmartChargingCtrlr Name = "SmartChargingCtrlr"
52+
ComponentNameTariffCostCtrlr Name = "TariffCostCtrlr"
53+
ComponentNameMonitoringCtrlr Name = "MonitoringCtrlr"
54+
ComponentNameDisplayMessageCtrlr Name = "DisplayMessageCtrlr"
55+
ComponentNameISO15118Ctrlr Name = "ISO15118Ctrlr"
56+
ComponentNameAuthCtrlr Name = "AuthCtrlr"
57+
ComponentNameAuthCacheCtrlr Name = "AuthCacheCtrlr"
58+
ComponentNameChargingStation Name = "ChargingStation"
59+
ComponentNameEVSE Name = "EVSE"
60+
ComponentNameConnector Name = "Connector"
61+
ComponentNameConnectedEV Name = "ConnectedEV"
5162
)

ocpp_v201/component/component_variable_opts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ type componentVariableOptions struct {
66
attributeType string
77
}
88

9+
// WithAttributeType sets the attribute type for the variable options.
910
func WithAttributeType(attributeType string) GetSetVariableOption {
1011
return func(o *componentVariableOptions) {
1112
o.attributeType = attributeType

ocpp_v201/connector.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package ocpp_v201
2+
3+
import "github.com/ChargePi/ocpp-manager/ocpp_v201/component"
4+
5+
type Connector struct {
6+
ID int
7+
components map[component.Name]component.Component
8+
}

ocpp_v201/controllers/aligned_data_ctrlr.go

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package controllers
22

33
import (
4+
"fmt"
5+
"sync"
6+
47
"github.com/ChargePi/ocpp-manager/ocpp_v201/component"
58
"github.com/ChargePi/ocpp-manager/ocpp_v201/variables"
69
)
@@ -39,65 +42,106 @@ func supportedAlignedDataVariables() []variables.VariableName {
3942
}
4043

4144
type AlignedDataCtrlr struct {
42-
variables map[variables.VariableName]variables.Variable
45+
mu sync.RWMutex
46+
variables map[variables.VariableName]*variables.Variable
4347
requiredVariables []variables.VariableName
4448
supportedVariables []variables.VariableName
49+
instanceId string
50+
validator *variableValidator
4551
}
4652

47-
func (a *AlignedDataCtrlr) GetName() component.ComponentName {
48-
//TODO implement me
49-
panic("implement me")
53+
func (a *AlignedDataCtrlr) GetName() component.Name {
54+
return component.ComponentNameAlignedDataCtrlr
5055
}
5156

5257
func (a *AlignedDataCtrlr) GetInstanceId() string {
53-
//TODO implement me
54-
panic("implement me")
58+
return a.instanceId
5559
}
5660

5761
func (a *AlignedDataCtrlr) RegisterSubComponent(component component.Component) {
58-
//TODO implement me
59-
panic("implement me")
62+
// No-op: controllers do not support sub-components
6063
}
6164

6265
func (a *AlignedDataCtrlr) UnregisterSubComponent(component component.Component) {
63-
//TODO implement me
64-
panic("implement me")
66+
// No-op: controllers do not support sub-components
6567
}
6668

6769
func (a *AlignedDataCtrlr) GetSubComponents() []component.Component {
68-
//TODO implement me
69-
panic("implement me")
70+
// Controllers do not support sub-components, always return empty slice
71+
return []component.Component{}
7072
}
7173

72-
func (a *AlignedDataCtrlr) GetRequiredVariables() []variables.Variable {
73-
//TODO implement me
74-
panic("implement me")
74+
func (a *AlignedDataCtrlr) GetRequiredVariables() []variables.VariableName {
75+
a.mu.RLock()
76+
defer a.mu.RUnlock()
77+
78+
return a.requiredVariables
7579
}
7680

77-
func (a *AlignedDataCtrlr) GetSupportedVariables() []variables.Variable {
78-
//TODO implement me
79-
panic("implement me")
81+
func (a *AlignedDataCtrlr) GetSupportedVariables() []variables.VariableName {
82+
a.mu.RLock()
83+
defer a.mu.RUnlock()
84+
85+
return a.supportedVariables
8086
}
8187

8288
func (a *AlignedDataCtrlr) GetVariable(key variables.VariableName, opts ...component.GetSetVariableOption) (*variables.Variable, error) {
83-
//TODO implement me
84-
panic("implement me")
89+
if !a.validator.IsVariableSupported(key) {
90+
return nil, fmt.Errorf("variable %s is not supported", key)
91+
}
92+
93+
a.mu.RLock()
94+
defer a.mu.RUnlock()
95+
96+
variable, exists := a.variables[key]
97+
if !exists {
98+
return nil, fmt.Errorf("variable %s not found", key)
99+
}
100+
101+
return variable, nil
85102
}
86103

87104
func (a *AlignedDataCtrlr) UpdateVariable(variable variables.VariableName, attribute string, value interface{}, opts ...component.GetSetVariableOption) error {
88-
//TODO implement me
89-
panic("implement me")
105+
if !a.validator.IsVariableSupported(variable) {
106+
return fmt.Errorf("variable %s is not supported", variable)
107+
}
108+
109+
a.mu.Lock()
110+
defer a.mu.Unlock()
111+
112+
v, exists := a.variables[variable]
113+
if !exists {
114+
return fmt.Errorf("variable %s not found", variable)
115+
}
116+
117+
return v.UpdateVariableAttribute(attribute, value)
90118
}
91119

92120
func (a *AlignedDataCtrlr) Validate(key variables.VariableName) bool {
93-
//TODO implement me
94-
panic("implement me")
121+
if !a.validator.IsVariableSupported(key) {
122+
return false
123+
}
124+
125+
a.mu.RLock()
126+
defer a.mu.RUnlock()
127+
128+
v, exists := a.variables[key]
129+
if !exists {
130+
return false
131+
}
132+
133+
return v.Validate()
95134
}
96135

97136
func NewAlignedDataCtrlr() *AlignedDataCtrlr {
98-
return &AlignedDataCtrlr{
99-
variables: make(map[variables.VariableName]variables.Variable),
137+
ctrlr := &AlignedDataCtrlr{
138+
mu: sync.RWMutex{},
139+
variables: make(map[variables.VariableName]*variables.Variable),
100140
requiredVariables: requiredAlignedDataVariables(),
101141
supportedVariables: supportedAlignedDataVariables(),
142+
instanceId: "aligned-data-ctrlr",
102143
}
144+
145+
ctrlr.validator = newVariableValidator(ctrlr)
146+
return ctrlr
103147
}

0 commit comments

Comments
 (0)