package sensor import ( "context" "fmt" "net/url" "os" "git.cryptic.systems/volker.raschek/flucky/pkg/cli" "git.cryptic.systems/volker.raschek/flucky/pkg/config" "git.cryptic.systems/volker.raschek/flucky/pkg/repository" "git.cryptic.systems/volker.raschek/flucky/pkg/types" "git.cryptic.systems/volker.raschek/go-logger" uuid "github.com/satori/go.uuid" "github.com/spf13/cobra" ) // InitCmd initialize all sensor subcommands func InitCmd(cmd *cobra.Command) error { sensorCmd := &cobra.Command{ Use: "sensor", Short: "Manage Sensors", } addSensorCmd := &cobra.Command{ Use: "add", Short: "Add Sensor", Aliases: []string{"append"}, Args: cobra.ExactArgs(2), Example: `flucky sensor add --gpio GPIO14 indoor DHT11 flucky sensor add --wire-id 28-011432f0bb3d outdoor DS18B20 flucky sensor add --i2c-bus 1 --i2c-address 0x76 wetter-station BME280`, RunE: addSensor, } addSensorCmd.Flags().Bool("enabled", true, "Enable new sensor") addSensorCmd.Flags().String("gpio", "", "Defines the GPIO port") addSensorCmd.Flags().Uint8("i2c-address", 0, "Defines the I2C address on the I2C bus") addSensorCmd.Flags().Int("i2c-bus", 0, "Defines the I2C bus") addSensorCmd.Flags().String("location", "", "Location of the sensor") addSensorCmd.Flags().String("tick-duration", "1m", "Specifies how often measured values should be read from the sensor") addSensorCmd.Flags().String("wire-id", "", "Defines the Wire-ID") disableSensorCmd := &cobra.Command{ Use: "disable", Short: "Disable Sensor", Args: cobra.MinimumNArgs(1), Example: "flucky sensor disable outdoor", RunE: disableSensor, } enableSensorCmd := &cobra.Command{ Use: "enable", Short: "Enable Sensor", Example: "flucky sensor enable outdoor", Args: cobra.MinimumNArgs(1), RunE: enableSensor, } listSensorCmd := &cobra.Command{ Use: "list", Short: "List Sensors", Aliases: []string{"ls"}, RunE: listSensors, } removeSensorCmd := &cobra.Command{ Use: "remove", Short: "Remove Sensor", Aliases: []string{"rm"}, Example: "flucky sensor remove outdoor", Args: cobra.MinimumNArgs(1), RunE: removeSensor, } renameSensorCmd := &cobra.Command{ Use: "rename", Short: "Rename Sensor", Args: cobra.ExactArgs(2), Example: `flucky sensor rename indoor outdoor flucky sensor rename f98b00ea-a9b2-4e00-924f-113859d0af2d outdoor`, RunE: renameSensor, } for _, subCommand := range []*cobra.Command{ addSensorCmd, disableSensorCmd, enableSensorCmd, listSensorCmd, removeSensorCmd, renameSensorCmd, } { sensorCmd.AddCommand(subCommand) } cmd.AddCommand(sensorCmd) return nil } func addSensor(cmd *cobra.Command, args []string) error { sensor := &types.Sensor{ ID: uuid.NewV4().String(), Name: args[0], Model: args[1], } sensorLocation, err := cmd.Flags().GetString("location") if err != nil { return err } sensor.Location = sensorLocation sensorEnabled, err := cmd.Flags().GetBool("enabled") if err != nil { return err } sensor.Enabled = sensorEnabled sensorGPIO, err := cmd.Flags().GetString("gpio") if err != nil { return err } if len(sensorGPIO) > 0 { sensor.GPIONumber = sensorGPIO } sensorI2CAddress, err := cmd.Flags().GetUint8("i2c-address") if err != nil { return err } if sensorI2CAddress > 0 { sensor.I2CAddress = &sensorI2CAddress } sensorI2CBus, err := cmd.Flags().GetInt("i2c-bus") if err != nil { return err } if sensorI2CBus > 0 { sensor.I2CBus = &sensorI2CBus } sensorTickDuration, err := cmd.Flags().GetString("tick-duration") if err != nil { return err } sensor.TickDuration = sensorTickDuration sensorWireID, err := cmd.Flags().GetString("wire-id") if err != nil { return err } if len(sensorWireID) > 0 { sensor.WireID = &sensorWireID } configFile, err := cmd.Flags().GetString("config") if err != nil { return fmt.Errorf("No config file defined") } cnf, err := config.Read(configFile) if err != nil { return err } sensor.DeviceID = cnf.DeviceID dsnURL, err := url.Parse(cnf.DSN) if err != nil { return err } // loglevel, err := cmd.Flags().GetString("loglevel") // if err != nil { // return fmt.Errorf("No loglevel defined") // } flogger := logger.NewLogger(logger.LogLevelDebug) repo, err := repository.New(dsnURL, flogger) if err != nil { return err } // add sensor entry to list err = repo.AddSensors(context.Background()) if err != nil { return err } // save new configuration // err = config.Write(cnf, configFile) // if err != nil { // return err // } return nil } func disableSensor(cmd *cobra.Command, args []string) error { configFile, err := cmd.Flags().GetString("config") if err != nil { return fmt.Errorf("No config file defined") } cnf, err := config.Read(configFile) if err != nil { return err } dsnURL, err := url.Parse(cnf.DSN) if err != nil { return err } // loglevel, err := cmd.Flags().GetString("loglevel") // if err != nil { // return fmt.Errorf("No loglevel defined") // } flogger := logger.NewLogger(logger.LogLevelDebug) repo, err := repository.New(dsnURL, flogger) if err != nil { return err } s, err := repo.GetSensorsByNames(context.Background(), args...) if err != nil { return err } for i := range s { s[i].Enabled = false } err = repo.UpdateSensors(context.Background(), s...) if err != nil { return err } return nil } func enableSensor(cmd *cobra.Command, args []string) error { configFile, err := cmd.Flags().GetString("config") if err != nil { return fmt.Errorf("No config file defined") } cnf, err := config.Read(configFile) if err != nil { return err } dsnURL, err := url.Parse(cnf.DSN) if err != nil { return err } // loglevel, err := cmd.Flags().GetString("loglevel") // if err != nil { // return fmt.Errorf("No loglevel defined") // } flogger := logger.NewLogger(logger.LogLevelDebug) repo, err := repository.New(dsnURL, flogger) if err != nil { return err } s, err := repo.GetSensorsByNames(context.Background(), args...) if err != nil { return err } for i := range s { s[i].Enabled = true } err = repo.UpdateSensors(context.Background(), s...) if err != nil { return err } return nil } func listSensors(cmd *cobra.Command, args []string) error { configFile, err := cmd.Flags().GetString("config") if err != nil { return fmt.Errorf("No config file defined") } cnf, err := config.Read(configFile) if err != nil { return err } dsnURL, err := url.Parse(cnf.DSN) if err != nil { return err } // loglevel, err := cmd.Flags().GetString("loglevel") // if err != nil { // return fmt.Errorf("No loglevel defined") // } flogger := logger.NewLogger(logger.LogLevelDebug) repo, err := repository.New(dsnURL, flogger) if err != nil { return err } // add sensor entry to list sensors, err := repo.GetSensorsByDeviceIDs(context.Background(), cnf.DeviceID) if err != nil { return err } err = cli.PrintSensors(sensors, os.Stdout) if err != nil { return err } return nil } func removeSensor(cmd *cobra.Command, args []string) error { configFile, err := cmd.Flags().GetString("config") if err != nil { return fmt.Errorf("No config file defined") } cnf, err := config.Read(configFile) if err != nil { return err } dsnURL, err := url.Parse(cnf.DSN) if err != nil { return err } // loglevel, err := cmd.Flags().GetString("loglevel") // if err != nil { // return fmt.Errorf("No loglevel defined") // } flogger := logger.NewLogger(logger.LogLevelDebug) repo, err := repository.New(dsnURL, flogger) if err != nil { return err } return repo.RemoveSensorsByNames(context.Background(), args...) } func renameSensor(cmd *cobra.Command, args []string) error { configFile, err := cmd.Flags().GetString("config") if err != nil { return fmt.Errorf("No config file defined") } cnf, err := config.Read(configFile) if err != nil { return err } dsnURL, err := url.Parse(cnf.DSN) if err != nil { return err } // loglevel, err := cmd.Flags().GetString("loglevel") // if err != nil { // return fmt.Errorf("No loglevel defined") // } flogger := logger.NewLogger(logger.LogLevelDebug) repo, err := repository.New(dsnURL, flogger) if err != nil { return err } s, err := repo.GetSensorsByNames(context.Background(), args[0]) if err != nil { return err } for i := range s { s[i].Name = args[1] } err = repo.UpdateSensors(context.Background(), s...) if err != nil { return err } return nil }