diff --git a/Makefile b/Makefile index ee6508c..8155d32 100644 --- a/Makefile +++ b/Makefile @@ -7,5 +7,5 @@ go-build-arm7: GOOS=linux GOARCH=arm GOARM=7 go build -o flucky -ldflags "-X main.version=${VERSION}" pi-copy: go-build-arm7 - scp flucky hades:/usr/local/bin - ssh hades 'chmod +x /usr/local/bin/flucky' + scp flucky hades.trier.cryptic.systems:/usr/local/bin + ssh hades.trier.cryptic.systems 'chmod +x /usr/local/bin/flucky' diff --git a/cmd/cmd.go b/cmd/cmd.go index 9303bcf..b71749a 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -3,9 +3,12 @@ package cmd import ( "fmt" "os" + "time" - "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" "git.cryptic.systems/fh-trier/go-flucky/cmd/remote" + "git.cryptic.systems/fh-trier/go-flucky/cmd/sensor" + "git.cryptic.systems/fh-trier/go-flucky/cmd/temperature" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" "git.cryptic.systems/fh-trier/go-flucky/pkg/config" uuid "github.com/satori/go.uuid" @@ -28,8 +31,9 @@ var rootCmd = &cobra.Command{ fc := config.FluckyConfig{ Device: &types.Device{ - DeviceID: uuid.NewV4().String(), - DeviceName: &hostname, + DeviceID: uuid.NewV4().String(), + DeviceName: &hostname, + CreationDate: time.Now(), }, } @@ -51,8 +55,8 @@ func Execute(version string) { // humidity.InitCmd(rootCmd, configDir) remote.InitCmd(rootCmd, cfg) - // sensor.InitCmd(rootCmd, cfg) - // temperature.InitCmd(rootCmd, configDir) + sensor.InitCmd(rootCmd, cfg) + temperature.InitCmd(rootCmd, cfg) rootCmd.Execute() } diff --git a/cmd/remote/add.go b/cmd/remote/add.go index b85189f..c7abbeb 100644 --- a/cmd/remote/add.go +++ b/cmd/remote/add.go @@ -13,6 +13,7 @@ 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) { diff --git a/cmd/sensor/add.go b/cmd/sensor/add.go index 2982eac..7b8ce3d 100644 --- a/cmd/sensor/add.go +++ b/cmd/sensor/add.go @@ -2,24 +2,58 @@ package sensor import ( "fmt" + "log" + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" "github.com/spf13/cobra" ) var enabled bool -var sensorLocation, wireID, wirePath string +var location, wireID, wirePath string var addSensorCmd = &cobra.Command{ Use: "add", Short: "Add Sensor", + Aliases: []string{"append"}, Args: cobra.ExactArgs(3), Example: fmt.Sprintf("flucky sensor add indoor dht11 14\nflucky sensor add --wire-id 28-011432f0bb3d outdoor ds18b20 14"), + Run: func(cmd *cobra.Command, args []string) { + // read configuration + fc, err := config.Read(cfg) + if err != nil { + log.Fatalln(err) + } + + // create new sensor struct + sensor := &types.Sensor{ + SensorName: args[0], + SensorType: args[1], + SensorLocation: location, + SensorEnabled: enabled, + GPIONumber: &args[2], + WireID: &wireID, + } + + // // add sensor entry to list + err = fc.AddSensor(sensor) + if err != nil { + log.Fatalln(err) + } + + // save new configuration + err = config.Write(fc, cfg) + if err != nil { + log.Fatalln(err) + } + }, } func init() { sensorCmd.AddCommand(addSensorCmd) + addSensorCmd.Flags().BoolVarP(&enabled, "enabled", "e", true, "Enable Sensor") - addSensorCmd.Flags().StringVarP(&sensorLocation, "sensor-location", "l", "", "Sensor location") + addSensorCmd.Flags().StringVarP(&location, "location", "l", "", "Sensor location") addSensorCmd.Flags().StringVarP(&wireID, "wire-id", "i", "", "Wire-ID") addSensorCmd.Flags().StringVarP(&wirePath, "wire-path", "w", "/sys/bus/w1/devices", "Wire device path") } diff --git a/cmd/sensor/disable.go b/cmd/sensor/disable.go index 0aa0b74..a2bc326 100644 --- a/cmd/sensor/disable.go +++ b/cmd/sensor/disable.go @@ -1,24 +1,40 @@ package sensor -// import ( -// "log" +import ( + "log" -// "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" -// "github.com/spf13/cobra" -// ) + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "github.com/spf13/cobra" +) -// var disableSensorCmd = &cobra.Command{ -// Use: "disable", -// Short: "Disable Sensor", -// Args: cobra.ExactArgs(1), -// Run: func(cmd *cobra.Command, args []string) { +var disableSensorCmd = &cobra.Command{ + Use: "disable", + Short: "Disable Sensor", + Args: cobra.ExactArgs(1), + Example: "flucky sensor disable outdoor", + Run: func(cmd *cobra.Command, args []string) { -// if err := sensor.Disable(args[0], configDir); err != nil { -// log.Fatal(err) -// } -// }, -// } + // read configuration + fc, err := config.Read(cfg) + if err != nil { + log.Fatalln(err) + } -// func init() { -// sensorCmd.AddCommand(disableSensorCmd) -// } + // disable sensor entry to list + err = fc.DisableSensor(args[0]) + if err != nil { + log.Fatalln(err) + } + + // save new configuration + err = config.Write(fc, cfg) + if err != nil { + log.Fatalln(err) + } + + }, +} + +func init() { + sensorCmd.AddCommand(disableSensorCmd) +} diff --git a/cmd/sensor/enable.go b/cmd/sensor/enable.go index 8669e6f..53897c8 100644 --- a/cmd/sensor/enable.go +++ b/cmd/sensor/enable.go @@ -1,24 +1,39 @@ package sensor -// import ( -// "log" +import ( + "log" -// "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" -// "github.com/spf13/cobra" -// ) + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "github.com/spf13/cobra" +) -// var enableSensorCmd = &cobra.Command{ -// Use: "enable", -// Short: "Enable Sensor", -// Args: cobra.ExactArgs(1), -// Run: func(cmd *cobra.Command, args []string) { +var enableSensorCmd = &cobra.Command{ + Use: "enable", + Short: "Enable Sensor", + Example: "flucky sensor enable outdoor", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { -// if err := sensor.Enable(args[0], configDir); err != nil { -// log.Fatal(err) -// } -// }, -// } + // read configuration + fc, err := config.Read(cfg) + if err != nil { + log.Fatalln(err) + } -// func init() { -// sensorCmd.AddCommand(enableSensorCmd) -// } + // disable sensor entry to list + err = fc.EnableSensor(args[0]) + if err != nil { + log.Fatalln(err) + } + + // save new configuration + err = config.Write(fc, cfg) + if err != nil { + log.Fatalln(err) + } + }, +} + +func init() { + sensorCmd.AddCommand(enableSensorCmd) +} diff --git a/cmd/sensor/list.go b/cmd/sensor/list.go index f1ccedd..1d59d35 100644 --- a/cmd/sensor/list.go +++ b/cmd/sensor/list.go @@ -1,29 +1,38 @@ package sensor -// import ( -// "log" -// "os" +import ( + "log" + "os" -// "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" -// "github.com/spf13/cobra" -// ) + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "github.com/spf13/cobra" +) -// var quiet bool +var listSensorCmd = &cobra.Command{ + Use: "ls", + Short: "List Sensors", + Aliases: []string{"list"}, + Run: func(cmd *cobra.Command, args []string) { + // read configuration + fc, err := config.Read(cfg) + if err != nil { + log.Fatalln(err) + } -// var listSensorCmd = &cobra.Command{ -// Use: "ls", -// Short: "List Sensors", -// Aliases: []string{"list"}, -// Run: func(cmd *cobra.Command, args []string) { -// if err := sensor.Print(os.Stdout, configDir, quiet); err != nil { -// log.Fatal(err) -// } -// }, -// //28-01143277168e -// } + // print sensors on stdout + err = fc.PrintSensors(os.Stdout) + if err != nil { + log.Fatalln(err) + } -// func init() { -// sensorCmd.AddCommand(listSensorCmd) + // save new configuration + err = config.Write(fc, cfg) + if err != nil { + log.Fatalln(err) + } + }, +} -// listSensorCmd.Flags().BoolVarP(&quiet, "quiet", "q", false, "List only sensor id's") -// } +func init() { + sensorCmd.AddCommand(listSensorCmd) +} diff --git a/cmd/sensor/rm.go b/cmd/sensor/rm.go index a0d80e0..b874b29 100644 --- a/cmd/sensor/rm.go +++ b/cmd/sensor/rm.go @@ -1,24 +1,39 @@ package sensor -// import ( -// "log" +import ( + "log" -// "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" -// "github.com/spf13/cobra" -// ) + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "github.com/spf13/cobra" +) -// var rmSensorCmd = &cobra.Command{ -// Use: "rm", -// Short: "Remove Sensor", -// Aliases: []string{"remove"}, -// Args: cobra.ExactArgs(1), -// Run: func(cmd *cobra.Command, args []string) { -// if err := sensor.Remove(args[0], configDir); err != nil { -// log.Fatal(err) -// } -// }, -// } +var rmSensorCmd = &cobra.Command{ + Use: "rm", + Short: "Remove Sensor", + Example: "flucky sensor rm outdoor", + Aliases: []string{"remove"}, + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + // read configuration + fc, err := config.Read(cfg) + if err != nil { + log.Fatalln(err) + } -// func init() { -// sensorCmd.AddCommand(rmSensorCmd) -// } + // // add remote entry to list + err = fc.RemoveSensor(args[0]) + if err != nil { + log.Fatalln(err) + } + + // save new configuration + err = config.Write(fc, cfg) + if err != nil { + log.Fatalln(err) + } + }, +} + +func init() { + sensorCmd.AddCommand(rmSensorCmd) +} diff --git a/cmd/temperature/get.go b/cmd/temperature/get.go deleted file mode 100644 index 523568e..0000000 --- a/cmd/temperature/get.go +++ /dev/null @@ -1,34 +0,0 @@ -package temperature - -import ( - "log" - "os" - - "git.cryptic.systems/fh-trier/go-flucky/pkg/temperature" - "github.com/spf13/cobra" -) - -var follow, push bool - -var getTemperatureCmd = &cobra.Command{ - Use: "get", - Short: "get temperature from sensor", - Run: func(cmd *cobra.Command, args []string) { - - if follow { - if err := temperature.Follow(args, push, configDir, os.Stdout); err != nil { - log.Fatal(err) - } - } else { - if err := temperature.Get(args, push, configDir, os.Stdout); err != nil { - log.Fatal(err) - } - } - }, -} - -func init() { - temperatureCmd.AddCommand(getTemperatureCmd) - getTemperatureCmd.Flags().BoolVarP(&follow, "follow", "f", false, "Follow output") - getTemperatureCmd.Flags().BoolVarP(&push, "push", "p", false, "Push to remote server") -} diff --git a/cmd/temperature/log.go b/cmd/temperature/log.go deleted file mode 100644 index f1b3413..0000000 --- a/cmd/temperature/log.go +++ /dev/null @@ -1,26 +0,0 @@ -package temperature - -import ( - "log" - "os" - - "git.cryptic.systems/fh-trier/go-flucky/pkg/logs" - "github.com/spf13/cobra" -) - -var writeLog bool - -var logTemperatureCmd = &cobra.Command{ - Use: "log", - Short: "Log print all temperatures saved from logfile on stdout", - Run: func(cmd *cobra.Command, args []string) { - - if err := logs.ListTemperatures(configDir, os.Stdout); err != nil { - log.Fatal(err) - } - }, -} - -func init() { - temperatureCmd.AddCommand(logTemperatureCmd) -} diff --git a/cmd/temperature/push.go b/cmd/temperature/push.go index 43efe35..80680bb 100644 --- a/cmd/temperature/push.go +++ b/cmd/temperature/push.go @@ -1,23 +1,22 @@ package temperature -import ( - "log" +// import ( +// "log" - "git.cryptic.systems/fh-trier/go-flucky/pkg/temperature" - "github.com/spf13/cobra" -) +// "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) { +// 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) - } - }, -} +// if err := temperature.Push(configDir); err != nil { +// log.Fatal(err) +// } +// }, +// } -func init() { - temperatureCmd.AddCommand(pushTemperatureCmd) -} +// func init() { +// temperatureCmd.AddCommand(pushTemperatureCmd) +// } diff --git a/cmd/temperature/read.go b/cmd/temperature/read.go new file mode 100644 index 0000000..86cd608 --- /dev/null +++ b/cmd/temperature/read.go @@ -0,0 +1,41 @@ +package temperature + +import ( + "log" + "os" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/cli" + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" + "github.com/spf13/cobra" +) + +var follow, push bool + +var readTemperatureCmd = &cobra.Command{ + Use: "read", + Short: "read temperature from sensor", + Run: func(cmd *cobra.Command, args []string) { + + // read configuration + fc, err := config.Read(cfg) + if err != nil { + log.Fatalln(err) + } + + // FIXME: + // add sensor entry to list + temperatures, err := sensor.ReadTemperatures(fc.GetTemperatureSensors()) + if err != nil { + log.Fatalln(err) + } + + cli.PrintTemperatures(temperatures, fc, os.Stdout) + + }, +} + +func init() { + temperatureCmd.AddCommand(readTemperatureCmd) + readTemperatureCmd.Flags().BoolVarP(&follow, "follow", "f", false, "Follow output") +} diff --git a/cmd/temperature/temperature.go b/cmd/temperature/temperature.go index f8b9fc1..e59486d 100644 --- a/cmd/temperature/temperature.go +++ b/cmd/temperature/temperature.go @@ -1,19 +1,22 @@ package temperature import ( + "fmt" + "github.com/spf13/cobra" ) -var configDir string +var cfg string var temperatureCmd = &cobra.Command{ - Use: "temperature", - Short: "Read temperature from sensor", + Use: "temperature", + Short: "", + Example: fmt.Sprintf("flucky temperature read\nflucky temperature read outdoor"), } // Execute a -func InitCmd(cmd *cobra.Command, cnf string) { - configDir = cnf +func InitCmd(cmd *cobra.Command, config string) { + cfg = config cmd.AddCommand(temperatureCmd) diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go new file mode 100644 index 0000000..fbdf0ca --- /dev/null +++ b/pkg/cli/cli.go @@ -0,0 +1,73 @@ +package cli + +import ( + "fmt" + "io" + "text/tabwriter" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/config" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" +) + +func PrintTemperatures(temperatures []*types.Temperature, cnf *config.FluckyConfig, w io.Writer) { + + sensors := []*types.Sensor{} + + // Search after sensors + for _, temperature := range temperatures { + found := false + + // Search for the sensor that has acquired the measured value + for _, sensor := range cnf.Sensors { + if sensor.SensorID == temperature.SensorID { + sensors = append(sensors, sensor) + found = true + break + } + } + + // If it was not found, pass only the sensor with the UUID on + if !found { + sensor := &types.Sensor{ + SensorID: temperature.SensorID, + } + sensors = append(sensors, sensor) + } + } + + // sort temperature values for every sensor + orderedTemperatures := make(map[string][]*types.Temperature) + for _, temperature := range temperatures { + orderedTemperatures[temperature.SensorID] = append(orderedTemperatures[temperature.SensorID], temperature) + } + + // declare tabwriter + tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) + + // headlines + for _, sensor := range sensors { + fmt.Fprintf(tw, "%v\t", sensor.Name()) + } + fmt.Fprintf(tw, "\n") + + // find sensor with maximum temperature values + maxLength := 0 + for _, orderedTemperature := range orderedTemperatures { + if len(orderedTemperature) > maxLength { + maxLength = len(orderedTemperature) + } + } + + // body + for i := 0; i < maxLength; i++ { + for _, sensor := range sensors { + if len(orderedTemperatures[sensor.SensorID]) > i { + fmt.Fprintf(tw, "%3.3f\t", orderedTemperatures[sensor.SensorID][i].TemperatureValue) + } else { + fmt.Fprint(tw, "\t") + } + fmt.Fprint(tw, "\n") + } + } + tw.Flush() +} diff --git a/pkg/config/fluckyconfig.go b/pkg/config/fluckyconfig.go index d24adec..10fc6d8 100644 --- a/pkg/config/fluckyconfig.go +++ b/pkg/config/fluckyconfig.go @@ -6,10 +6,12 @@ import ( "fmt" "io" "text/tabwriter" + "time" + "git.cryptic.systems/fh-trier/go-flucky/pkg/sensor" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" "github.com/satori/go.uuid" - - "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" ) // FluckyConfig dasd @@ -37,12 +39,23 @@ func (fc *FluckyConfig) AddSensor(sensor *types.Sensor) error { return fmt.Errorf("Sensor %v with UUID %v already exists", s.SensorName, s.SensorID) } - if sensor.WireID != nil && - s.WireID == sensor.WireID { - return fmt.Errorf("Sensor with 1wire-id %v already exists as %v", s.WireID, s.SensorName) + 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 @@ -110,8 +123,8 @@ func (fc *FluckyConfig) DisableSensor(nameOrUUID string) error { // disable sensor matched after name if !validUUID.MatchString(nameOrUUID) && - *sensor.SensorName == nameOrUUID { - *sensor.SensorEnabled = false + sensor.SensorName == nameOrUUID { + sensor.SensorEnabled = false found = true break } @@ -119,7 +132,7 @@ func (fc *FluckyConfig) DisableSensor(nameOrUUID string) error { // remove machted uuid if validUUID.MatchString(nameOrUUID) && sensor.SensorID == nameOrUUID { - *sensor.SensorEnabled = false + sensor.SensorEnabled = false found = true break } @@ -170,8 +183,8 @@ func (fc *FluckyConfig) EnableSensor(nameOrUUID string) error { // disable sensor matched after name if !validUUID.MatchString(nameOrUUID) && - *sensor.SensorName == nameOrUUID { - *sensor.SensorEnabled = true + sensor.SensorName == nameOrUUID { + sensor.SensorEnabled = true found = true break } @@ -179,7 +192,7 @@ func (fc *FluckyConfig) EnableSensor(nameOrUUID string) error { // remove machted uuid if validUUID.MatchString(nameOrUUID) && sensor.SensorID == nameOrUUID { - *sensor.SensorEnabled = true + sensor.SensorEnabled = true found = true break } @@ -192,6 +205,45 @@ func (fc *FluckyConfig) EnableSensor(nameOrUUID string) error { return nil } +func (fc *FluckyConfig) GetHumiditySensors() []sensor.HumiditySensor { + hs := []sensor.HumiditySensor{} + // for _, s := range fc.Sensors { + // switch s.SensorType { + // case "DHT11": + // hs = append(hs, sensor.DHT11Sensor{ + // Sensor: s, + // }) + // case "DHT22": + // hs = append(hs, sensor.DHT22Sensor{ + // Sensor: s, + // }) + // } + // } + return hs +} + +func (fc *FluckyConfig) GetTemperatureSensors() []sensor.TemperatureSensor { + ts := []sensor.TemperatureSensor{} + + for _, s := range fc.Sensors { + switch s.SensorType { + case "DHT11": + ts = append(ts, &sensor.DHT11Sensor{ + Sensor: s, + }) + case "DHT22": + ts = append(ts, &sensor.DHT22Sensor{ + Sensor: s, + }) + case "DS18B20": + ts = append(ts, &sensor.DS18B20{ + Sensor: s, + }) + } + } + return ts +} + // JSONDecoder decode a JSON string from a reader into a struct func (fc *FluckyConfig) JSONDecoder(r io.Reader) error { jsonDecoder := json.NewDecoder(r) @@ -234,10 +286,10 @@ func (fc *FluckyConfig) PrintSensors(w io.Writer) error { // declar tabwriter tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) - fmt.Fprint(tw, "id\tname\tlocation\ttype\twire-id\tgpio\tenabled\n") + fmt.Fprint(tw, "name\tlocation\ttype\twire-id\tgpio\tenabled\n") for _, sensor := range fc.Sensors { - fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%v\t%v\n", sensor.SensorID, *sensor.SensorName, *sensor.SensorLocation, *sensor.SensorType, *sensor.WireID, *sensor.GPIONumber, *sensor.SensorEnabled) + fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%v\n", sensor.SensorName, sensor.SensorLocation, sensor.SensorType, *sensor.WireID, *sensor.GPIONumber, sensor.SensorEnabled) } tw.Flush() @@ -253,10 +305,9 @@ func (fc *FluckyConfig) RemoveSensor(nameOrUUID string) error { // remove machted name if !validUUID.MatchString(nameOrUUID) && - *sensor.SensorName == nameOrUUID { + sensor.SensorName == nameOrUUID { fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...) found = true - break } // remove machted uuid @@ -264,12 +315,11 @@ func (fc *FluckyConfig) RemoveSensor(nameOrUUID string) error { sensor.SensorID == nameOrUUID { fc.Sensors = append(fc.Sensors[:i], fc.Sensors[i+1:]...) found = true - break } } if !found { - return fmt.Errorf("Can not find remote %v", nameOrUUID) + return fmt.Errorf("Can not find sensor %v", nameOrUUID) } return nil diff --git a/pkg/config/remote.go b/pkg/config/remote.go index ca15b4c..c443dc6 100644 --- a/pkg/config/remote.go +++ b/pkg/config/remote.go @@ -1,6 +1,6 @@ package config -import "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" +import "git.cryptic.systems/fh-trier/go-flucky/pkg/types" // Remote ... type Remote struct { diff --git a/pkg/internal/errutils/errutils.go b/pkg/internal/errutils/errutils.go new file mode 100644 index 0000000..e855835 --- /dev/null +++ b/pkg/internal/errutils/errutils.go @@ -0,0 +1,31 @@ +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/sensor/dht11.go b/pkg/sensor/dht11.go index f4d574a..7c904c7 100644 --- a/pkg/sensor/dht11.go +++ b/pkg/sensor/dht11.go @@ -3,14 +3,19 @@ package sensor import ( "log" - "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" ) type DHT11Sensor struct { *types.Sensor } -func (s *DHT11Sensor) Read() (interface{}, error) { +func (s *DHT11Sensor) ReadHumidity() (*types.Humidity, error) { + log.Println("DHT11 Read Method not yet implemented") + return nil, nil +} + +func (s *DHT11Sensor) ReadTemperature() (*types.Temperature, error) { log.Println("DHT11 Read Method not yet implemented") return nil, nil } diff --git a/pkg/sensor/dht22.go b/pkg/sensor/dht22.go index afbf97a..22bfd41 100644 --- a/pkg/sensor/dht22.go +++ b/pkg/sensor/dht22.go @@ -3,14 +3,19 @@ package sensor import ( "log" - "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" ) type DHT22Sensor struct { *types.Sensor } -func (s *DHT22Sensor) Read() (interface{}, error) { +func (s *DHT22Sensor) ReadHumidity() (*types.Humidity, error) { + log.Println("DHT11 Read Method not yet implemented") + return nil, nil +} + +func (s *DHT22Sensor) ReadTemperature() (*types.Temperature, error) { log.Println("DHT22 Read Method not yet implemented") return nil, nil } diff --git a/pkg/sensor/ds18b20.go b/pkg/sensor/ds18b20.go index 82f99b1..30a865e 100644 --- a/pkg/sensor/ds18b20.go +++ b/pkg/sensor/ds18b20.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" uuid "github.com/satori/go.uuid" "github.com/yryz/ds18b20" ) @@ -13,7 +13,7 @@ type DS18B20 struct { *types.Sensor } -func (s *DS18B20) Read() (interface{}, error) { +func (s *DS18B20) ReadTemperature() (*types.Temperature, error) { t, err := ds18b20.Temperature(*s.WireID) if err != nil { diff --git a/pkg/sensor/sensor.go b/pkg/sensor/sensor.go index a37c90a..bd45350 100644 --- a/pkg/sensor/sensor.go +++ b/pkg/sensor/sensor.go @@ -1,7 +1,115 @@ package sensor -type Sensor interface { - Read() (interface{}, error) +import ( + "sync" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/internal/errutils" + + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" +) + +type HumiditySensor interface { + ReadHumidity() (*types.Humidity, error) } -// func ReadTemperatures +type TemperatureSensor interface { + ReadTemperature() (*types.Temperature, error) +} + +func ReadHumidities(humiditySensors []HumiditySensor) ([]*types.Humidity, 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 + } + 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 + +} + +func ReadTemperatures(temperatureSensors []TemperatureSensor) ([]*types.Temperature, 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 + } + 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) + + 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 + } + } +} diff --git a/pkg/types/sensor.go b/pkg/types/sensor.go new file mode 100644 index 0000000..5944eaa --- /dev/null +++ b/pkg/types/sensor.go @@ -0,0 +1,29 @@ +package types + +import ( + "time" +) + +// Sensor ... +type Sensor struct { + SensorID string `json:"sensor_id"` + SensorName string `json:"sensor_name"` + SensorLocation string `json:"sensor_location"` + WireID *string `json:"wire_id"` + GPIONumber *string `json:"gpio_number"` + SensorType string `json:"sensor_type"` + SensorEnabled bool `json:"sensor_enabled"` + SensorLastContact time.Time `json:"sensor_last_contact"` + DeviceID string `json:"device_id"` + CreationDate time.Time `json:"creation_date"` +} + +func (s *Sensor) Name() string { + if s.SensorName != "" { + return s.SensorName + } else if *s.WireID != "" { + return *s.WireID + } + + return s.SensorID +} diff --git a/pkg/types/types.go b/pkg/types/types.go new file mode 100644 index 0000000..7e16f5e --- /dev/null +++ b/pkg/types/types.go @@ -0,0 +1,32 @@ +package types + +import ( + "time" +) + +// Device ... +type Device struct { + DeviceID string `json:"device_id"` + DeviceName *string `json:"device_name"` + DeviceLocation *string `json:"device_location"` + DeviceLastContact time.Time `json:"device_last_contact"` + CreationDate time.Time `json:"creation_date"` +} + +// Humidity ... +type Humidity struct { + HumidityID string `json:"humidity_id"` + HumidityValue float64 `json:"humidity_value,string"` + HumidityDate time.Time `json:"humidity_date"` + SensorID string `json:"sensor_id"` + CreationDate time.Time `json:"creation_date"` +} + +// Temperature ... +type Temperature struct { + TemperatureID string `json:"temperature_id"` + TemperatureValue float64 `json:"temperature_value,string"` + TemperatureDate time.Time `json:"temperature_date"` + SensorID string `json:"sensor_id"` + CreationDate time.Time `json:"creation_date"` +} diff --git a/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go b/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go deleted file mode 100644 index bf00350..0000000 --- a/vendor/git.cryptic.systems/fh-trier/go-flucky-server/pkg/types/types.go +++ /dev/null @@ -1,97 +0,0 @@ -package types - -import ( - "time" -) - -// Checkpoint ... -type Checkpoint struct { - CheckpointID string `json:"checkpoint_id"` - CheckpointDate time.Time `json:"checkpoint_date,string"` - RFID string `json:"rfid"` - ProductID string `json:"product_id"` - SensorID string `json:"sensor_id"` - CreationDate time.Time `json:"creation_date"` -} - -// Device ... -type Device struct { - DeviceID string `json:"device_id"` - DeviceName *string `json:"device_name"` - DeviceLocation *string `json:"device_location"` - DeviceLastContact time.Time `json:"device_last_contact"` - CreationDate time.Time `json:"creation_date"` -} - -// Failnoise ... -type Failnoise struct { - FailnoiseID string `json:"failnoise_id"` - FailnoiseCounter int `json:"failnoise_counter,string"` - FailnoiseStartDate time.Time `json:"failnoise_start_date"` - FailnoiseEndDate time.Time `json:"failnoise_end_date"` - SensorID string `json:"sensor_id"` - CreationDate time.Time `json:"creation_date"` -} - -// Humidity ... -type Humidity struct { - HumidityID string `json:"humidity_id"` - HumidityValue float64 `json:"humidity_value,string"` - HumidityDate time.Time `json:"humidity_date"` - SensorID string `json:"sensor_id"` - CreationDate time.Time `json:"creation_date"` -} - -// Knock ... -type Knock struct { - KnockID string `json:"knock_id"` - KnockCounter int `json:"knock_counter,string"` - KnockStartDate time.Time `json:"knock_start_date"` - KnockEndDate time.Time `json:"knock_end_date"` - SensorID string `json:"sensor_id"` - CreationDate time.Time `json:"creation_date"` -} - -// Sensor ... -type Sensor struct { - SensorID string `json:"sensor_id"` - SensorName *string `json:"sensor_name"` - SensorLocation *string `json:"sensor_location"` - WireID *string `json:"wire_id"` - GPIONumber *string `json:"gpio_number"` - SensorType *string `json:"sensor_type"` - SensorEnabled *bool `json:"sensor_enabled"` - SensorLastContact time.Time `json:"sensor_last_contact"` - DeviceID string `json:"device_id"` - CreationDate time.Time `json:"creation_date"` -} - -// ReadableSensorName returns a readable sensor name -func (s *Sensor) ReadableSensorName() string { - if s.SensorName != nil { - return *s.SensorName - } - if s.WireID != nil { - return *s.WireID - } - return s.SensorID -} - -// Temperature ... -type Temperature struct { - TemperatureID string `json:"temperature_id"` - TemperatureValue float64 `json:"temperature_value,string"` - TemperatureDate time.Time `json:"temperature_date"` - SensorID string `json:"sensor_id"` - CreationDate time.Time `json:"creation_date"` -} - -// Throughput ... -type Throughput struct { - ThroughputID string `json:"throughput_id"` - ThroughputAverage float64 `json:"throughput_average,string"` - ThroughputStartDate time.Time `json:"throughput_start_date"` - ThroughputEndDate time.Time `json:"throughput_end_date"` - SensorID string `json:"sensor_id"` - CreationDate time.Time `json:"creation_date"` -}