diff --git a/.gitignore b/.gitignore index fcf48e4..af696ad 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,10 @@ _testmain.go # Kelvin files dist +kelvin +config.json +config.yaml # macOS .DS_Store +.vscode diff --git a/configuration.go b/configuration.go index bc402e6..7b8c871 100644 --- a/configuration.go +++ b/configuration.go @@ -21,14 +21,18 @@ // SOFTWARE. package main -import "io/ioutil" -import "encoding/json" -import "os" -import "errors" -import "time" -import "fmt" -import "crypto/sha256" -import log "github.com/Sirupsen/logrus" +import ( + "crypto/sha256" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os" + "time" + + log "github.com/Sirupsen/logrus" + "github.com/ghodss/yaml" +) // Bridge respresents the hue bridge in your system. type Bridge struct { @@ -166,12 +170,20 @@ func (configuration *Configuration) Write() error { return nil } log.Debugf("⚙ Configuration changed. Saving to %v", configuration.ConfigurationFile) - json, err := json.MarshalIndent(configuration, "", " ") + raw, err := json.MarshalIndent(configuration, "", " ") if err != nil { return err } - err = ioutil.WriteFile(configuration.ConfigurationFile, json, 0644) + // Convert JSON to YAML if needed + if isYAMLFile(configuration.ConfigurationFile) { + raw, err = yaml.JSONToYAML(raw) + if err != nil { + return err + } + } + + err = ioutil.WriteFile(configuration.ConfigurationFile, raw, 0644) if err != nil { return err } @@ -192,6 +204,14 @@ func (configuration *Configuration) Read() error { return err } + // Convert YAML to JSON if needed + if isYAMLFile(configuration.ConfigurationFile) { + raw, err = yaml.YAMLToJSON(raw) + if err != nil { + return err + } + } + err = json.Unmarshal(raw, configuration) if err != nil { return err diff --git a/configuration_test.go b/configuration_test.go new file mode 100644 index 0000000..244a4d3 --- /dev/null +++ b/configuration_test.go @@ -0,0 +1,54 @@ +package main + +import ( + "testing" +) + +func TestReadOK(t *testing.T) { + correctfiles := []string{ + "testdata/config-example.json", + "testdata/config-example.yaml", + } + for _, testFile := range correctfiles { + c := Configuration{} + c.ConfigurationFile = testFile + err := c.Read() + if err != nil { + t.Fatalf("Could not read correct configuration file : %v with error : %v", c.ConfigurationFile, err) + } + } +} + +func TestReadError(t *testing.T) { + wrongfiles := []string{ + "", // no file passed + "testdata/", // not a regular file + "testdata/config-bad-wrongFormat.json", + "testdata/config-bad-wrongFormat.yaml", + } + for _, testFile := range wrongfiles { + c := Configuration{} + c.ConfigurationFile = testFile + err := c.Read() + if err == nil { + t.Errorf("reading [%v] file should return an error", c.ConfigurationFile) + } + } +} + +func TestWriteOK(t *testing.T) { + correctfiles := []string{ + "testdata/config-example.json", + "testdata/config-example.yaml", + } + for _, testFile := range correctfiles { + c := Configuration{} + c.ConfigurationFile = testFile + _ = c.Read() + c.Hash = "" + err := c.Write() + if err != nil { + t.Errorf("Could not write configuration to correct file : %v", c.ConfigurationFile) + } + } +} diff --git a/testdata/config-bad-wrongFormat.json b/testdata/config-bad-wrongFormat.json new file mode 100644 index 0000000..1d33123 --- /dev/null +++ b/testdata/config-bad-wrongFormat.json @@ -0,0 +1,50 @@ +zzzzzzzz{ + "version": 1, + "bridge": { + "ip": "192.168.10.37", + "username": "lbCDGagZZ7JEYQX5iGxrjMIx2jIROgpXfsSjHmCv" + }, + "location": { + "latitude": 53.5553, + "longitude": 9.995 + }, + "webinterface": { + "enabled": false, + "port": 8080 + }, + "schedules": [ + { + "name": "default", + "associatedDeviceIDs": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "enableWhenLightsAppear": true, + "defaultColorTemperature": 2750, + "defaultBrightness": 100, + "beforeSunrise": [ + { + "time": "4:00", + "colorTemperature": 2000, + "brightness": 60 + } + ], + "afterSunset": [ + { + "time": "20:00", + "colorTemperature": 2300, + "brightness": 80 + }, + { + "time": "22:00", + "colorTemperature": 2000, + "brightness": 60 + } + ] + } + ] +} diff --git a/testdata/config-bad-wrongFormat.yaml b/testdata/config-bad-wrongFormat.yaml new file mode 100644 index 0000000..9306aef --- /dev/null +++ b/testdata/config-bad-wrongFormat.yaml @@ -0,0 +1,34 @@ +[][]dqiwdijqwd +bridge: + ip: 192.168.10.37 + username: lbCDGagZZ7JEYQX5iGxrjMIx2jIROgpXfsSjHmCv +location: + latitude: 53.5553 + longitude: 9.995 +schedules: +- afterSunset: + - brightness: 80 + colorTemperature: 2300 + time: "20:00" + - brightness: 60 + colorTemperature: 2000 + time: "22:00" + associatedDeviceIDs: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + beforeSunrise: + - brightness: 60 + colorTemperature: 2000 + time: "4:00" + defaultBrightness: 100 + defaultColorTemperature: 2750 + enableWhenLightsAppear: true + name: default +version: 1 +webinterface: + enabled: false + port: 8080 diff --git a/testdata/config-example.json b/testdata/config-example.json new file mode 100644 index 0000000..93fe560 --- /dev/null +++ b/testdata/config-example.json @@ -0,0 +1,50 @@ +{ + "version": 1, + "bridge": { + "ip": "192.168.10.37", + "username": "lbCDGagZZ7JEYQX5iGxrjMIx2jIROgpXfsSjHmCv" + }, + "location": { + "latitude": 53.5553, + "longitude": 9.995 + }, + "webinterface": { + "enabled": false, + "port": 8080 + }, + "schedules": [ + { + "name": "default", + "associatedDeviceIDs": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "enableWhenLightsAppear": true, + "defaultColorTemperature": 2750, + "defaultBrightness": 100, + "beforeSunrise": [ + { + "time": "4:00", + "colorTemperature": 2000, + "brightness": 60 + } + ], + "afterSunset": [ + { + "time": "20:00", + "colorTemperature": 2300, + "brightness": 80 + }, + { + "time": "22:00", + "colorTemperature": 2000, + "brightness": 60 + } + ] + } + ] +} \ No newline at end of file diff --git a/testdata/config-example.yaml b/testdata/config-example.yaml new file mode 100644 index 0000000..55fcea4 --- /dev/null +++ b/testdata/config-example.yaml @@ -0,0 +1,33 @@ +bridge: + ip: 192.168.10.37 + username: lbCDGagZZ7JEYQX5iGxrjMIx2jIROgpXfsSjHmCv +location: + latitude: 53.5553 + longitude: 9.995 +schedules: +- afterSunset: + - brightness: 80 + colorTemperature: 2300 + time: "20:00" + - brightness: 60 + colorTemperature: 2000 + time: "22:00" + associatedDeviceIDs: + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + beforeSunrise: + - brightness: 60 + colorTemperature: 2000 + time: "4:00" + defaultBrightness: 100 + defaultColorTemperature: 2750 + enableWhenLightsAppear: true + name: default +version: 1 +webinterface: + enabled: false + port: 8080 diff --git a/util.go b/util.go index 1418795..0aa3478 100644 --- a/util.go +++ b/util.go @@ -130,3 +130,11 @@ func durationUntilNextDay() time.Duration { endOfDay = endOfDay.Add(1 * time.Second) return time.Until(endOfDay) } + +func isYAMLFile(filename string) bool { + fileExt := filepath.Ext(filename) + if fileExt == ".yaml" || fileExt == ".yml" { + return true + } + return false +}