diff --git a/cmd/remote/list.go b/cmd/remote/list.go index 03c501c..2dcc663 100644 --- a/cmd/remote/list.go +++ b/cmd/remote/list.go @@ -11,8 +11,9 @@ import ( var quiet bool var listRemoteCmd = &cobra.Command{ - Use: "list", - Short: "List Remove Servers", + Use: "list", + Short: "List Remove Servers", + Aliases: []string{"ls"}, Run: func(cmd *cobra.Command, args []string) { if err := remote.Print(os.Stdout, configDir, quiet); err != nil { diff --git a/cmd/remote/remove.go b/cmd/remote/remove.go index a3e16ad..13ec6fd 100644 --- a/cmd/remote/remove.go +++ b/cmd/remote/remove.go @@ -10,9 +10,10 @@ import ( var all bool var rmRemoteCmd = &cobra.Command{ - Use: "rm", - Short: "Remove Remote Server", - Args: cobra.RangeArgs(0, 1), + Use: "rm", + Short: "Remove Remote Server", + Aliases: []string{"remove"}, + Args: cobra.RangeArgs(0, 1), Run: func(cmd *cobra.Command, args []string) { if all { diff --git a/cmd/remote/sync.go b/cmd/remote/sync.go index ba336a3..f2a5fd7 100644 --- a/cmd/remote/sync.go +++ b/cmd/remote/sync.go @@ -10,8 +10,9 @@ import ( var force bool var syncRemoteCmd = &cobra.Command{ - Use: "sync", - Short: "Synchronise Device Values with Remote Servers", + Use: "sync", + Aliases: []string{"synchronize"}, + Short: "Synchronise Device Values with Remote Servers", Run: func(cmd *cobra.Command, args []string) { if err := httpcall.SyncDevice(configDir, force); err != nil { diff --git a/cmd/sensor/list.go b/cmd/sensor/list.go index b24d971..ced8055 100644 --- a/cmd/sensor/list.go +++ b/cmd/sensor/list.go @@ -11,8 +11,9 @@ import ( var quiet bool var listSensorCmd = &cobra.Command{ - Use: "list", - Short: "List Sensors", + 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) diff --git a/cmd/sensor/rm.go b/cmd/sensor/rm.go index 72cbb38..369c278 100644 --- a/cmd/sensor/rm.go +++ b/cmd/sensor/rm.go @@ -8,9 +8,10 @@ import ( ) var rmSensorCmd = &cobra.Command{ - Use: "rm", - Short: "Remove Sensor", - Args: cobra.ExactArgs(1), + 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) diff --git a/cmd/sensor/sync.go b/cmd/sensor/sync.go index 861f8d6..b90aa4e 100644 --- a/cmd/sensor/sync.go +++ b/cmd/sensor/sync.go @@ -10,8 +10,9 @@ import ( var force bool var syncSensorCmd = &cobra.Command{ - Use: "sync", - Short: "Synchronise Sensors with Remote Servers", + Use: "sync", + Short: "Synchronise Sensors with Remote Servers", + Aliases: []string{"synchronize"}, Run: func(cmd *cobra.Command, args []string) { if err := httpcall.SyncSensors(configDir, force); err != nil { diff --git a/pkg/httpcall/temperature.go b/pkg/httpcall/temperature.go index de5581f..7e5e764 100644 --- a/pkg/httpcall/temperature.go +++ b/pkg/httpcall/temperature.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "math" "net/http" "git.cryptic.systems/fh-trier/go-flucky/pkg/config" @@ -20,34 +21,54 @@ func SendTemperatures(temperatures []*stypes.Temperature, configDir string) erro return err } - temperaturesAsBytes, err := json.Marshal(temperatures) - if err != nil { - return fmt.Errorf("Can not marshal temperatures to JSON: %v", err) + // split temperatures in blocks to reduce server data size in single request + blockSize := 500 + temperatureBlocks := make(map[int][]*stypes.Temperature) + length := int(math.Ceil(float64(len(temperatures)) / float64(blockSize))) + for i := 0; i < length; i++ { + start := i * blockSize + end := (i + 1) * blockSize + + if end > len(temperatures) { + end = len(temperatures) + } + + temperatureBlocks[i] = temperatures[start:end] } - temperaturesAsReader := bytes.NewReader(temperaturesAsBytes) - for _, remote := range cnf.Remotes { + if remote.Enabled { - requestURL := fmt.Sprintf("%s%s", remote.Address, "/temperatures") - req, err := http.NewRequest("POST", requestURL, temperaturesAsReader) - if err != nil { - return err - } - client := http.Client{} - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() + for _, temperatureBlock := range temperatureBlocks { - if resp.StatusCode < 200 || resp.StatusCode > 299 { - b, err := ioutil.ReadAll(resp.Body) + temperaturesAsBytes, err := json.Marshal(temperatureBlock) if err != nil { - return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d - can not read response body: %v", resp.StatusCode, err) + return fmt.Errorf("Can not marshal temperatures to JSON: %v", err) + } + + temperaturesAsReader := bytes.NewReader(temperaturesAsBytes) + + requestURL := fmt.Sprintf("%s%s", remote.Address, "/temperatures") + req, err := http.NewRequest("POST", requestURL, temperaturesAsReader) + if err != nil { + return err + } + + client := http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode > 299 { + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d - can not read response body: %v", resp.StatusCode, err) + } + return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d: %v", resp.StatusCode, string(b)) } - return fmt.Errorf("Invalid HTTP-Statuscode - expected 200, got %d: %v", resp.StatusCode, string(b)) } } } diff --git a/pkg/temperature/temperature.go b/pkg/temperature/temperature.go index b6c9112..ca5f503 100644 --- a/pkg/temperature/temperature.go +++ b/pkg/temperature/temperature.go @@ -12,6 +12,7 @@ import ( stypes "git.cryptic.systems/fh-trier/go-flucky-server/pkg/types" "git.cryptic.systems/fh-trier/go-flucky/pkg/httpcall" "git.cryptic.systems/fh-trier/go-flucky/pkg/logs" + "git.cryptic.systems/fh-trier/go-flucky/pkg/types" "git.cryptic.systems/fh-trier/go-flucky/pkg/config" @@ -30,49 +31,20 @@ func Get(sensorNames []string, push bool, configDir string, w io.Writer) error { return err } + // get sensors + sensors, err := getSensors(sensorNames, cnf) + if err != nil { + return err + } + + // get temperatures + temperatures, err := getTemperatures(sensors) + if err != nil { + return err + } + tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0) - // filter sensors - var sensors []*stypes.Sensor - if len(sensorNames) > 0 { - for _, sensorName := range sensorNames { - for _, sensor := range cnf.Sensors { - if sensorName == *sensor.SensorName && *sensor.SensorEnabled || - sensorName == sensor.SensorID && *sensor.SensorEnabled || - sensorName == *sensor.WireID && *sensor.SensorEnabled { - sensors = append(sensors, sensor) - } - } - } - } else { - for _, sensor := range cnf.Sensors { - if *sensor.SensorEnabled { - sensors = append(sensors, sensor) - } - } - } - - if len(sensors) == 0 { - return fmt.Errorf("No matched Sensors. Check if your sensor is configured or enabled") - } - - // check if sensor exists in cnf and has a wire id - for _, filterdSensor := range sensors { - if filterdSensor.WireID == nil || *filterdSensor.WireID == "" { - return fmt.Errorf("Sensor %v has no wire id", filterdSensor.SensorID) - } - - var found bool - for _, cnfSensor := range cnf.Sensors { - if filterdSensor.SensorID == cnfSensor.SensorID { - found = true - } - } - if !found { - return fmt.Errorf("Can not found sensor %v in config", filterdSensor.SensorID) - } - } - // headlines for _, sensor := range sensors { if sensor.SensorName != nil && *sensor.SensorName != "" { @@ -84,10 +56,6 @@ func Get(sensorNames []string, push bool, configDir string, w io.Writer) error { fmt.Fprint(tw, "\n") // body - temperatures, err := getTemperatures(sensors) - if err != nil { - return err - } for _, temperature := range temperatures { fmt.Fprintf(tw, "%v\t", temperature.TemperatureValue) } @@ -110,6 +78,43 @@ func Get(sensorNames []string, push bool, configDir string, w io.Writer) error { } +// Fetch ... +func Fetch(sensorNames []string, push bool, configDir string) error { + + // get cnf + cnf, err := config.Read(configDir) + if err != nil { + return err + } + + // get sensors + sensors, err := getSensors(sensorNames, cnf) + if err != nil { + return err + } + + // get temperatures + temperatures, err := getTemperatures(sensors) + if err != nil { + return err + } + + // write logfiles or push + if !push { + if err := logs.AppendTemperature(temperatures, cnf); err != nil { + return err + } + } else { + if err := httpcall.SendTemperatures(temperatures, configDir); err != nil { + return err + } + } + + return nil + +} + +// Follow ... func Follow(sensorNames []string, push bool, configDir string, w io.Writer) error { // get cnf @@ -118,39 +123,29 @@ func Follow(sensorNames []string, push bool, configDir string, w io.Writer) erro return err } - var temperatures []*stypes.Temperature + // get sensors + sensors, err := getSensors(sensorNames, cnf) + if err != nil { + return err + } - // tabwriter tw := tabwriter.NewWriter(w, 0, 0, 5, ' ', 0) // headlines - var sensors []*stypes.Sensor - - numOfSensors := len(cnf.Sensors) - for _, sensor := range cnf.Sensors { - switch { - case sensor.SensorName != nil && numOfSensors <= 1: - sensors = append(sensors, sensor) - case sensor.SensorName == nil && numOfSensors <= 1: - sensors = append(sensors, sensor) - case sensor.SensorName != nil && numOfSensors > 1: + for _, sensor := range sensors { + if sensor.SensorName != nil && *sensor.SensorName != "" { fmt.Fprintf(tw, "%v\t", *sensor.SensorName) - sensors = append(sensors, sensor) - break - case sensor.SensorName == nil && numOfSensors > 1: + } else { fmt.Fprintf(tw, "%v\t", sensor.SensorID) - sensors = append(sensors, sensor) - break } } - - if numOfSensors > 1 { - fmt.Fprint(tw, "\n") - } + fmt.Fprint(tw, "\n") // body + temperatures := []*stypes.Temperature{} ticker := time.NewTicker(1 * time.Second) + // TODO: create channel for own sensor go func() { for { select { @@ -160,8 +155,16 @@ func Follow(sensorNames []string, push bool, configDir string, w io.Writer) erro } // get temperatures from sensors and write them into writer - temperatures, err = getTemperatures(sensors) - for _, temperature := range temperatures { + t, err := getTemperatures(sensors) + // TODO: get error back over channel + if err != nil { + return + } + + // append temperatures to temperature list + temperatures = append(temperatures, t...) + + for _, temperature := range t { fmt.Fprintf(tw, "%3.3f\t", temperature.TemperatureValue) } @@ -244,3 +247,46 @@ func getTemperatures(sensors []*stypes.Sensor) ([]*stypes.Temperature, error) { return temperatures, nil } + +func getSensors(sensorNames []string, cnf *types.Config) ([]*stypes.Sensor, error) { + sensors := []*stypes.Sensor{} + if len(sensorNames) > 0 { + for _, sensorName := range sensorNames { + for _, sensor := range cnf.Sensors { + if sensorName == *sensor.SensorName && *sensor.SensorEnabled || + sensorName == sensor.SensorID && *sensor.SensorEnabled || + sensorName == *sensor.WireID && *sensor.SensorEnabled { + sensors = append(sensors, sensor) + } + } + } + } else { + for _, sensor := range cnf.Sensors { + if *sensor.SensorEnabled { + sensors = append(sensors, sensor) + } + } + } + + if len(sensors) == 0 { + return nil, fmt.Errorf("No matched Sensors. Check if your sensor is configured or enabled") + } + + // check if sensor exists in cnf and has a wire id + for _, filterdSensor := range sensors { + if filterdSensor.WireID == nil || *filterdSensor.WireID == "" { + return nil, fmt.Errorf("Sensor %v has no wire id", filterdSensor.SensorID) + } + + var found bool + for _, cnfSensor := range cnf.Sensors { + if filterdSensor.SensorID == cnfSensor.SensorID { + found = true + } + } + if !found { + return nil, fmt.Errorf("Can not found sensor %v in config", filterdSensor.SensorID) + } + } + return sensors, nil +}