diff --git a/cmd/get.go b/cmd/get.go new file mode 100644 index 0000000..fdc3108 --- /dev/null +++ b/cmd/get.go @@ -0,0 +1,61 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "golang.org/x/net/context" + "openhue-cli/openhue" +) + +type GetFlags struct { + Json bool +} + +var GetConfig GetFlags + +// getCmd represents the get command +var getCmd = &cobra.Command{ + Use: "get", + Short: "Get resources", + Long: ` +Retrieve information for any kind of resources exposed by your Hue Bridge: lights, rooms, scenes, etc. +`, + Run: func(cmd *cobra.Command, args []string) { + resp, err := openhue.Api.GetResourcesWithResponse(context.Background()) + cobra.CheckErr(err) + resources := *(*resp.JSON200).Data + + typeFlag := cmd.Flag("type").Value.String() + + if len(typeFlag) > 0 { + // filter resources by type + n := 0 + for _, r := range resources { + if *r.Type == openhue.ResourceGetType(typeFlag) { + resources[n] = r + n++ + } + } + resources = resources[:n] + } + + if GetConfig.Json { + openhue.PrintJson(resources) + } else { + openhue.PrintTable(resources, PrintResource, "Resource ID", "Resource Type") + } + }, +} + +func init() { + rootCmd.AddCommand(getCmd) + + // local flags + getCmd.Flags().StringP("type", "t", "", "Filter by resource type (light, scene, room...)") + + // persistence flags + getCmd.PersistentFlags().BoolVar(&GetConfig.Json, "json", false, "Format output as JSON") +} + +func PrintResource(resource openhue.ResourceGet) string { + return *resource.Id + "\t" + string(*resource.Type) +} diff --git a/cmd/get_lights.go b/cmd/get_lights.go new file mode 100644 index 0000000..eb9ed4e --- /dev/null +++ b/cmd/get_lights.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" + "golang.org/x/net/context" + "openhue-cli/openhue" + "os" +) + +// lightCmd represents the light command +var lightCmd = &cobra.Command{ + Use: "light", + Short: "Get light", + Long: ` +Fetches and displays all available lights +`, + Args: cobra.MatchAll(cobra.RangeArgs(0, 1), cobra.OnlyValidArgs), + Run: func(cmd *cobra.Command, args []string) { + + var lights *[]openhue.LightGet + + if len(args) > 0 { + resp, err := openhue.Api.GetLightWithResponse(context.Background(), args[0]) + cobra.CheckErr(err) + + if resp.JSON200 == nil { + fmt.Println("\nNot light found with ID", args[0]) + os.Exit(0) + } + + lights = (*resp.JSON200).Data + } else { + resp, err := openhue.Api.GetLightsWithResponse(context.Background()) + cobra.CheckErr(err) + lights = (*resp.JSON200).Data + } + + if !GetConfig.Json { + openhue.PrintTable(*lights, PrintLight, "Light ID", "Light Name", "Light Type") + } else { + openhue.PrintJsonArray(*lights) + } + }, +} + +func init() { + getCmd.AddCommand(lightCmd) +} + +func PrintLight(light openhue.LightGet) string { + return *light.Id + "\t" + *light.Metadata.Name + "\t" + string(*light.Metadata.Archetype) +} diff --git a/cmd/get_rooms.go b/cmd/get_rooms.go new file mode 100644 index 0000000..9c789b3 --- /dev/null +++ b/cmd/get_rooms.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "fmt" + "github.com/spf13/cobra" + "golang.org/x/net/context" + "openhue-cli/openhue" + "os" +) + +// roomCmd represents the room command +var roomCmd = &cobra.Command{ + Use: "room", + Short: "Get room", + Long: ` +Fetches and displays all available rooms from the Philips Hue bridge +`, + Args: cobra.MatchAll(cobra.RangeArgs(0, 1), cobra.OnlyValidArgs), + Run: func(cmd *cobra.Command, args []string) { + + var rooms *[]openhue.RoomGet + + if len(args) > 0 { + resp, err := openhue.Api.GetRoomWithResponse(context.Background(), args[0]) + cobra.CheckErr(err) + + if resp.JSON200 == nil { + fmt.Println("\nNot room found with ID", args[0]) + os.Exit(0) + } + + rooms = (*resp.JSON200).Data + } else { + resp, err := openhue.Api.GetRoomsWithResponse(context.Background()) + cobra.CheckErr(err) + rooms = (*resp.JSON200).Data + } + + if !GetConfig.Json { + openhue.PrintTable(*rooms, PrintRoom, "Room ID", "Room Name", "Room Type") + } else { + openhue.PrintJsonArray(*rooms) + } + }, +} + +func init() { + getCmd.AddCommand(roomCmd) +} + +func PrintRoom(room openhue.RoomGet) string { + return *room.Id + "\t" + *room.Metadata.Name + "\t" + string(*room.Metadata.Archetype) +} diff --git a/cmd/lights.go b/cmd/lights.go deleted file mode 100644 index 9a6c600..0000000 --- a/cmd/lights.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -// lightsCmd represents the lights command -var lightsCmd = &cobra.Command{ - GroupID: "hue", - Use: "lights", - Short: "Control lights", - Long: `Control all available lights`, - Run: func(cmd *cobra.Command, args []string) { - err := cmd.Help() - cobra.CheckErr(err) - }, -} - -func init() { - rootCmd.AddCommand(lightsCmd) -} diff --git a/cmd/lights_list.go b/cmd/lights_list.go deleted file mode 100644 index c337ea2..0000000 --- a/cmd/lights_list.go +++ /dev/null @@ -1,38 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "openhue-cli/openhue" - "os" - "text/tabwriter" - - "github.com/spf13/cobra" -) - -// listCmd represents the list command -var listLightsCmd = &cobra.Command{ - Use: "list", - Short: "List lights", - Long: `Fetches and displays all available lights from the Philips Hue bridge`, - Run: func(cmd *cobra.Command, args []string) { - - resp, err := openhue.Api.GetLightsWithResponse(context.Background()) - cobra.CheckErr(err) - - w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) - _, _ = fmt.Fprintln(w, "Light ID\tLight Name\tLight Type") - _, _ = fmt.Fprintln(w, "----\t----\t----") - - lights := (*resp.JSON200).Data - for _, l := range *lights { - _, _ = fmt.Fprintf(w, "%s\t%s\t%s\n", *l.Id, *l.Metadata.Name, *l.Metadata.Archetype) - } - - _ = w.Flush() - }, -} - -func init() { - lightsCmd.AddCommand(listLightsCmd) -} diff --git a/cmd/rooms.go b/cmd/rooms.go deleted file mode 100644 index 7723ea7..0000000 --- a/cmd/rooms.go +++ /dev/null @@ -1,21 +0,0 @@ -package cmd - -import ( - "github.com/spf13/cobra" -) - -// roomsCmd represents the rooms command -var roomsCmd = &cobra.Command{ - GroupID: "hue", - Use: "rooms", - Short: "Control rooms", - Long: `Control the rooms available from the Philips HUE bridge`, - Run: func(cmd *cobra.Command, args []string) { - err := cmd.Help() - cobra.CheckErr(err) - }, -} - -func init() { - rootCmd.AddCommand(roomsCmd) -} diff --git a/cmd/rooms_list.go b/cmd/rooms_list.go deleted file mode 100644 index c9f0ffd..0000000 --- a/cmd/rooms_list.go +++ /dev/null @@ -1,38 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "openhue-cli/openhue" - "os" - "text/tabwriter" - - "github.com/spf13/cobra" -) - -// listCmd represents the list command -var listRoomsCmd = &cobra.Command{ - Use: "list", - Short: "Display all rooms", - Long: `Fetches and displays all available rooms from the Philips Hue bridge`, - Run: func(cmd *cobra.Command, args []string) { - - resp, err := openhue.Api.GetRoomsWithResponse(context.Background()) - cobra.CheckErr(err) - - w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) - _, _ = fmt.Fprintln(w, "Room ID\tRoom Name") - _, _ = fmt.Fprintln(w, "----\t----") - - rooms := (*resp.JSON200).Data - for _, l := range *rooms { - _, _ = fmt.Fprintf(w, "%s\t%s\n", *l.Id, *l.Metadata.Name) - } - - _ = w.Flush() - }, -} - -func init() { - roomsCmd.AddCommand(listRoomsCmd) -} diff --git a/go.mod b/go.mod index 31f9086..7feffbb 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/oapi-codegen/runtime v1.0.0 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.17.0 + golang.org/x/net v0.17.0 ) require ( @@ -33,7 +34,6 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.14.0 // indirect diff --git a/openhue/utils.go b/openhue/utils.go new file mode 100644 index 0000000..913f4fa --- /dev/null +++ b/openhue/utils.go @@ -0,0 +1,46 @@ +package openhue + +import ( + "encoding/json" + "fmt" + "os" + "text/tabwriter" +) + +// PrintJsonArray formats the input array as JSON and prints it. If the length of the array is equal to 1, +// it will print it as a single object +func PrintJsonArray[T any](array []T) { + if len(array) == 1 { + PrintJson(array[0]) + } else { + PrintJson(array) + } +} + +func PrintJson[T any](array T) { + var out []byte + out, _ = json.MarshalIndent(array, "", " ") + fmt.Println(string(out)) +} + +// PrintTable prints each line of the objects contained in the table value +func PrintTable[T any](table []T, lineFn func(T) string, header ...string) { + + w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) + + for _, h := range header { + _, _ = fmt.Fprint(w, h+"\t") + } + _, _ = fmt.Fprintln(w) + + for range header { + _, _ = fmt.Fprint(w, "----\t") + } + _, _ = fmt.Fprintln(w) + + for _, l := range table { + _, _ = fmt.Fprintln(w, lineFn(l)) + } + + _ = w.Flush() +} diff --git a/openhue/utils_test.go b/openhue/utils_test.go new file mode 100644 index 0000000..13dcc98 --- /dev/null +++ b/openhue/utils_test.go @@ -0,0 +1,19 @@ +package openhue + +import "testing" + +type Light struct { + id string + name string +} + +func PrintLightLineProcessor(light Light) string { + return light.id + "\t" + light.name +} + +func TestPrintTable(t *testing.T) { + + lights := []Light{{id: "1234", name: "Light 1"}, {id: "4321", name: "Light 2"}} + + PrintTable(lights, PrintLightLineProcessor, "id", "name") +}