Skip to content

Commit 95748ba

Browse files
committed
Add config/objects file handling
1 parent fbbc80a commit 95748ba

9 files changed

+306
-81
lines changed

apdu_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ func TestVariousFrames(t *testing.T) {
163163
apdu Apdu
164164
apduBytes string
165165
}{
166+
// to do: test fail, because ssn,rsn are now dependent on state. state must be set in each test item
166167
{"M_ME_TD_1 spont", m_me_td_1, "\x68\x17\x14\x00\x02\x00\x22\x01\x03\x00\x01\x00\xd3\x04\x00\xff\x7f\x00\xbf\xde\x2c\x13\x61\x0b\x17"},
167168
{"C_IC_NA_1 act", gi_act, "\x68\x0e\x00\x00\x00\x00\x64\x01\x06\x00\x01\x00\x00\x00\x00\x14"},
168169
{"C_SC_NA_1 act", sc_act, "\x68\x0e\x02\x00\x18\x00\x2d\x01\x06\x00\x01\x00\x94\x11\x00\x01"},

cmd/main.go

+2-36
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,12 @@ import (
99
func main() {
1010
fmt.Println("vv140 started.")
1111

12-
state := vv104.NewState()
13-
config := vv104.NewState().Config
14-
15-
config.ParseFlags()
16-
state.Config = config
17-
1812
objects := vv104.NewObjects()
19-
asdu := vv104.NewAsdu()
20-
var infoObject vv104.InfoObj
21-
infoObject.Ioa = 100
22-
infoObject.Value = vv104.IntVal(2)
23-
var infoObjects []vv104.InfoObj
24-
infoObjects = append(infoObjects, infoObject)
25-
asdu.Casdu = 1
26-
asdu.TypeId = vv104.M_DP_NA_1
27-
asdu.InfoObj = infoObjects
28-
objects.AddObject("dp1", *asdu)
29-
30-
infoObject.Ioa = 101
31-
32-
objects.AddObject("dp2", *asdu)
33-
infoObject.Ioa = 102
34-
objects.AddObject("dp3", *asdu)
35-
infoObject.Ioa = 103
36-
objects.AddObject("dp4", *asdu)
37-
38-
asdu = vv104.NewAsdu()
39-
40-
infoObjects = nil
41-
infoObject.Ioa = 10
42-
infoObject.Value = vv104.IntVal(0)
43-
infoObjects = append(infoObjects, infoObject)
44-
asdu.Casdu = 1
45-
asdu.TypeId = vv104.C_SC_NA_1
46-
asdu.InfoObj = infoObjects
47-
objects.AddObject("sc1", *asdu)
13+
state := vv104.NewState()
14+
state.Config.ParseFlags(objects)
4815

4916
objects.PrintObjects()
5017

51-
// go sendAFrame(&state)
5218
state.Start()
5319

5420
fmt.Println("vv140 finished.")

config.go

+122-34
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,46 @@
11
package vv104
22

33
import (
4+
"errors"
45
"flag"
6+
"fmt"
7+
"os"
8+
"path/filepath"
9+
10+
"github.com/pelletier/go-toml/v2"
511
)
612

713
type Config struct {
8-
Mode string `json:"mode"`
9-
Ipv4Addr string `json:"ipv4Addr"`
10-
Port int `json:"port"`
11-
Casdu int `json:"casdu"`
12-
AutoAck bool `json:"autoAck"`
13-
K int `json:"k"`
14-
W int `json:"w"`
15-
T1 int `json:"t1"`
16-
T2 int `json:"t2"`
17-
T3 int `json:"t3"`
18-
IoaStructured bool `json:"ioaStructured"`
19-
InteractiveMode bool `json:"interactiveMode"`
20-
UseLocalTime bool `json:"useLocalTime"`
21-
LogToBuffer bool `json:"logToBuffer"`
22-
LogToStdOut bool `json:"logToStdOut"`
14+
Mode string `toml:"mode"`
15+
Ipv4Addr string `toml:"ipv4Addr"`
16+
Port int `toml:"port"`
17+
Casdu int `toml:"casdu"`
18+
AutoAck bool `toml:"autoAck"`
19+
K int `toml:"k"`
20+
W int `toml:"w"`
21+
T1 int `toml:"t1"`
22+
T2 int `toml:"t2"`
23+
T3 int `toml:"t3"`
24+
IoaStructured bool `toml:"ioaStructured"`
25+
InteractiveMode bool `toml:"interactiveMode"`
26+
UseLocalTime bool `toml:"useLocalTime"`
27+
LogToBuffer bool `toml:"logToBuffer"`
28+
LogToStdOut bool `toml:"logToStdOut"`
29+
}
30+
31+
type eximportConfig struct {
32+
Config *Config
33+
ConfiguredObjects *ConfiguredObjects
34+
}
35+
36+
func NewConfig() *Config {
37+
cfg := Config{}
38+
return &cfg
2339
}
2440

25-
func (config *Config) ParseFlags() {
41+
func (config *Config) ParseFlags(objects *Objects) {
2642

43+
confPathPtr := flag.String("c", "", "Path to config toml file. If conf.toml is provided, all other flags are overwritten")
2744
serverPtr := flag.Bool("s", false, "Connection mode: For Server (Controlled station) use '-s'. For Client (Controlling station) use without flag (default)")
2845
ipPtr := flag.String("h", "127.0.0.1", "IP address")
2946
interactivePtr := flag.Bool("i", true, "Start in interactive mode, control program with cli commands")
@@ -33,31 +50,102 @@ func (config *Config) ParseFlags() {
3350

3451
flag.Parse()
3552

36-
if *serverPtr {
37-
config.Mode = "server"
53+
if *confPathPtr != "" {
54+
// use conf.toml
55+
56+
loadedConfig, loadedObjects, err := LoadConfigAndObjectsFromFile(*confPathPtr)
57+
if err != nil {
58+
fmt.Println(err)
59+
return
60+
}
61+
*config = *loadedConfig
62+
*objects = *loadedObjects
63+
3864
} else {
39-
config.Mode = "client"
40-
}
4165

42-
config.Ipv4Addr = *ipPtr
43-
config.InteractiveMode = *interactivePtr
44-
config.Port = *portPtr
45-
config.LogToBuffer = *logToBufferPtr
46-
config.LogToStdOut = *logToStdOutPtr
66+
if *serverPtr {
67+
config.Mode = "server"
68+
} else {
69+
config.Mode = "client"
70+
}
4771

48-
// todo
49-
config.K = 12
50-
config.W = 8
51-
config.T1 = 15
52-
config.T2 = 10
53-
config.T3 = 20
54-
config.AutoAck = true
55-
config.IoaStructured = false
56-
config.UseLocalTime = false
72+
config.Ipv4Addr = *ipPtr
73+
config.InteractiveMode = *interactivePtr
74+
config.Port = *portPtr
75+
config.LogToBuffer = *logToBufferPtr
76+
config.LogToStdOut = *logToStdOutPtr
77+
78+
// todo
79+
config.K = 12
80+
config.W = 8
81+
config.T1 = 15
82+
config.T2 = 10
83+
config.T3 = 20
84+
config.AutoAck = true
85+
config.IoaStructured = false
86+
config.UseLocalTime = false
87+
}
5788

5889
}
5990

6091
func printConfig(config Config) {
6192
logInfo.Println("============= Config =============")
6293
logInfo.Printf("%+v\n", config)
6394
}
95+
96+
func WriteConfigAndObjectsToFile(config Config, configuredObjects ConfiguredObjects, filePathAndName string) error {
97+
98+
eximportConfig := &eximportConfig{
99+
Config: &config,
100+
ConfiguredObjects: &configuredObjects,
101+
}
102+
103+
data, err := toml.Marshal(eximportConfig)
104+
if err != nil {
105+
logError.Println(err)
106+
return err
107+
}
108+
109+
fmt.Printf("%s\n", data)
110+
111+
if filePathAndName[len(filePathAndName)-5:] != ".toml" {
112+
fmt.Println("Please save as .toml file")
113+
return errors.New("please save as .toml file")
114+
}
115+
116+
err = os.WriteFile(filepath.Join(filePathAndName), data, 0644)
117+
if err != nil {
118+
fmt.Println(err)
119+
return err
120+
}
121+
return nil
122+
}
123+
124+
func LoadConfigAndObjectsFromFile(filePathAndName string) (*Config, *Objects, error) {
125+
126+
eximportConfig := &eximportConfig{
127+
Config: &Config{},
128+
ConfiguredObjects: &ConfiguredObjects{},
129+
}
130+
131+
data, err := os.ReadFile(filePathAndName)
132+
if err != nil {
133+
return nil, nil, err
134+
}
135+
136+
err = toml.Unmarshal(data, eximportConfig)
137+
if err != nil {
138+
return nil, nil, err
139+
}
140+
141+
// fmt.Println(*eximportConfig.ConfiguredObjects)
142+
143+
objects := NewObjects()
144+
145+
err = objects.addObjectsFromList(*eximportConfig.ConfiguredObjects)
146+
if err != nil {
147+
return nil, nil, err
148+
}
149+
150+
return eximportConfig.Config, objects, nil
151+
}

config/config_client.toml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[Config]
2+
mode = 'client'
3+
ipv4Addr = '127.0.0.1'
4+
port = 2404
5+
casdu = 1
6+
autoAck = true
7+
k = 12
8+
w = 8
9+
t1 = 15
10+
t2 = 10
11+
t3 = 20
12+
ioaStructured = false
13+
interactiveMode = true
14+
useLocalTime = true
15+
logToBuffer = true
16+
logToStdOut = true
17+
18+
[ConfiguredObjects]
19+
monitoringList = [
20+
['sp1', '1', '5212'],
21+
['sp2', '1', '4242'],
22+
['sp3', '1', '3232'],
23+
['sp4', '1', '2252'],
24+
['sp5', '1', '1262'],
25+
['dp1', '3', '222'],
26+
['dp2', '3', '333'],
27+
['dp3', '3', '444'],
28+
['dp4', '3', '555'],
29+
]
30+
31+
controlList = [
32+
['sc1', '45', '666'],
33+
['sc2', '45', '777'],
34+
['sc3', '45', '888'],
35+
['dc1', '46', '4888'],
36+
['dc2', '46', '3888'],
37+
['dc3', '46', '2888'],
38+
['dc4', '46', '1888'],
39+
]

config/config_server.toml

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[Config]
2+
mode = 'server'
3+
ipv4Addr = '127.0.0.1'
4+
port = 2404
5+
casdu = 1
6+
autoAck = true
7+
k = 12
8+
w = 8
9+
t1 = 15
10+
t2 = 10
11+
t3 = 20
12+
ioaStructured = false
13+
interactiveMode = true
14+
useLocalTime = true
15+
logToBuffer = true
16+
logToStdOut = true
17+
18+
[ConfiguredObjects]
19+
monitoringList = [
20+
['sp1', '1', '5212'],
21+
['sp2', '1', '4242'],
22+
['sp3', '1', '3232'],
23+
['sp4', '1', '2252'],
24+
['sp5', '1', '1262'],
25+
['dp1', '3', '222'],
26+
['dp2', '3', '333'],
27+
['dp3', '3', '444'],
28+
['dp4', '3', '555'],
29+
]
30+
31+
controlList = [
32+
['sc1', '45', '666'],
33+
['sc2', '45', '777'],
34+
['sc3', '45', '888'],
35+
['dc1', '46', '4888'],
36+
['dc2', '46', '3888'],
37+
['dc3', '46', '2888'],
38+
['dc4', '46', '1888'],
39+
]

go.mod

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
module "github.com/viduq/vv104"
1+
module github.com/viduq/vv104
22

33
go 1.20
4+
5+
require github.com/pelletier/go-toml/v2 v2.1.1

go.sum

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
5+
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
6+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
7+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
8+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
9+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
10+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
11+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
12+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
13+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
14+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
15+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
16+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
17+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
18+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

logging.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ func initLogger(config Config) {
8484
// logError = log.New(output, "❌ ", log.Ltime|log.Lshortfile)
8585
// logInfo = log.New(output, "🥨 ", log.Ltime)
8686

87-
logDebug = log.New(vv104loggerDebug, "🪲 ", log.Ltime|log.Lshortfile)
88-
logError = log.New(vv104loggerError, " ", log.Ltime|log.Lshortfile)
89-
logInfo = log.New(vv104loggerInfo, "🥨 ", log.Ltime)
87+
logDebug = log.New(vv104loggerDebug, "Debug: ", log.Ltime|log.Lshortfile)
88+
logError = log.New(vv104loggerError, "ERROR: ", log.Ltime|log.Lshortfile)
89+
logInfo = log.New(vv104loggerInfo, "", log.Ltime)
9090

9191
}
9292

0 commit comments

Comments
 (0)