Skip to content

Commit 5d883bf

Browse files
committed
mqtt-gateway v0.3.1
1 parent 08105cb commit 5d883bf

File tree

3 files changed

+102
-76
lines changed

3 files changed

+102
-76
lines changed

cmd/gateway/config.go

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,33 @@ import (
1616
var jamlExts = []string{".yaml", ".yml"}
1717

1818
type configSet struct {
19+
logger *log.Logger
1920
csConfigMap map[string]*gateway.CSConfig
2021
locoConfigMap map[string]*gateway.LocoConfig
22+
csList []*gateway.CS
2123
}
2224

23-
func newConfigSet() *configSet {
25+
func newConfigSet(logger *log.Logger) *configSet {
26+
if logger == nil {
27+
logger = log.New(io.Discard, "", 0) // dev/null
28+
}
2429
return &configSet{
30+
logger: logger,
2531
csConfigMap: map[string]*gateway.CSConfig{},
2632
locoConfigMap: map[string]*gateway.LocoConfig{},
2733
}
2834
}
2935

36+
func (c *configSet) close() error {
37+
var lastErr error
38+
for _, cs := range c.csList {
39+
if err := cs.Close(); err != nil {
40+
lastErr = err
41+
}
42+
}
43+
return lastErr
44+
}
45+
3046
func isCSConfig(m map[string]any) bool {
3147
if _, ok := m["host"]; ok {
3248
return true
@@ -93,22 +109,58 @@ func (c *configSet) load(fsys fs.FS, path string) error {
93109
}
94110

95111
if !slices.Contains(jamlExts, filepath.Ext(d.Name())) {
96-
log.Printf("...skipped %s", subPath)
112+
c.logger.Printf("...skipped %s", subPath)
97113
return nil
98114
}
99115

100116
b, err := fs.ReadFile(fsys, subPath)
101117
if err != nil {
102-
log.Printf("...%s %s", subPath, err)
118+
c.logger.Printf("...%s %s", subPath, err)
103119
return err
104120
}
105121

106122
if err = c.parseYaml(b); err != nil {
107-
log.Printf("...error loading %s: %s", subPath, err)
123+
c.logger.Printf("...error loading %s: %s", subPath, err)
108124
return err
109125
}
110126

111-
log.Printf("...loaded %s", subPath)
127+
c.logger.Printf("...loaded %s", subPath)
112128
return nil
113129
})
114130
}
131+
132+
func (c *configSet) register(gw *gateway.Gateway) error {
133+
locoMap := map[string]string{}
134+
135+
for csName, csConfig := range c.csConfigMap {
136+
c.logger.Printf("register central station %s", csName)
137+
cs, err := gateway.NewCS(csConfig, gw)
138+
if err != nil {
139+
return err
140+
}
141+
c.csList = append(c.csList, cs)
142+
143+
for locoName, locoConfig := range c.locoConfigMap {
144+
145+
csAssignedName, ok := locoMap[locoName]
146+
147+
controlsLoco, err := cs.AddLoco(locoConfig)
148+
if err != nil {
149+
return err
150+
}
151+
152+
if controlsLoco && ok {
153+
return fmt.Errorf("loco %s is controlled by more than one central station %s, %s", locoName, csName, csAssignedName)
154+
}
155+
156+
locoMap[locoName] = csName
157+
158+
if controlsLoco {
159+
c.logger.Printf("added loco %s controlled by central station %s", locoConfig.Name, csConfig.Name)
160+
} else {
161+
c.logger.Printf("added loco %s to central station %s", locoConfig.Name, csConfig.Name)
162+
}
163+
}
164+
}
165+
return nil
166+
}

cmd/gateway/config_test.go

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,53 @@ import (
99
)
1010

1111
func testLoad(t *testing.T) {
12-
cmpConfigSet := &configSet{
13-
csConfigMap: map[string]*gateway.CSConfig{
14-
"cs01": {
15-
Name: "cs01",
16-
Port: "/dev/ttyACM0",
17-
Incls: []string{".*"},
18-
Excls: []string{"br18"},
19-
},
20-
"cs02": {
21-
Name: "cs02",
22-
Host: "localhost",
23-
Port: "4242",
24-
Incls: []string{"br18"},
25-
},
12+
cmpCSConfigMap := map[string]*gateway.CSConfig{
13+
"cs01": {
14+
Name: "cs01",
15+
Port: "/dev/ttyACM0",
16+
Incls: []string{".*"},
17+
Excls: []string{"br18"},
2618
},
27-
locoConfigMap: map[string]*gateway.LocoConfig{
28-
"br01": {
29-
Name: "br01",
30-
Addr: 1,
31-
Fcts: map[string]gateway.LocoFctConfig{
32-
"light": {No: 0},
33-
"horn": {No: 5},
34-
},
19+
"cs02": {
20+
Name: "cs02",
21+
Host: "localhost",
22+
Port: "4242",
23+
Incls: []string{"br18"},
24+
},
25+
}
26+
cmpLocoConfigMap := map[string]*gateway.LocoConfig{
27+
"br01": {
28+
Name: "br01",
29+
Addr: 1,
30+
Fcts: map[string]gateway.LocoFctConfig{
31+
"light": {No: 0},
32+
"horn": {No: 5},
3533
},
36-
"br18": {
37-
Name: "br18",
38-
Addr: 18,
39-
Fcts: map[string]gateway.LocoFctConfig{
40-
"light": {No: 0},
41-
"bell": {No: 5},
42-
"whistle": {No: 8},
43-
},
34+
},
35+
"br18": {
36+
Name: "br18",
37+
Addr: 18,
38+
Fcts: map[string]gateway.LocoFctConfig{
39+
"light": {No: 0},
40+
"bell": {No: 5},
41+
"whistle": {No: 8},
4442
},
4543
},
4644
}
4745

48-
configSet := newConfigSet()
46+
configSet := newConfigSet(nil)
4947
externFsys := os.DirFS("config_examples")
5048
if err := configSet.load(externFsys, "."); err != nil {
5149
t.Fatal(err)
5250
}
5351

5452
// compare
55-
if !reflect.DeepEqual(configSet, cmpConfigSet) {
56-
t.Fatalf("invalid config set %v - expected %v", configSet, cmpConfigSet)
53+
if !reflect.DeepEqual(configSet.csConfigMap, cmpCSConfigMap) {
54+
t.Fatalf("invalid cs config map %v - expected %v", configSet.csConfigMap, cmpCSConfigMap)
55+
}
56+
if !reflect.DeepEqual(configSet.locoConfigMap, cmpLocoConfigMap) {
57+
t.Fatalf("invalid loco config map %v - expected %v", configSet.locoConfigMap, cmpLocoConfigMap)
5758
}
58-
5959
}
6060

6161
func TestConfig(t *testing.T) {

cmd/gateway/gateway.go

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ func lookupEnv(name, defVal string) string {
3535

3636
func main() {
3737

38+
logger := log.New(os.Stderr, "gateway", log.LstdFlags)
39+
3840
config := &gateway.Config{}
39-
configSet := newConfigSet()
41+
configSet := newConfigSet(logger)
42+
defer configSet.close()
4043

4144
flag.StringVar(&config.TopicRoot, "topicRoot", lookupEnv(envTopicRoot, gateway.DefaultTopicRoot), "topic root")
4245
flag.StringVar(&config.Host, "host", lookupEnv(envHost, gateway.DefaultHost), "MQTT host")
@@ -48,56 +51,27 @@ func main() {
4851

4952
flag.Parse()
5053

51-
log.Printf("load embedded configuration files")
54+
logger.Printf("load embedded configuration files")
5255
if err := configSet.load(embedFsys, embedConfigDir); err != nil {
53-
os.Exit(1)
56+
logger.Fatal(err)
5457
}
5558

5659
if *externConfigDir != "" {
57-
log.Printf("load external configuration files at %s", *externConfigDir)
60+
logger.Printf("load external configuration files at %s", *externConfigDir)
5861
externFsys := os.DirFS(*externConfigDir)
5962
if err := configSet.load(externFsys, "."); err != nil {
60-
os.Exit(1)
63+
logger.Fatal(err)
6164
}
6265
}
6366

6467
gw, err := gateway.New(config)
6568
if err != nil {
66-
log.Fatal(err)
69+
logger.Fatal(err)
6770
}
6871
defer gw.Close()
6972

70-
locoMap := map[string]string{}
71-
72-
for csName, csConfig := range configSet.csConfigMap {
73-
log.Printf("register central station %s", csName)
74-
cs, err := gateway.NewCS(csConfig, gw)
75-
if err != nil {
76-
log.Fatal(err)
77-
}
78-
defer cs.Close()
79-
80-
for locoName, locoConfig := range configSet.locoConfigMap {
81-
82-
csAssignedName, ok := locoMap[locoName]
83-
84-
controlsLoco, err := cs.AddLoco(locoConfig)
85-
if err != nil {
86-
log.Fatal(err)
87-
}
88-
89-
if controlsLoco && ok {
90-
log.Fatalf("loco %s is controlled by more than one central station %s, %s", locoName, csName, csAssignedName)
91-
}
92-
93-
locoMap[locoName] = csName
94-
95-
if controlsLoco {
96-
log.Printf("added loco %s controlled by central station %s", locoConfig.Name, csConfig.Name)
97-
} else {
98-
log.Printf("added loco %s to central station %s", locoConfig.Name, csConfig.Name)
99-
}
100-
}
73+
if err := configSet.register(gw); err != nil {
74+
logger.Fatal(err)
10175
}
10276

10377
sig := make(chan os.Signal, 1)

0 commit comments

Comments
 (0)