-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
139 lines (124 loc) · 3.84 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/rs/zerolog/log"
"gopkg.in/yaml.v3"
)
const (
CONFIG_FILE = "mqtt-timer.yml"
CONFIG_DIR = ".config"
CONFIG_ROOT = "/config"
)
type Mqtt struct {
Url string `yaml:"url"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Qos int `yaml:"qos"`
Retain bool `yaml:"retain"`
}
type Timer struct {
Id string `yaml:"id"`
Description string `yaml:"description"`
Cron string `yaml:"cron"`
Time string `yaml:"time"`
Days string `yaml:"days"`
Before string `yaml:"before"`
After string `yaml:"after"`
RandomBefore string `yaml:"randomBefore"`
RandomAfter string `yaml:"randomAfter"`
Topic string `yaml:"topic"`
Message string `yaml:"message"`
Enabled *bool `yaml:"enabled,omitempty"`
Active bool
}
type Config struct {
Latitude float64 `yaml:"latitude"`
Longitude float64 `yaml:"longitude"`
Mqtt Mqtt `yaml:"mqtt"`
Timers []Timer `yaml:"timers"`
}
func getConfig() Config {
var config Config
configFile := filepath.Join(CONFIG_ROOT, CONFIG_FILE)
msg := configFile
data, err := os.ReadFile(configFile)
if err != nil {
homedir, _ := os.UserHomeDir()
configFile := filepath.Join(homedir, CONFIG_DIR, CONFIG_FILE)
msg += ", " + configFile
data, err = os.ReadFile(configFile)
}
if err != nil {
workingdir, _ := os.Getwd()
configFile := filepath.Join(workingdir, CONFIG_FILE)
msg += ", " + configFile
data, err = os.ReadFile(configFile)
}
if err != nil {
msg = "Configuration file could not be found: " + msg
log.Fatal().Msg(msg)
}
err = yaml.Unmarshal(data, &config)
if err != nil {
log.Fatal().Err(err).Msg("unmarshal")
}
for i := 0; i < len(config.Timers); i++ {
if config.Timers[i].Enabled != nil {
config.Timers[i].Active = *config.Timers[i].Enabled
} else {
config.Timers[i].Active = true
}
}
err = validate(config)
if err != nil {
log.Fatal().Err(err).Msg("validate")
}
// log.Printf("%+v\n", config)
return config
}
func validate(config Config) error {
if config.Mqtt.Url == "" {
return errors.New("Config error: MQTT Server URL is mandatory")
}
for _, timer := range config.Timers {
if timer.Id == "" {
return errors.New("Config error: timer.id is mandatory")
}
if timer.Cron == "" && timer.Time == "" {
return fmt.Errorf("Config error: timer.cron or timer.time is mandatory (timer %s)", timer.Id)
}
if timer.Cron != "" && timer.Time != "" {
return fmt.Errorf("Config error: use only timer.cron or timer.time (timer %s)", timer.Id)
}
if timer.Cron != "" && timer.Before != "" {
return fmt.Errorf("Config error: timer.before cannot be used with cron (timer %s)", timer.Id)
}
if timer.Cron != "" && timer.RandomBefore != "" {
return fmt.Errorf("Config error: timer.randomBefore cannot be used with cron (timer %s)", timer.Id)
}
if timer.Before != "" {
if timer.RandomBefore != "" || timer.After != "" || timer.RandomAfter != "" {
return fmt.Errorf("Config error: only one of before, randomBefore, after or randomAfter can be used (timer %s)", timer.Id)
}
}
if timer.RandomBefore != "" {
if timer.Before != "" || timer.After != "" || timer.RandomAfter != "" {
return fmt.Errorf("Config error: only one of before,randomBefore, after or randomAfter can be used (timer %s)", timer.Id)
}
}
if timer.After != "" {
if timer.Before != "" || timer.RandomBefore != "" || timer.RandomAfter != "" {
return fmt.Errorf("Config error: only one of before, randomBefore, after or randomAfter can be used (timer %s)", timer.Id)
}
}
if timer.RandomAfter != "" {
if timer.Before != "" || timer.RandomBefore != "" || timer.After != "" {
return fmt.Errorf("Config error: only one of before, randomBefore, after or randomAfter can be used (timer %s)", timer.Id)
}
}
}
return nil
}