package cli import ( "fmt" "strconv" "github.com/cnachtigall/heatwave-autopilot/internal/store" "github.com/spf13/cobra" ) var ( deviceRoom int64 deviceType string deviceIdle float64 deviceTypical float64 devicePeak float64 deviceDuty float64 ) func init() { deviceCmd := &cobra.Command{ Use: "device", Short: "Manage heat-producing devices", } addCmd := &cobra.Command{ Use: "add ", Short: "Add a device", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { d, err := db.CreateDevice(deviceRoom, args[0], deviceType, deviceIdle, deviceTypical, devicePeak, deviceDuty) if err != nil { return err } fmt.Printf("Device added: %s (ID: %d, typical: %.0fW)\n", d.Name, d.ID, d.WattsTypical) return nil }, } addCmd.Flags().Int64Var(&deviceRoom, "room", 0, "room ID") addCmd.Flags().StringVar(&deviceType, "type", "other", "device type (pc, monitor, appliance, other)") addCmd.Flags().Float64Var(&deviceIdle, "watts-idle", 0, "idle power draw (W)") addCmd.Flags().Float64Var(&deviceTypical, "watts-typical", 0, "typical power draw (W)") addCmd.Flags().Float64Var(&devicePeak, "watts-peak", 0, "peak power draw (W)") addCmd.Flags().Float64Var(&deviceDuty, "duty-cycle", 1.0, "duty cycle (0.0-1.0)") addCmd.MarkFlagRequired("room") listCmd := &cobra.Command{ Use: "list", Short: "List devices", RunE: func(cmd *cobra.Command, args []string) error { p, err := getActiveProfile() if err != nil { return err } roomFilter, _ := cmd.Flags().GetInt64("room") var devices []store.Device if roomFilter > 0 { devices, err = db.ListDevices(roomFilter) } else { devices, err = db.ListAllDevices(p.ID) } if err != nil { return err } if len(devices) == 0 { fmt.Println("No devices found") return nil } for _, d := range devices { fmt.Printf(" [%d] %s — type: %s, idle: %.0fW, typical: %.0fW, peak: %.0fW, duty: %.0f%%\n", d.ID, d.Name, d.DeviceType, d.WattsIdle, d.WattsTypical, d.WattsPeak, d.DutyCycle*100) } return nil }, } listCmd.Flags().Int64("room", 0, "filter by room ID") editCmd := &cobra.Command{ Use: "edit ", Short: "Edit a device field", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { id, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return fmt.Errorf("invalid device ID: %s", args[0]) } return db.UpdateDevice(id, args[1], args[2]) }, } removeCmd := &cobra.Command{ Use: "remove ", Short: "Remove a device", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { id, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return fmt.Errorf("invalid device ID: %s", args[0]) } return db.DeleteDevice(id) }, } deviceCmd.AddCommand(addCmd, listCmd, editCmd, removeCmd) rootCmd.AddCommand(deviceCmd) }