package cli import ( "errors" "fmt" "io" "regexp" "text/tabwriter" "github.com/go-flucky/flucky/pkg/config" "github.com/go-flucky/flucky/pkg/types" ) var ( errorMeasuredValueIDNotValid = errors.New("Measured value id is not a valid uuid") errorSensorIDNotValid = errors.New("Sensor id is not a valid uuid") validUUID = regexp.MustCompile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") ) // GetSensorIDsByMeasuredValues returns commulated list of sensors by measured values func GetSensorIDsByMeasuredValues(measuredValues []*types.MeasuredValue, cnf *config.Configuration) (map[string]*types.Sensor, error) { sensors := make(map[string]*types.Sensor) for _, measuredValue := range measuredValues { // check if sensor id is valid if !validUUID.MatchString(measuredValue.ID) { return nil, errorMeasuredValueIDNotValid } // check if sensor id is valid if !validUUID.MatchString(measuredValue.SensorID) { return nil, errorSensorIDNotValid } if _, ok := sensors[measuredValue.SensorID]; !ok { sensors[measuredValue.SensorID] = cnf.GetSensorByID(measuredValue.SensorID) } } return sensors, nil } // PrintRGBLEDs displays a list with all configured RGBLEDs func PrintRGBLEDs(cnf *config.Configuration, w io.Writer) { // declare tabwriter tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) // headline fmt.Fprintln(tw, "name\tlocation\tblue\tgreen\tred\tenabled\taction") for _, rgbled := range cnf.RGBLEDs { fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t%v\t%v\t", rgbled.RGBLEDName, rgbled.RGBLEDLocation, *rgbled.BaseColorsToGPIO[types.BaseColorBlue], *rgbled.BaseColorsToGPIO[types.BaseColorGreen], *rgbled.BaseColorsToGPIO[types.BaseColorRed], rgbled.RGBLEDEnabled) for action, color := range rgbled.ActionMapping { fmt.Fprintf(tw, "%v=%v,", action, color) } fmt.Fprintf(tw, "\n") } tw.Flush() } // PrintSensors displays a list with all configured sensors func PrintSensors(cnf *config.Configuration, w io.Writer) error { // declar tabwriter tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) fmt.Fprint(tw, "name\tlocation\ttype\twire-id\ti2c-bus\ti2c-address\tgpio\tenabled\n") for _, sensor := range cnf.Sensors { fmt.Fprintf(tw, "%v\t%v\t%v\t", sensor.Name, sensor.Location, sensor.Model) if sensor.WireID != nil { fmt.Fprintf(tw, "%v\t", *sensor.WireID) } else { fmt.Fprintf(tw, "\t") } if sensor.I2CBus != nil { fmt.Fprintf(tw, "%v\t", *sensor.I2CBus) } else { fmt.Fprintf(tw, "\t") } if sensor.I2CAddress != nil { fmt.Fprintf(tw, "%v\t", *sensor.I2CAddress) } else { fmt.Fprintf(tw, "\t") } if sensor.GPIONumber != nil { fmt.Fprintf(tw, "%v\t", *sensor.GPIONumber) } else { fmt.Fprintf(tw, "\t") } fmt.Fprintf(tw, "%v\n", sensor.Enabled) } tw.Flush() return nil } // PrintMeasuredValues displays a list of measured values func PrintMeasuredValues(measuredValues []*types.MeasuredValue, cnf *config.Configuration, w io.Writer) error { sensors, err := GetSensorIDsByMeasuredValues(measuredValues, cnf) if err != nil { return err } // sort measured values for every sensor orderedMeasuredValues := make(map[string][]*types.MeasuredValue) for _, measuredValue := range measuredValues { orderedMeasuredValues[measuredValue.SensorID] = append(orderedMeasuredValues[measuredValue.SensorID], measuredValue) } // declare tabwriter tw := tabwriter.NewWriter(w, 0, 0, 3, ' ', 0) // headlines i := 0 for _, sensor := range sensors { fmt.Fprintf(tw, "%v\t", sensor.FullName()) if i == len(sensors)-1 { fmt.Fprintf(tw, "\n") } i++ } // find sensor with the most measured values maxLength := 0 for _, orderedMeasuredValue := range orderedMeasuredValues { if len(orderedMeasuredValue) > maxLength { maxLength = len(orderedMeasuredValue) } } // body for i := 0; i < maxLength; i++ { for _, sensor := range sensors { if len(orderedMeasuredValues[sensor.ID]) > i { fmt.Fprintf(tw, "%3.3f\t", orderedMeasuredValues[sensor.ID][i].Value) } else { fmt.Fprint(tw, "\t") } } fmt.Fprint(tw, "\n") } tw.Flush() return err }