diff --git a/cmd/cmd.go b/cmd/cmd.go index 2cbd099..8feec6d 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -5,11 +5,8 @@ import ( "os" "time" - lg "github.com/volker-raschek/flucky/cmd/logger" - "github.com/volker-raschek/flucky/cmd/remote" "github.com/volker-raschek/flucky/cmd/sensor" "github.com/volker-raschek/flucky/cmd/temperature" - "github.com/volker-raschek/flucky/pkg/logger" "github.com/volker-raschek/flucky/pkg/types" uuid "github.com/satori/go.uuid" @@ -17,7 +14,7 @@ import ( "github.com/volker-raschek/flucky/pkg/config" ) -var cfg string +var configPath string var rootCmd = &cobra.Command{ Use: "flucky", @@ -25,28 +22,21 @@ var rootCmd = &cobra.Command{ PersistentPreRunE: func(cmd *cobra.Command, args []string) error { // check if config file exists - if _, err := os.Stat(cfg); os.IsNotExist(err) { + if _, err := os.Stat(configPath); os.IsNotExist(err) { hostname, err := os.Hostname() if err != nil { return fmt.Errorf("Can not locate the hostname: %v", err) } - logfiles := make(map[logger.LogValue][]string) - logfiles[logger.LogHumidity] = []string{"/var/log/flucky/humidity.json"} - logfiles[logger.LogTemperature] = []string{"/var/log/flucky/temperature.json"} - - fc := config.FluckyConfig{ + cnf := config.Configuration{ Device: &types.Device{ DeviceID: uuid.NewV4().String(), DeviceName: hostname, CreationDate: time.Now(), }, - FileLogger: &logger.FileLogger{ - LogFiles: logfiles, - }, } - err = config.Write(&fc, cfg) + err = config.Write(&cnf, configPath) if err != nil { return err } @@ -60,13 +50,9 @@ var rootCmd = &cobra.Command{ func Execute(version string) { rootCmd.Version = version - rootCmd.PersistentFlags().StringVar(&cfg, "config", "/etc/flucky/config.json", "Config file") - - lg.InitCmd(rootCmd, cfg) + rootCmd.PersistentFlags().StringVar(&configPath, "config", "/etc/flucky/config.json", "Config file") // humidity.InitCmd(rootCmd, configDir) - remote.InitCmd(rootCmd, cfg) - sensor.InitCmd(rootCmd, cfg) - temperature.InitCmd(rootCmd, cfg) - + sensor.InitCmd(rootCmd, configPath) + temperature.InitCmd(rootCmd, configPath) rootCmd.Execute() } diff --git a/cmd/daemon/daemon.go b/cmd/daemon/daemon.go new file mode 100644 index 0000000..c2253fa --- /dev/null +++ b/cmd/daemon/daemon.go @@ -0,0 +1,22 @@ +package daemon + +import ( + "github.com/spf13/cobra" +) + +var configDir string + +var daemonCmd = &cobra.Command{ + Use: "daemon", + Short: "Read continuously data from all enabled sensors", + Run: func(cmd *cobra.Command, args []string) { + + }, +} + +func InitCmd(cmd *cobra.Command, cnf string) { + configDir = cnf + + cmd.AddCommand(daemonCmd) + +} diff --git a/cmd/logger/add.go b/cmd/logger/add.go deleted file mode 100644 index 64aefa9..0000000 --- a/cmd/logger/add.go +++ /dev/null @@ -1,54 +0,0 @@ -package logger - -import ( - "log" - - "github.com/volker-raschek/flucky/pkg/logger" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var enabled bool - -var addLoggerCmd = &cobra.Command{ - Use: "add", - Short: "Add internal logger", - Args: cobra.ExactArgs(2), - Aliases: []string{"append"}, - Example: "flucky logger add temperature /var/log/flucky/temperature.log", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // loggertype, err := logger.StringToLoggerType(args[0]) - // if err != nil { - // log.Fatalln(err) - // } - - logvalue, err := logger.StringToLogValue(args[0]) - if err != nil { - log.Fatalln(err) - } - - err = fc.AddLogFile(args[1], logvalue) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - - }, -} - -func init() { - loggerCmd.AddCommand(addLoggerCmd) -} diff --git a/cmd/logger/list.go b/cmd/logger/list.go deleted file mode 100644 index 8c867d0..0000000 --- a/cmd/logger/list.go +++ /dev/null @@ -1,40 +0,0 @@ -package logger - -import ( - "log" - "os" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/cli" - "github.com/volker-raschek/flucky/pkg/config" -) - -var quiet bool - -var listLoggerCmd = &cobra.Command{ - Use: "ls", - Short: "List internal Loggers", - Aliases: []string{"list"}, - Example: "flucky logger ls", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // print all configured remote addresses on stdout - cli.PrintLoggers(fc, os.Stdout) - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - }, -} - -func init() { - loggerCmd.AddCommand(listLoggerCmd) -} diff --git a/cmd/logger/logger.go b/cmd/logger/logger.go deleted file mode 100644 index e422882..0000000 --- a/cmd/logger/logger.go +++ /dev/null @@ -1,18 +0,0 @@ -package logger - -import ( - "github.com/spf13/cobra" -) - -var cfg string - -var loggerCmd = &cobra.Command{ - Use: "logger", - Short: "Manage internal logger", -} - -func InitCmd(cmd *cobra.Command, config string) { - cfg = config - - cmd.AddCommand(loggerCmd) -} diff --git a/cmd/logger/rm.go b/cmd/logger/rm.go deleted file mode 100644 index 7b24ec2..0000000 --- a/cmd/logger/rm.go +++ /dev/null @@ -1,40 +0,0 @@ -package logger - -import ( - "log" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var rmLoggerCmd = &cobra.Command{ - Use: "rm", - Short: "Remove internal logger", - Args: cobra.ExactArgs(1), - Aliases: []string{"remove"}, - Example: "flucky logger rm /var/log/flucky/temperature.log", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - err = fc.RemoveLogFile(args[0]) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - - }, -} - -func init() { - loggerCmd.AddCommand(rmLoggerCmd) -} diff --git a/cmd/remote/add.go b/cmd/remote/add.go deleted file mode 100644 index 969cfc8..0000000 --- a/cmd/remote/add.go +++ /dev/null @@ -1,51 +0,0 @@ -package remote - -import ( - "log" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var enabled bool - -var addRemoteCmd = &cobra.Command{ - Use: "add", - Short: "Add Remote Server", - Args: cobra.ExactArgs(2), - Aliases: []string{"append"}, - Example: "flucky remote add origin https://example.local", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // create new remote struct - remote := config.Remote{ - Name: args[0], - Address: args[1], - Enabled: enabled, - } - - // // add remote entry to list - err = fc.AddRemote(&remote) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - - }, -} - -func init() { - remoteCmd.AddCommand(addRemoteCmd) - addRemoteCmd.Flags().BoolVarP(&enabled, "enable", "e", true, "Enable") -} diff --git a/cmd/remote/disable.go b/cmd/remote/disable.go deleted file mode 100644 index 20ef5c6..0000000 --- a/cmd/remote/disable.go +++ /dev/null @@ -1,40 +0,0 @@ -package remote - -import ( - "log" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var disableRemoteCmd = &cobra.Command{ - Use: "disable", - Short: "Disable Remove Server", - Args: cobra.ExactArgs(1), - Example: "flucky remote disable origin", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // disnable remote address - err = fc.DisableRemote(args[0]) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - - }, -} - -func init() { - remoteCmd.AddCommand(disableRemoteCmd) -} diff --git a/cmd/remote/enable.go b/cmd/remote/enable.go deleted file mode 100644 index 7d3525b..0000000 --- a/cmd/remote/enable.go +++ /dev/null @@ -1,39 +0,0 @@ -package remote - -import ( - "log" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var enableRemoteCmd = &cobra.Command{ - Use: "enable", - Short: "Enable Remove Server", - Args: cobra.ExactArgs(1), - Example: "flucky remote enable origin", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // enable remote address - err = fc.EnableRemote(args[0]) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - }, -} - -func init() { - remoteCmd.AddCommand(enableRemoteCmd) -} diff --git a/cmd/remote/list.go b/cmd/remote/list.go deleted file mode 100644 index 0bb6db9..0000000 --- a/cmd/remote/list.go +++ /dev/null @@ -1,43 +0,0 @@ -package remote - -import ( - "log" - "os" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/cli" - "github.com/volker-raschek/flucky/pkg/config" -) - -var quiet bool - -var listRemoteCmd = &cobra.Command{ - Use: "ls", - Short: "List Remove Servers", - Aliases: []string{"list"}, - Example: "flucky remote ls", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // print all configured remote addresses on stdout - err = cli.PrintRemotes(fc, os.Stdout) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - }, -} - -func init() { - remoteCmd.AddCommand(listRemoteCmd) -} diff --git a/cmd/remote/remote.go b/cmd/remote/remote.go deleted file mode 100644 index 1729408..0000000 --- a/cmd/remote/remote.go +++ /dev/null @@ -1,18 +0,0 @@ -package remote - -import ( - "github.com/spf13/cobra" -) - -var cfg string - -var remoteCmd = &cobra.Command{ - Use: "remote", - Short: "Manage Remote Server", -} - -func InitCmd(cmd *cobra.Command, config string) { - cfg = config - - cmd.AddCommand(remoteCmd) -} diff --git a/cmd/remote/remove.go b/cmd/remote/remove.go deleted file mode 100644 index 9d88cdf..0000000 --- a/cmd/remote/remove.go +++ /dev/null @@ -1,40 +0,0 @@ -package remote - -import ( - "log" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var rmRemoteCmd = &cobra.Command{ - Use: "rm", - Short: "Remove Remote Server", - Aliases: []string{"remove"}, - Args: cobra.ExactArgs(1), - Example: "flucky remote rm origin", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // add remote entry to list - err = fc.RemoveRemote(args[0]) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - }, -} - -func init() { - remoteCmd.AddCommand(rmRemoteCmd) -} diff --git a/cmd/remote/rename.go b/cmd/remote/rename.go deleted file mode 100644 index d8351f4..0000000 --- a/cmd/remote/rename.go +++ /dev/null @@ -1,40 +0,0 @@ -package remote - -import ( - "log" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/config" -) - -var renameRemoteCmd = &cobra.Command{ - Use: "rename", - Short: "Rename Remote Server", - Args: cobra.ExactArgs(2), - Example: "flucky remote rename origin slave", - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - // rename remote address - err = fc.RenameRemote(args[0], args[1]) - if err != nil { - log.Fatalln(err) - } - - // save new configuration - err = config.Write(fc, cfg) - if err != nil { - log.Fatalln(err) - } - - }, -} - -func init() { - remoteCmd.AddCommand(renameRemoteCmd) -} diff --git a/cmd/temperature/list.go b/cmd/temperature/list.go new file mode 100644 index 0000000..b2de2e2 --- /dev/null +++ b/cmd/temperature/list.go @@ -0,0 +1,28 @@ +package temperature + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var listTemperatureCmd = &cobra.Command{ + Use: "list", + Short: "print temperatures", + Example: fmt.Sprintf("flucky temperature logs"), + Run: func(cmd *cobra.Command, args []string) { + + // read configuration + // fc, err := config.Read(cnfPath) + // if err != nil { + // list.Fatalln(err) + // } + + //cli.PrintTemperatures(temperatures, fc, os.Stdout) + + }, +} + +func init() { + temperatureCmd.AddCommand(listTemperatureCmd) +} diff --git a/cmd/temperature/log.go b/cmd/temperature/log.go deleted file mode 100644 index 34b6a70..0000000 --- a/cmd/temperature/log.go +++ /dev/null @@ -1,37 +0,0 @@ -package temperature - -import ( - "fmt" - "log" - "os" - - "github.com/spf13/cobra" - "github.com/volker-raschek/flucky/pkg/cli" - "github.com/volker-raschek/flucky/pkg/config" -) - -var logTemperatureCmd = &cobra.Command{ - Use: "log", - Short: "print temperature logs", - Example: fmt.Sprintf("flucky temperature logs"), - Run: func(cmd *cobra.Command, args []string) { - - // read configuration - fc, err := config.Read(cfg) - if err != nil { - log.Fatalln(err) - } - - temperatures, err := fc.FileLogger.GetTemperatures(nil, nil, args) - if err != nil { - log.Fatalln(err) - } - - cli.PrintTemperatures(temperatures, fc, os.Stdout) - - }, -} - -func init() { - temperatureCmd.AddCommand(logTemperatureCmd) -} diff --git a/cmd/temperature/push.go b/cmd/temperature/push.go deleted file mode 100644 index 80680bb..0000000 --- a/cmd/temperature/push.go +++ /dev/null @@ -1,22 +0,0 @@ -package temperature - -// import ( -// "log" - -// "github.com/spf13/cobra" -// ) - -// var pushTemperatureCmd = &cobra.Command{ -// Use: "push", -// Short: "push temperature from sensor to remote servers", -// Run: func(cmd *cobra.Command, args []string) { - -// if err := temperature.Push(configDir); err != nil { -// log.Fatal(err) -// } -// }, -// } - -// func init() { -// temperatureCmd.AddCommand(pushTemperatureCmd) -// } diff --git a/cmd/temperature/read.go b/cmd/temperature/read.go index c8587af..4c2ef5d 100644 --- a/cmd/temperature/read.go +++ b/cmd/temperature/read.go @@ -20,16 +20,13 @@ var readTemperatureCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { // read configuration - fc, err := config.Read(cfg) + cnf, err := config.Read(cnfPath) if err != nil { log.Fatalln(err) } // fetch all temperature sensors - temperatureSensors, err := fc.GetTemperatureSensors(args) - if err != nil { - log.Fatalln(err) - } + temperatureSensors := cnf.GetTemperatureSensors() // read temperature from sensors temperatures, err := sensor.ReadTemperatures(temperatureSensors) @@ -38,14 +35,7 @@ var readTemperatureCmd = &cobra.Command{ } // print temperatures on stdout - cli.PrintTemperatures(temperatures, fc, os.Stdout) - - if logs { - err = fc.FileLogger.LogTemperatures(temperatures) - if err != nil { - log.Fatalln(err) - } - } + cli.PrintTemperatures(temperatures, cnf, os.Stdout) }, } diff --git a/cmd/temperature/temperature.go b/cmd/temperature/temperature.go index 30baea7..ce9b373 100644 --- a/cmd/temperature/temperature.go +++ b/cmd/temperature/temperature.go @@ -6,7 +6,7 @@ import ( "github.com/spf13/cobra" ) -var cfg string +var cnfPath string var temperatureCmd = &cobra.Command{ Use: "temperature", @@ -15,8 +15,8 @@ var temperatureCmd = &cobra.Command{ } // Execute a -func InitCmd(cmd *cobra.Command, config string) { - cfg = config +func InitCmd(cmd *cobra.Command, configPath string) { + cnfPath = configPath cmd.AddCommand(temperatureCmd) diff --git a/go.mod b/go.mod index 257ca1e..421d415 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,10 @@ require ( github.com/satori/go.uuid v1.2.0 github.com/spf13/cobra v0.0.3 github.com/spf13/pflag v1.0.3 // indirect + github.com/vishvananda/netlink v1.0.0 + github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect + github.com/volker-raschek/go-dht v0.1.0 github.com/yryz/ds18b20 v0.0.0-20180211073435-3cf383a40624 + golang.org/x/sys v0.0.0-20190613124609-5ed2794edfdc // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect - periph.io/x/periph v3.4.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index 4baebcf..08cba13 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,15 @@ github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= +github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc h1:R83G5ikgLMxrBvLh22JhdfI8K6YXEPHx5P03Uu3DRs4= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/volker-raschek/go-dht v0.1.0/go.mod h1:Fjv93K0m5sjdN/0ls8EeB4blawrEQVpda8HfSobPet4= github.com/yryz/ds18b20 v0.0.0-20180211073435-3cf383a40624 h1:bePzgtpuLSl+F9aacwuaquuoOyKfMKuJORq2CvPPJK4= github.com/yryz/ds18b20 v0.0.0-20180211073435-3cf383a40624/go.mod h1:MqFju5qeLDFh+S9PqxYT7TEla8xeW7bgGr/69q3oki0= +golang.org/x/sys v0.0.0-20190613124609-5ed2794edfdc h1:x+/QxSNkVFAC+v4pL1f6mZr1z+qgi+FoR8ccXZPVC10= +golang.org/x/sys v0.0.0-20190613124609-5ed2794edfdc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= periph.io/x/periph v3.4.0+incompatible h1:5gzxE4ryPq52cdqSw0mErR6pyJK8cBF2qdUAcOWh0bo= diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go index a259386..2fc7428 100644 --- a/pkg/cli/cli.go +++ b/pkg/cli/cli.go @@ -5,16 +5,13 @@ import ( "io" "text/tabwriter" - "github.com/volker-raschek/flucky/pkg/logger" - - "github.com/volker-raschek/flucky/pkg/internal/temperature" - "github.com/volker-raschek/flucky/pkg/config" + "github.com/volker-raschek/flucky/pkg/internal/temperature" "github.com/volker-raschek/flucky/pkg/types" ) // PrintHumidities displays a list of humidities -func PrintHumidities(humidities []*types.Humidity, cnf *config.FluckyConfig, w io.Writer) { +func PrintHumidities(humidities []*types.Humidity, cnf *config.Configuration, w io.Writer) { // determine all humidity sensors based on the humidiy values sensors := []*types.Sensor{} for _, humidity := range humidities { @@ -71,37 +68,8 @@ func PrintHumidities(humidities []*types.Humidity, cnf *config.FluckyConfig, w i tw.Flush() } -func PrintLoggers(cnf *config.FluckyConfig, w io.Writer) { - // declare tabwriter - tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) - - fmt.Fprintf(w, "type\tvalue\t\tlocation\n") - - for _, logfile := range cnf.LogFiles[logger.LogTemperature] { - fmt.Fprintf(w, "file\t%v\t%v\n", logger.LogTemperature, logfile) - } - - tw.Flush() -} - -// PrintRemotes displays a list with all configured remote addresses -func PrintRemotes(cnf *config.FluckyConfig, w io.Writer) error { - - tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) - - fmt.Fprint(tw, "name\taddress\tenabled\tregistered\n") - - for _, remote := range cnf.Remotes { - fmt.Fprintf(tw, "%v\t%v\t%v\t%v\n", remote.Name, remote.Address, remote.Enabled, remote.Registered) - } - - tw.Flush() - - return nil -} - // PrintSensors displays a list with all configured sensors -func PrintSensors(cnf *config.FluckyConfig, w io.Writer) error { +func PrintSensors(cnf *config.Configuration, w io.Writer) error { // declar tabwriter tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) @@ -118,7 +86,7 @@ func PrintSensors(cnf *config.FluckyConfig, w io.Writer) error { } // PrintTemperatures displays a list of temperatures -func PrintTemperatures(temperatures []*types.Temperature, cnf *config.FluckyConfig, w io.Writer) { +func PrintTemperatures(temperatures []*types.Temperature, cnf *config.Configuration, w io.Writer) { sensors := temperature.GetSensorsByTemperatures(temperatures, cnf) diff --git a/pkg/config/config.go b/pkg/config/config.go index 403e526..00cd42b 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,6 +1,7 @@ package config import ( + "encoding/json" "fmt" "os" "path/filepath" @@ -10,9 +11,9 @@ import ( var validUUID = regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") // Read the configuration file -func Read(configFile string) (*FluckyConfig, error) { +func Read(configFile string) (*Configuration, error) { - fc := &FluckyConfig{} + fc := &Configuration{} f, err := os.Open(configFile) if err != nil { @@ -20,9 +21,9 @@ func Read(configFile string) (*FluckyConfig, error) { } defer f.Close() - err = fc.JSONDecoder(f) - if err != nil { - return nil, fmt.Errorf("Can not decode json file %v: %v", configFile, err) + jsonDecoder := json.NewDecoder(f) + if err := jsonDecoder.Decode(&fc); err != nil { + return nil, fmt.Errorf("Can not unmarshal JSON: %v", err) } return fc, nil @@ -30,7 +31,7 @@ func Read(configFile string) (*FluckyConfig, error) { } // Write the configuration into a file, specified by the configuration filepath -func Write(cfg *FluckyConfig, configFile string) error { +func Write(cfg *Configuration, configFile string) error { if _, err := os.Stat(configFile); os.IsNotExist(err) { configDir := filepath.Dir(configFile) @@ -46,9 +47,11 @@ func Write(cfg *FluckyConfig, configFile string) error { } defer f.Close() - err = cfg.JSONWriter(f) + encoder := json.NewEncoder(f) + encoder.SetIndent("", " ") + err = encoder.Encode(cfg) if err != nil { - return err + return fmt.Errorf("Error in encoding struct to json: %v", err) } return nil diff --git a/pkg/config/flucky.go b/pkg/config/flucky.go new file mode 100644 index 0000000..dc31dee --- /dev/null +++ b/pkg/config/flucky.go @@ -0,0 +1,191 @@ +package config + +import ( + + "fmt" + + "time" + + "github.com/volker-raschek/flucky/pkg/sensor" + + uuid "github.com/satori/go.uuid" + "github.com/volker-raschek/flucky/pkg/types" +) + +// Configuration of flucky +type Configuration struct { + Device *types.Device `json:"device"` + Sensors []*types.Sensor `json:"sensors"` +} + +// AddSensor add a new sensor +func (c *Configuration) AddSensor(sensor *types.Sensor) error { + + // check if sensorID is a valid UUID string + if !validUUID.MatchString(sensor.SensorID) { + sensor.SensorID = uuid.NewV4().String() + } + + // check if sensor name and sensor uuid already exists + for _, s := range c.Sensors { + if s.SensorName == sensor.SensorName { + return fmt.Errorf("Sensor %v already exists", s.SensorName) + } + + if s.SensorID == sensor.SensorID { + return fmt.Errorf("Sensor %v with UUID %v already exists", s.SensorName, s.SensorID) + } + + if *sensor.WireID != "" && + *s.WireID == *sensor.WireID { + return fmt.Errorf("Sensor with 1wire-id %v already exists as %v", *s.WireID, s.SensorName) + } + } + + // check if sensor has a valid device id + if sensor.DeviceID != c.Device.DeviceID { + sensor.DeviceID = c.Device.DeviceID + } + + // overwrite creation date + sensor.CreationDate = time.Now() + + //TODO: check if wire sensor exists in /dev/bus/w1/devices + + // check + c.Sensors = append(c.Sensors, sensor) + + return nil +} + +// DisableSensor disables a sensor by its name or its unique UUID +func (c *Configuration) DisableSensor(name string) error { + found := false + + for _, sensor := range c.Sensors { + + // disable sensor matched after name + if !validUUID.MatchString(name) && + sensor.SensorName == name { + sensor.SensorEnabled = false + found = true + break + } + + // remove machted uuid + if validUUID.MatchString(name) && + sensor.SensorID == name { + sensor.SensorEnabled = false + found = true + break + } + } + + if !found { + return fmt.Errorf("Can not found sensor %v", name) + } + + return nil +} + +// EnableSensor enables a sensor by its name or its unique UUID +func (c *Configuration) EnableSensor(name string) error { + found := false + + for _, sensor := range c.Sensors { + + // disable sensor matched after name + if !validUUID.MatchString(name) && + sensor.SensorName == name { + sensor.SensorEnabled = true + found = true + break + } + + // remove machted uuid + if validUUID.MatchString(name) && + sensor.SensorID == name { + sensor.SensorEnabled = true + found = true + break + } + } + + if !found { + return fmt.Errorf("Can not found sensor %v", name) + } + + return nil +} + +// GetHumiditySensors returns a list of humidity sensors +func (c *Configuration) GetHumiditySensors() []sensor.HumiditySensor{ + humiditySensors, _ := c.splitSensors() + return humiditySensors +} + +// GetTemperatureSensors returns a list of humidity sensors +func (c *Configuration) GetTemperatureSensors() []sensor.TemperatureSensor{ + _, temperatureSensors := c.splitSensors() + return temperatureSensors +} + +// RemoveSensor deletes a sensor by its name or its unique UUID +func (c *Configuration) RemoveSensor(name string) error { + for i, sensor := range c.Sensors { + // remove machted name + if !validUUID.MatchString(name) && + sensor.SensorName == name { + c.Sensors = append(c.Sensors[:i], c.Sensors[i+1:]...) + return nil + } + // remove machted uuid + if validUUID.MatchString(name) && + sensor.SensorID == name { + c.Sensors = append(c.Sensors[:i], c.Sensors[i+1:]...) + return nil + } + } + return fmt.Errorf("Can not find sensor %v", name) +} + +// RenameSensor renames a sensor identified by the name or the UUID +func (c *Configuration) RenameSensor(oldName, newName string) error { + for _, sensor := range c.Sensors { + if sensor.SensorName == oldName || + sensor.SensorID == oldName { + sensor.SensorName = newName + return nil + } + } + return fmt.Errorf("Could not find remote %v to replace into with %v", oldName, newName) +} + +func (c *Configuration) splitSensors() ([]sensor.HumiditySensor, []sensor.TemperatureSensor) { + humiditySensors := make([]sensor.HumiditySensor, 0) + temperatureSensors := make([]sensor.TemperatureSensor, 0) + + for _, s := range c.Sensors { + switch s.SensorModel { + case types.DHT11: + humiditySensors = append(humiditySensors, &sensor.DHT11{ + Sensor: s, + }) + temperatureSensors = append(temperatureSensors, &sensor.DHT11{ + Sensor: s, + }) + case types.DHT22: + humiditySensors = append(humiditySensors, &sensor.DHT22{ + Sensor: s, + }) + temperatureSensors = append(temperatureSensors, &sensor.DHT22{ + Sensor: s, + }) + case types.DS18B20: + temperatureSensors = append(temperatureSensors, &sensor.DS18B20{ + Sensor: s, + }) + } + } + return humiditySensors, temperatureSensors +} diff --git a/pkg/config/fluckyconfig.go b/pkg/config/fluckyconfig.go deleted file mode 100644 index 2f9d1da..0000000 --- a/pkg/config/fluckyconfig.go +++ /dev/null @@ -1,384 +0,0 @@ -package config - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "time" - - "github.com/volker-raschek/flucky/pkg/logger" - - "github.com/volker-raschek/flucky/pkg/sensor" - - uuid "github.com/satori/go.uuid" - "github.com/volker-raschek/flucky/pkg/types" -) - -// FluckyConfig dasd -type FluckyConfig struct { - Device *types.Device `json:"device"` - *logger.FileLogger - Remotes []*Remote `json:"remotes"` - Sensors []*types.Sensor `json:"sensors"` -} - -// AddSensor add a new sensor -func (fc *FluckyConfig) AddSensor(sensor *types.Sensor) error { - - // check if sensorID is a valid UUID string - if !validUUID.MatchString(sensor.SensorID) { - sensor.SensorID = uuid.NewV4().String() - } - - // check if sensor name and sensor uuid already exists - for _, s := range fc.Sensors { - if s.SensorName == sensor.SensorName { - return fmt.Errorf("Sensor %v already exists", s.SensorName) - } - - if s.SensorID == sensor.SensorID { - return fmt.Errorf("Sensor %v with UUID %v already exists", s.SensorName, s.SensorID) - } - - if *sensor.WireID != "" && - *s.WireID == *sensor.WireID { - return fmt.Errorf("Sensor with 1wire-id %v already exists as %v", *s.WireID, s.SensorName) - } - } - - // check if sensor has a valid device id - if sensor.DeviceID != fc.Device.DeviceID { - sensor.DeviceID = fc.Device.DeviceID - } - - // overwrite creation date - sensor.CreationDate = time.Now() - - //TODO: check if wire sensor exists in /dev/bus/w1/devices - - // check - fc.Sensors = append(fc.Sensors, sensor) - - return nil -} - -// AddRemote add a new remote address -func (fc *FluckyConfig) AddRemote(remote *Remote) error { - - // check if remoteID is a valid UUID string - if !validUUID.MatchString(remote.RemoteID) { - remote.RemoteID = uuid.NewV4().String() - } - - // check if remote name or remiteid already exists - for _, r := range fc.Remotes { - if r.Name == remote.Name { - return fmt.Errorf("Remote %v -> %v already exists", r.Name, r.Address) - } - - if r.RemoteID == remote.RemoteID { - return fmt.Errorf("Remote %v with UUID %v already exists", r.Name, r.RemoteID) - } - } - - fc.Remotes = append(fc.Remotes, remote) - - return nil -} - -// DisableRemote disables a remote address by its name or its unique UUID -func (fc *FluckyConfig) DisableRemote(nameOrUUID string) error { - found := false - - for _, remote := range fc.Remotes { - - // disable sensor matched after name - if !validUUID.MatchString(nameOrUUID) && - remote.Name == nameOrUUID { - remote.Enabled = false - found = true - break - } - - // remove machted uuid - if validUUID.MatchString(nameOrUUID) && - remote.RemoteID == nameOrUUID { - remote.Enabled = false - found = true - break - } - } - - if !found { - return fmt.Errorf("Can not found remote name %v", nameOrUUID) - } - - return nil -} - -// DisableSensor disables a sensor by its name or its unique UUID -func (fc *FluckyConfig) DisableSensor(nameOrUUID string) error { - found := false - - for _, sensor := range fc.Sensors { - - // disable sensor matched after name - if !validUUID.MatchString(nameOrUUID) && - sensor.SensorName == nameOrUUID { - sensor.SensorEnabled = false - found = true - break - } - - // remove machted uuid - if validUUID.MatchString(nameOrUUID) && - sensor.SensorID == nameOrUUID { - sensor.SensorEnabled = false - found = true - break - } - } - - if !found { - return fmt.Errorf("Can not found sensor %v", nameOrUUID) - } - - return nil -} - -// EnableRemote enable a remote address by its name or its unique UUID -func (fc *FluckyConfig) EnableRemote(nameOrUUID string) error { - found := false - - for _, remote := range fc.Remotes { - - // disable sensor matched after name - if !validUUID.MatchString(nameOrUUID) && - remote.Name == nameOrUUID { - remote.Enabled = true - found = true - break - } - - // remove machted uuid - if validUUID.MatchString(nameOrUUID) && - remote.RemoteID == nameOrUUID { - remote.Enabled = true - found = true - break - } - } - - if !found { - return fmt.Errorf("Can not found sensor %v", nameOrUUID) - } - - return nil -} - -// EnableSensor enables a sensor by its name or its unique UUID -func (fc *FluckyConfig) EnableSensor(nameOrUUID string) error { - found := false - - for _, sensor := range fc.Sensors { - - // disable sensor matched after name - if !validUUID.MatchString(nameOrUUID) && - sensor.SensorName == nameOrUUID { - sensor.SensorEnabled = true - found = true - break - } - - // remove machted uuid - if validUUID.MatchString(nameOrUUID) && - sensor.SensorID == nameOrUUID { - sensor.SensorEnabled = true - found = true - break - } - } - - if !found { - return fmt.Errorf("Can not found sensor %v", nameOrUUID) - } - - return nil -} - -func (fc *FluckyConfig) GetHumiditySensors(namesOrUUIDs []string) []sensor.HumiditySensor { - hs := []sensor.HumiditySensor{} - for _, s := range fc.Sensors { - // select only named sensors - if len(namesOrUUIDs) > 0 { - found := false - for _, nameOrUUID := range namesOrUUIDs { - if nameOrUUID == s.SensorID || nameOrUUID == s.SensorName { - found = true - break - } - } - if !found { - continue - } - } - // skip disabled sensors - if !s.SensorEnabled { - continue - } - switch s.SensorModel { - case types.DHT11: - hs = append(hs, &sensor.DHT11Sensor{ - Sensor: s, - }) - case types.DHT22: - hs = append(hs, &sensor.DHT22Sensor{ - Sensor: s, - }) - } - } - return hs -} - -func (fc *FluckyConfig) GetTemperatureSensors(namesOrUUIDs []string) ([]sensor.TemperatureSensor, error) { - ts := []sensor.TemperatureSensor{} - for _, s := range fc.Sensors { - // select only named sensors - if len(namesOrUUIDs) > 0 { - found := false - for _, nameOrUUID := range namesOrUUIDs { - if nameOrUUID == s.SensorID || nameOrUUID == s.SensorName { - found = true - break - } - } - if !found { - continue - } - } - // skip disabled sensors - if !s.SensorEnabled { - continue - } - switch s.SensorModel { - case types.DHT11: - ts = append(ts, &sensor.DHT11Sensor{ - Sensor: s, - }) - case types.DHT22: - ts = append(ts, &sensor.DHT22Sensor{ - Sensor: s, - }) - case types.DS18B20: - ts = append(ts, &sensor.DS18B20{ - Sensor: s, - }) - default: - return nil, fmt.Errorf("Sensor Model %v is not a valid sensor model. Please remove the sensor named %v", s.SensorModel, s.Name()) - } - } - return ts, nil -} - -// JSONDecoder decode a JSON string from a reader into a struct -func (fc *FluckyConfig) JSONDecoder(r io.Reader) error { - jsonDecoder := json.NewDecoder(r) - if err := jsonDecoder.Decode(&fc); err != nil { - return fmt.Errorf("Can not unmarshal JSON: %v", err) - } - return nil -} - -// JSONWriter needs a writer to write the struct into JSON string -func (fc *FluckyConfig) JSONWriter(w io.Writer) error { - encoder := json.NewEncoder(w) - encoder.SetIndent("", " ") - err := encoder.Encode(&fc) - if err != nil { - return fmt.Errorf("Error in encoding struct to json: %v", err) - } - return nil -} - -// RemoveSensor deletes a sensor by its name or its unique UUID -func (fc *FluckyConfig) RemoveSensor(nameOrUUID string) error { - for i, sensor := range fc.Sensors { - // remove machted name - if !validUUID.MatchString(nameOrUUID) && - sensor.SensorName == nameOrUUID { - fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...) - return nil - } - // remove machted uuid - if validUUID.MatchString(nameOrUUID) && - sensor.SensorID == nameOrUUID { - fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...) - return nil - } - } - return fmt.Errorf("Can not find sensor %v", nameOrUUID) -} - -// RemoveRemote deletes a remote address by its name or its unique UUID -func (fc *FluckyConfig) RemoveRemote(nameOrUUID string) error { - found := false - - for i, remote := range fc.Remotes { - - // remove machted name - if !validUUID.MatchString(nameOrUUID) && - remote.Name == nameOrUUID { - fc.Remotes = append(fc.Remotes[:i], fc.Remotes[i+1:]...) - found = true - } - - // remove machted uuid - if validUUID.MatchString(nameOrUUID) && - remote.RemoteID == nameOrUUID { - fc.Remotes = append(fc.Remotes[:i], fc.Remotes[i+1:]...) - found = true - } - } - - if !found { - return fmt.Errorf("Can not find remote %v", nameOrUUID) - } - - return nil -} - -// RenameSensor renames a sensor identified by the name or the UUID -func (fc *FluckyConfig) RenameSensor(oldName, newName string) error { - for _, sensor := range fc.Sensors { - if sensor.SensorName == oldName || - sensor.SensorID == oldName { - sensor.SensorName = newName - return nil - } - } - return fmt.Errorf("Could not find sensor %v to replace into ", oldName) -} - -// RenameRemote renames a remote address identified by the name or the UUID -func (fc *FluckyConfig) RenameRemote(oldName, newName string) error { - for _, remote := range fc.Remotes { - if remote.Name == oldName || - remote.RemoteID == oldName { - remote.Name = newName - return nil - } - } - return fmt.Errorf("Could not find remote name %v to replace into %v", oldName, newName) -} - -// ToJSON returns the struct as JSON string -func (fc *FluckyConfig) ToJSON() (string, error) { - var b bytes.Buffer - err := fc.JSONWriter(&b) - if err != nil { - return "", err - } - - return b.String(), nil -} diff --git a/pkg/config/remote.go b/pkg/config/remote.go deleted file mode 100644 index 20e051b..0000000 --- a/pkg/config/remote.go +++ /dev/null @@ -1,28 +0,0 @@ -package config - -import "github.com/volker-raschek/flucky/pkg/types" - -// Remote ... -type Remote struct { - RemoteID string `json:"remote_id"` - Name string `json:"remote_name"` - Address string `json:"remote_address"` - Registered bool `json:"remote_registered"` - Enabled bool `json:"remote_enabled"` -} - -func (r *Remote) AddSensor(s *types.Sensor) error { - return nil -} - -func (r *Remote) RegisterDevice(d *types.Device) error { - return nil -} - -func (r *Remote) RemoveSensor(s *types.Sensor) error { - return nil -} - -func (r *Remote) UnregisterDevice(d *types.Device) error { - return nil -} diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go new file mode 100644 index 0000000..4cf2818 --- /dev/null +++ b/pkg/daemon/daemon.go @@ -0,0 +1,33 @@ +package daemon + +import ( + "fmt" + "os" + "os/signal" + "syscall" + + "github.com/volker-raschek/flucky/pkg/config" + "github.com/volker-raschek/flucky/pkg/sensor" + "github.com/volker-raschek/flucky/pkg/types" +) + +// Start the daemon +func Start(cnf *config.FluckyConfig) error { + + interrupt := make(chan os.Signal, 1) + signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM) + + humidityChannel := make(chan *types.Humidity) + temperatureChannel := make(chan *types.Temperature) + + go sensor.ReadHumiditiesContinuously(humiditySensors, humidityChannel) + go sensor.ReadTemperaturesContinuously(temperatureSensors, temperatureChannel) + + for { + select { + case killSignal := <-interrupt: + return fmt.Errorf("Daemon was interruped by system signal %v", killSignal) + } + } + +} diff --git a/pkg/internal/collect/errors.go b/pkg/internal/collect/errors.go new file mode 100644 index 0000000..e405c40 --- /dev/null +++ b/pkg/internal/collect/errors.go @@ -0,0 +1,16 @@ +package collect + +func Errors(errorChannel <-chan error) []error { + errorList := make([]error, 0) + for { + select { + case err, more := <-errorChannel: + if more { + errorList = append(errorList, err) + continue + } + default: + return errorList + } + } +} diff --git a/pkg/internal/collect/humidity.go b/pkg/internal/collect/humidity.go new file mode 100644 index 0000000..e1c3abc --- /dev/null +++ b/pkg/internal/collect/humidity.go @@ -0,0 +1,20 @@ +package collect + +import "github.com/volker-raschek/flucky/pkg/types" + +func Humidities(humidityChannel <-chan *types.Humidity) []*types.Humidity { + humidityList := make([]*types.Humidity, 0) + + for { + select { + case hum, more := <-humidityChannel: + if more { + humidityList = append(humidityList, hum) + continue + } + return nil + default: + return humidityList + } + } +} diff --git a/pkg/internal/collect/temperatures.go b/pkg/internal/collect/temperatures.go new file mode 100644 index 0000000..cecda0d --- /dev/null +++ b/pkg/internal/collect/temperatures.go @@ -0,0 +1,20 @@ +package collect + +import ( + "github.com/volker-raschek/flucky/pkg/types" +) + +func Temperatures(temperatureChannel <-chan *types.Temperature) []*types.Temperature { + temperatureList := make([]*types.Temperature, 0) + for { + select { + case temperature, more := <-temperatureChannel: + if more { + temperatureList = append(temperatureList, temperature) + continue + } + default: + return temperatureList + } + } +} diff --git a/pkg/internal/errutils/errutils.go b/pkg/internal/errutils/errutils.go deleted file mode 100644 index e855835..0000000 --- a/pkg/internal/errutils/errutils.go +++ /dev/null @@ -1,31 +0,0 @@ -package errutils - -import ( - "fmt" -) - -func CollectErrors(errChan <-chan error) []error { - errorList := make([]error, 0) - for { - select { - case err, more := <-errChan: - if more { - errorList = append(errorList, err) - continue - } - default: - return errorList - } - } -} - -func FormatErrors(errorList []error) error { - if len(errorList) > 0 { - errMsg := "" - for _, err := range errorList { - errMsg = fmt.Sprintf("%v\n%v", errMsg, err.Error()) - } - return fmt.Errorf(errMsg) - } - return nil -} diff --git a/pkg/internal/prittyprint/prittyprint.go b/pkg/internal/prittyprint/prittyprint.go new file mode 100644 index 0000000..d5a840b --- /dev/null +++ b/pkg/internal/prittyprint/prittyprint.go @@ -0,0 +1,14 @@ +package prittyprint + +import "fmt" + +func FormatErrors(errors []error) error { + if len(errors) > 0 { + errMsg := "" + for _, err := range errors { + errMsg = fmt.Sprintf("%v\n%v", errMsg, err.Error()) + } + return fmt.Errorf(errMsg) + } + return nil +} diff --git a/pkg/internal/temperature/temperature.go b/pkg/internal/temperature/temperature.go index dee7305..0e6debb 100644 --- a/pkg/internal/temperature/temperature.go +++ b/pkg/internal/temperature/temperature.go @@ -9,7 +9,7 @@ import ( ) // GetSensorsByTemperatures returns commulated list of sensors by temperature values -func GetSensorsByTemperatures(temperatures []*types.Temperature, cnf *config.FluckyConfig) []*types.Sensor { +func GetSensorsByTemperatures(temperatures []*types.Temperature, cnf *config.Configuration) []*types.Sensor { sensors := []*types.Sensor{} for _, temperature := range temperatures { duplicated := false @@ -66,7 +66,7 @@ func GetTemperaturesBetweenTimeRange(from time.Time, till *time.Time, temperatur // GetTemperaturesBySensors returns a list of temperatures given by the sensor id. // If the sensor name, wire-id or id can not found in configured sensors, it would be skiped! -func GetTemperaturesBySensors(sensorNamesOrIDs []string, temperatures []*types.Temperature, cnf *config.FluckyConfig) []*types.Temperature { +func GetTemperaturesBySensors(sensorNamesOrIDs []string, temperatures []*types.Temperature, cnf *config.Configuration) []*types.Temperature { cachedSensors := []*types.Sensor{} cachedTemperatures := []*types.Temperature{} diff --git a/pkg/logger/file_logger.go b/pkg/logger/file_logger.go deleted file mode 100644 index 67ac89a..0000000 --- a/pkg/logger/file_logger.go +++ /dev/null @@ -1,222 +0,0 @@ -package logger - -import ( - "encoding/json" - "fmt" - "io" - "os" - "time" - - "github.com/volker-raschek/flucky/pkg/types" -) - -type FileLogger struct { - LogFiles map[LogValue][]string `json:"logfiles"` - writer io.Writer -} - -func (fl *FileLogger) AddLogFile(logfile string, logValue LogValue) error { - for _, logfiles := range fl.LogFiles { - for _, lf := range logfiles { - if lf == logfile { - return fmt.Errorf("Logfile %v already configured", logfile) - } - } - } - fl.LogFiles[logValue] = append(fl.LogFiles[logValue], logfile) - return nil -} - -func (fl *FileLogger) GetHumidities(fromDate *time.Time, tillDate *time.Time, sensorNameOrUUID *[]string) ([]*types.Humidity, error) { - return nil, nil -} - -func (fl *FileLogger) GetTemperatures(from *time.Time, till *time.Time, sensorIDs []string) ([]*types.Temperature, error) { - cachedTemperatures := []*types.Temperature{} - - // iterate over all configured temperature logfiles - for _, logfile := range fl.LogFiles[LogTemperature] { - - // skip logfile if not exists - if _, err := os.Stat(logfile); os.IsNotExist(err) { - return nil, fmt.Errorf("Logfile %v not exists", logfile) - } - - loggedTemperatures := []*types.Temperature{} - - f, err := os.Open(logfile) - if err != nil { - return nil, fmt.Errorf("Can not open %v: %v", logfile, err) - } - defer f.Close() - - decoder := json.NewDecoder(f) - err = decoder.Decode(&loggedTemperatures) - if err != nil { - return nil, fmt.Errorf("Can not decode temperatures from logfile %v: %v", logfile, err) - } - - cachedTemperatures = append(cachedTemperatures, loggedTemperatures...) - - // // sort all redundant values out - // for _, loggedTemperature := range loggedTemperatures { - // found := false - // for _, cachedTemperature := range cachedTemperatures { - // if cachedTemperature.TemperatureID == loggedTemperature.TemperatureID { - // found = true - // break - // } - // } - // if !found { - // cachedTemperatures = append(cachedTemperatures, loggedTemperature) - // } - // } - } - - // // sort out all temperatures which are not mesured by sensor id - // for i, cachedTemperature := range cachedTemperatures { - // found := false - // for _, sensorID := range sensorIDs { - // if cachedTemperature.SensorID == sensorID { - // found = true - // break - // } - // } - // if !found { - // cachedTemperatures = append(cachedTemperatures[:i], cachedTemperatures[i+1:]...) - // } - // } - - // // sort out all temperatures which are before from date - // if from != nil { - // for i, cachedTemperature := range cachedTemperatures { - // if cachedTemperature.TemperatureDate.Before(*from) { - // cachedTemperatures = append(cachedTemperatures[:i], cachedTemperatures[i+1:]...) - // } - // } - // } - - // // sort out all temperatures which are after till date - // if till != nil { - // for i, cachedTemperature := range cachedTemperatures { - // if cachedTemperature.TemperatureDate.After(*till) { - // cachedTemperatures = append(cachedTemperatures[:i], cachedTemperatures[i+1:]...) - // } - // } - // } - - return cachedTemperatures, nil -} - -// LogHumidities write humidities to all configured humidity logfiles -func (fl *FileLogger) LogHumidities(humidities []*types.Humidity) error { - for _, logfile := range fl.LogFiles[LogHumidity] { - logHumidities := []*types.Humidity{} - // if logfile already exists, read humidities from logfile - if _, err := os.Stat(logfile); err == nil { - f, err := os.Open(logfile) - if err != nil { - return fmt.Errorf("Can not open file %v: %v", logfile, err) - } - - decoder := json.NewDecoder(f) - err = decoder.Decode(&logHumidities) - if err != nil { - return fmt.Errorf("Can not decode humidities from reader") - } - - f.Close() - } - - // append new humidities with existing humidities from logfile - logHumidities = append(logHumidities, humidities...) - - // overwrite lofgile with new entries - f, err := os.Create(logfile) - if err != nil { - return fmt.Errorf("Can not open file %v: %v", logfile, err) - } - defer f.Close() - - // encode humidities - encoder := json.NewEncoder(f) - encoder.SetIndent("", " ") - err = encoder.Encode(logHumidities) - if err != nil { - return fmt.Errorf("Can not encode humidities for the writer") - } - } - - return nil -} - -// LogTemperatures write temperatures to all configured temperature logfiles -func (fl *FileLogger) LogTemperatures(temperatures []*types.Temperature) error { - for _, logfile := range fl.LogFiles[LogTemperature] { - logTemperatures := []*types.Temperature{} - // if logfile already exists, read temperatures from logfile - if _, err := os.Stat(logfile); err == nil { - f, err := os.Open(logfile) - if err != nil { - return fmt.Errorf("Can not open file %v: %v", logfile, err) - } - - decoder := json.NewDecoder(f) - err = decoder.Decode(&logTemperatures) - if err != nil { - return fmt.Errorf("Can not decode temperatures from reader") - } - - f.Close() - } - - // append new temperatures with existing temperatures from logfile - logTemperatures = append(logTemperatures, temperatures...) - - // overwrite lofgile with new entries - f, err := os.Create(logfile) - if err != nil { - return fmt.Errorf("Can not open file %v: %v", logfile, err) - } - defer f.Close() - - // encode temperatures - encoder := json.NewEncoder(f) - encoder.SetIndent("", " ") - err = encoder.Encode(logTemperatures) - if err != nil { - return fmt.Errorf("Can not encode temperatures for the writer") - } - } - - return nil -} - -func (fl *FileLogger) RemoveLogFile(logfile string) error { - - for i, logfiles := range fl.LogFiles { - cachedLogfiles := []string{} - for _, lf := range logfiles { - if lf == logfile { - continue - } - cachedLogfiles = append(cachedLogfiles, lf) - } - fl.LogFiles[i] = cachedLogfiles - } - - if _, err := os.Stat(logfile); err == nil { - err := os.Remove(logfile) - if err != nil { - return fmt.Errorf("Can not remote file %v: %v", logfile, err) - } - } - - return nil -} - -func NewFileLogger(w io.Writer) *FileLogger { - return &FileLogger{ - writer: w, - } -} diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go deleted file mode 100644 index 7f2b274..0000000 --- a/pkg/logger/logger.go +++ /dev/null @@ -1,73 +0,0 @@ -package logger - -import ( - "fmt" - "time" - - "github.com/volker-raschek/flucky/pkg/types" -) - -type Logger interface { - GetHumidities(fromDate *time.Time, tillDate *time.Time, sensorNameOrUUID *[]string) ([]*types.Humidity, error) - GetTemperatures(from *time.Time, till *time.Time, sensorIDs []string) ([]*types.Temperature, error) - LogHumidities(humidities []*types.Humidity) error - LogTemperatures(temperatures []*types.Temperature) error -} - -type LoggerType string - -const ( - LogFile LoggerType = "file" - LogRemote = "remote" -) - -type LogValue string - -const ( - LogHumidity LogValue = "humidity" - LogTemperature = "temperature" -) - -// LogTypeToString converts a logtype into a string -func LogTypeToString(loggertype LoggerType) (string, error) { - switch loggertype { - case LogFile: - return "file", nil - default: - return "", fmt.Errorf("Can not determine loggertype %v", loggertype) - } -} - -// LogValueToString converts a logvalue into a string -func LogValueToString(logvalue LogValue) (string, error) { - switch logvalue { - case LogHumidity: - return "humidity", nil - case LogTemperature: - return "temperature", nil - default: - return "", fmt.Errorf("Can not determine logvalue %v", logvalue) - } -} - -// StringToLoggerType converts a string into loggertype -func StringToLoggerType(loggertype string) (LoggerType, error) { - switch loggertype { - case "file": - return LogFile, nil - default: - return "", fmt.Errorf("Can not determine loggertype %v", loggertype) - } -} - -// StringToLogValue converts a string into logvalue -func StringToLogValue(logvalue string) (LogValue, error) { - switch logvalue { - case "humidity": - return LogHumidity, nil - case "temperature": - return LogTemperature, nil - default: - return "", fmt.Errorf("Can not determine logvalue %v", logvalue) - } -} diff --git a/pkg/sensor/dht11.go b/pkg/sensor/dht11.go index 18f92c5..c12bcd5 100644 --- a/pkg/sensor/dht11.go +++ b/pkg/sensor/dht11.go @@ -9,11 +9,18 @@ import ( "github.com/volker-raschek/flucky/pkg/types" ) -type DHT11Sensor struct { +// DHT11 is a sensor to measure humidity and temperature. +type DHT11 struct { *types.Sensor } -func (s *DHT11Sensor) ReadHumidity() (*types.Humidity, error) { +// GetSensorModel returns the sensor model +func (s *DHT11) GetSensorModel() types.SensorModel { + return s.Sensor.SensorModel +} + +// ReadHumidity measure the humidity +func (s *DHT11) ReadHumidity() (*types.Humidity, error) { err := dht.HostInit() if err != nil { return nil, fmt.Errorf("HostInit error: %v", err) @@ -44,7 +51,8 @@ func (s *DHT11Sensor) ReadHumidity() (*types.Humidity, error) { return humidity, nil } -func (s *DHT11Sensor) ReadTemperature() (*types.Temperature, error) { +// ReadTemperature measure the temperature +func (s *DHT11) ReadTemperature() (*types.Temperature, error) { err := dht.HostInit() if err != nil { return nil, fmt.Errorf("HostInit error: %v", err) diff --git a/pkg/sensor/dht22.go b/pkg/sensor/dht22.go index fa30777..20a191e 100644 --- a/pkg/sensor/dht22.go +++ b/pkg/sensor/dht22.go @@ -9,11 +9,18 @@ import ( "github.com/volker-raschek/flucky/pkg/types" ) -type DHT22Sensor struct { +// DHT22 is a sensor to measure humidity and temperature. +type DHT22 struct { *types.Sensor } -func (s *DHT22Sensor) ReadHumidity() (*types.Humidity, error) { +// GetSensorModel returns the sensor model +func (s *DHT22) GetSensorModel() types.SensorModel { + return s.Sensor.SensorModel +} + +// ReadHumidity measure the humidity +func (s *DHT22) ReadHumidity() (*types.Humidity, error) { err := dht.HostInit() if err != nil { return nil, fmt.Errorf("HostInit error: %v", err) @@ -44,7 +51,8 @@ func (s *DHT22Sensor) ReadHumidity() (*types.Humidity, error) { return humidity, nil } -func (s *DHT22Sensor) ReadTemperature() (*types.Temperature, error) { +// ReadTemperature measure the temperature +func (s *DHT22) ReadTemperature() (*types.Temperature, error) { err := dht.HostInit() if err != nil { return nil, fmt.Errorf("HostInit error: %v", err) diff --git a/pkg/sensor/ds18b20.go b/pkg/sensor/ds18b20.go index 2a01ae9..9dad728 100644 --- a/pkg/sensor/ds18b20.go +++ b/pkg/sensor/ds18b20.go @@ -9,10 +9,22 @@ import ( "github.com/yryz/ds18b20" ) +// DS18B20 is a sensor to measure humidity and temperature. type DS18B20 struct { *types.Sensor } +// GetSensorModel returns the sensor model +func (s *DS18B20) GetSensorModel() types.SensorModel { + return s.Sensor.SensorModel +} + +// GetSensor return the sensor struct +func (s *DS18B20) GetSensor() *types.Sensor { + return s.Sensor +} + +// ReadTemperature measure the temperature func (s *DS18B20) ReadTemperature() (*types.Temperature, error) { t, err := ds18b20.Temperature(*s.WireID) diff --git a/pkg/sensor/interfaces.go b/pkg/sensor/interfaces.go new file mode 100644 index 0000000..16c1f2f --- /dev/null +++ b/pkg/sensor/interfaces.go @@ -0,0 +1,15 @@ +package sensor + +import "github.com/volker-raschek/flucky/pkg/types" + +// HumiditySensor is a interface to describe required functions to measure humidities +type HumiditySensor interface { + GetSensorModel() types.SensorModel + ReadHumidity() (*types.Humidity, error) +} + +// TemperatureSensor is a interface to describe required functions to measure temperatures +type TemperatureSensor interface { + GetSensorModel() types.SensorModel + ReadTemperature() (*types.Temperature, error) +} diff --git a/pkg/sensor/sensor.go b/pkg/sensor/sensor.go index 786a760..95ca0eb 100644 --- a/pkg/sensor/sensor.go +++ b/pkg/sensor/sensor.go @@ -3,106 +3,87 @@ package sensor import ( "sync" - "github.com/volker-raschek/flucky/pkg/internal/errutils" - + "github.com/volker-raschek/flucky/pkg/internal/collect" + "github.com/volker-raschek/flucky/pkg/internal/prittyprint" "github.com/volker-raschek/flucky/pkg/types" ) -type HumiditySensor interface { - ReadHumidity() (*types.Humidity, error) -} - -type TemperatureSensor interface { - ReadTemperature() (*types.Temperature, error) -} - +// ReadHumidities returns a list of measured humidities by humidity sensors func ReadHumidities(humiditySensors []HumiditySensor) ([]*types.Humidity, error) { + errorChannel := make(chan error, len(humiditySensors)) + humidityChannel := make(chan *types.Humidity, len(humiditySensors)) + ReadHumiditiesIntoChannel(humiditySensors, humidityChannel, errorChannel) + errorList := collect.Errors(errorChannel) + if len(errorList) != 0 { + return nil, prittyprint.FormatErrors(errorList) + } + + humidityList := collect.Humidities(humidityChannel) + return humidityList, nil +} + +// ReadHumiditiesIntoChannel reads the humidity values of humidity sensors and writes them into a channel +func ReadHumiditiesIntoChannel(humiditySensors []HumiditySensor, humidityChannel chan<- *types.Humidity, errorChannel chan<- error) { wg := new(sync.WaitGroup) wg.Add(len(humiditySensors)) - - errChannel := make(chan error, len(humiditySensors)) - humidityChannel := make(chan *types.Humidity, len(humiditySensors)) - for _, humiditySensor := range humiditySensors { go func(hs HumiditySensor) { defer wg.Done() humidity, err := hs.ReadHumidity() if err != nil { - errChannel <- err - humidityChannel <- nil + errorChannel <- err + return } - errChannel <- nil humidityChannel <- humidity }(humiditySensor) } - wg.Wait() - - errorList := errutils.CollectErrors(errChannel) - if err := errutils.FormatErrors(errorList); err != nil { - return nil, err - } - - humidityList := collectHumidities(humidityChannel) - return humidityList, nil - } +// ReadHumiditiesContinuously reads the humidity values of humidity sensors continuously and writes them into a channel +func ReadHumiditiesContinuously(humiditySensors []HumiditySensor, humidityChannel chan<- *types.Humidity, errorChannel chan<- error) { + for { + ReadHumiditiesIntoChannel(humiditySensors, humidityChannel, errorChannel) + } +} + +// ReadTemperatures returns a list of measured temperatures by temperature sensors func ReadTemperatures(temperatureSensors []TemperatureSensor) ([]*types.Temperature, error) { + errorChannel := make(chan error, len(temperatureSensors)) + temperatureChannel := make(chan *types.Temperature, len(temperatureSensors)) + ReadTemperaturesIntoChannel(temperatureSensors, temperatureChannel, errorChannel) + + errorList := collect.Errors(errorChannel) + if len(errorList) != 0 { + return nil, prittyprint.FormatErrors(errorList) + } + + temperatureList := collect.Temperatures(temperatureChannel) + return temperatureList, nil +} + +// ReadTemperaturesIntoChannel reads the temperature values of temperature sensors and writes them into a channel +func ReadTemperaturesIntoChannel(temperatureSensors []TemperatureSensor, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) { wg := new(sync.WaitGroup) wg.Add(len(temperatureSensors)) - errChannel := make(chan error, len(temperatureSensors)) - temperatureChannel := make(chan *types.Temperature, len(temperatureSensors)) for _, temperatureSensor := range temperatureSensors { go func(ts TemperatureSensor) { defer wg.Done() temperature, err := ts.ReadTemperature() if err != nil { - errChannel <- err + errorChannel <- err + return } temperatureChannel <- temperature }(temperatureSensor) } wg.Wait() - errorList := errutils.CollectErrors(errChannel) - if err := errutils.FormatErrors(errorList); err != nil { - return nil, err - } - temperatureList := collectTemperatures(temperatureChannel) - return temperatureList, nil } -func collectHumidities(humChan <-chan *types.Humidity) []*types.Humidity { - humidityList := make([]*types.Humidity, 0) - +// ReadTemperaturesContinuously reads the temperature values of temperature sensors continuously and writes them into a chann +func ReadTemperaturesContinuously(temperatureSensors []TemperatureSensor, temperatureChannel chan<- *types.Temperature, errorChannel chan<- error) { for { - select { - case hum, more := <-humChan: - if more { - humidityList = append(humidityList, hum) - continue - } - return nil - default: - return humidityList - } - } -} - -func collectTemperatures(tempChan <-chan *types.Temperature) []*types.Temperature { - temperatureList := make([]*types.Temperature, 0) - - for { - select { - case temp, more := <-tempChan: - if more { - temperatureList = append(temperatureList, temp) - continue - } - return nil - default: - return temperatureList - } + ReadTemperaturesIntoChannel(temperatureSensors, temperatureChannel, errorChannel) } }