Skip to content

Commit

Permalink
Adaptations for openhue-cli (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
thibauult authored Jul 5, 2024
1 parent 962b0ce commit 220538a
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 55 deletions.
29 changes: 13 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,32 @@
OpenHue Go is a library written in Goland for interacting with the Philips Hue smart lighting systems.

## Usage
Use the following command to import the library:
```shell
go get github.com/openhue/openhue-go
```

```go
package main

import "os"
import "github.com/openhue/openhue-go"
import "os"
import "log"

func main() {

home, err := openhue.NewHome(os.Getenv("BRIDGE"), os.Getenv("KEY"))
if err != nil {
log.Fatal(err)
}

lights, err := home.GetLights()
if err != nil {
log.Fatal(err)
}

for _, light := range lights {
home, _ := openhue.NewHome(os.Getenv("BRIDGE"), os.Getenv("KEY"))
lights, _ := home.GetLights()

body := openhue.UpdateLightJSONRequestBody{
On: light.On.Switch(),
}
home.SetLight(*light.Id, body)
for id, light := range lights {
fmt.Printf("Toggling light %s (%s)\n", *light.Metadata.Name, id)
home.UpdateLight(*light.Id, openhue.LightPut{
On: light.Toggle(),
})
}
}
```
This example demonstrates how to toggle all the lights of your house, in a very few lines of code.

## License
[![GitHub License](https://img.shields.io/github/license/openhue/openhue-cli)](https://github.com/openhue/openhue-cli/blob/main/LICENSE)
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/openhue/openhue-go
go 1.22

require (
github.com/oapi-codegen/oapi-codegen/v2 v2.3.0
github.com/oapi-codegen/runtime v1.1.1
github.com/stretchr/testify v1.9.0
gopkg.in/yaml.v3 v3.0.1
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
github.com/oapi-codegen/oapi-codegen/v2 v2.3.0 h1:rICjNsHbPP1LttefanBPnwsSwl09SqhCO7Ee623qR84=
github.com/oapi-codegen/oapi-codegen/v2 v2.3.0/go.mod h1:4k+cJeSq5ntkwlcpQSxLxICCxQzCL772o30PxdibRt4=
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
6 changes: 0 additions & 6 deletions helper.go

This file was deleted.

7 changes: 7 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package openhue

// Toggleable defines resources that have an On field and can therefore be switched to on or off, mainly lights.
type Toggleable interface {
Toggle() *On
IsOn() bool
}
14 changes: 6 additions & 8 deletions internal/test/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"github.com/openhue/openhue-go"
"gopkg.in/yaml.v3"
"log"
Expand All @@ -21,14 +22,11 @@ func main() {
return
}

for _, light := range lights {

if *light.Metadata.Name == "Bureau" {
body := openhue.UpdateLightJSONRequestBody{
On: light.On.Switch(),
}
home.SetLight(*light.Id, body)
}
for id, light := range lights {
fmt.Printf("Toggling light %s (%s)\n", *light.Metadata.Name, id)
home.UpdateLight(*light.Id, openhue.LightPut{
On: light.Toggle(),
})
}
}

Expand Down
138 changes: 116 additions & 22 deletions openhue.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
"errors"
sp "github.com/oapi-codegen/oapi-codegen/v2/pkg/securityprovider"
"log/slog"
"net/http"
)
Expand Down Expand Up @@ -53,11 +52,35 @@ func (h *Home) GetBridgeHome() (*BridgeHomeGet, error) {
return &(*(*resp.JSON200).Data)[0], nil
}

//--------------------------------------------------------------------------------------------------------------------//
// RESOURCE
//--------------------------------------------------------------------------------------------------------------------//

func (h *Home) GetResources() (map[string]ResourceGet, error) {
resp, err := h.api.GetResourcesWithResponse(context.Background())
if err != nil {
return nil, err
}

if resp.HTTPResponse.StatusCode != http.StatusOK {
return nil, newApiError(resp)
}

data := *(*resp.JSON200).Data
resources := make(map[string]ResourceGet)

for _, resource := range data {
resources[*resource.Id] = resource
}

return resources, nil
}

//--------------------------------------------------------------------------------------------------------------------//
// DEVICE
//--------------------------------------------------------------------------------------------------------------------//

func (h *Home) GetDevices() ([]DeviceGet, error) {
func (h *Home) GetDevices() (map[string]DeviceGet, error) {
resp, err := h.api.GetDevicesWithResponse(context.Background())
if err != nil {
return nil, err
Expand All @@ -67,14 +90,21 @@ func (h *Home) GetDevices() ([]DeviceGet, error) {
return nil, newApiError(resp)
}

return *(*resp.JSON200).Data, nil
data := *(*resp.JSON200).Data
devices := make(map[string]DeviceGet)

for _, device := range data {
devices[*device.Id] = device
}

return devices, nil
}

//--------------------------------------------------------------------------------------------------------------------//
// ROOM
//--------------------------------------------------------------------------------------------------------------------//

func (h *Home) GetRooms() ([]RoomGet, error) {
func (h *Home) GetRooms() (map[string]RoomGet, error) {
resp, err := h.api.GetRoomsWithResponse(context.Background())
if err != nil {
return nil, err
Expand All @@ -84,14 +114,21 @@ func (h *Home) GetRooms() ([]RoomGet, error) {
return nil, newApiError(resp)
}

return *(*resp.JSON200).Data, nil
data := *(*resp.JSON200).Data
rooms := make(map[string]RoomGet)

for _, room := range data {
rooms[*room.Id] = room
}

return rooms, nil
}

//--------------------------------------------------------------------------------------------------------------------//
// LIGHT
//--------------------------------------------------------------------------------------------------------------------//

func (h *Home) GetLights() ([]LightGet, error) {
func (h *Home) GetLights() (map[string]LightGet, error) {
resp, err := h.api.GetLightsWithResponse(context.Background())
if err != nil {
return nil, err
Expand All @@ -101,14 +138,26 @@ func (h *Home) GetLights() ([]LightGet, error) {
return nil, newApiError(resp)
}

return *(*resp.JSON200).Data, nil
data := *(*resp.JSON200).Data
lights := make(map[string]LightGet)

for _, light := range data {
lights[*light.Id] = light
}

return lights, nil
}

func (l *LightGet) IsOn() bool {
return *l.On.On
}

func (h *Home) SetLight(lightId string, body UpdateLightJSONRequestBody) error {
func (l *LightGet) Toggle() *On {
v := !(*l.On.On)
return &On{On: &v}
}

func (h *Home) UpdateLight(lightId string, body LightPut) error {
_, err := h.api.UpdateLightWithResponse(context.Background(), lightId, body)
if err != nil {
return err
Expand All @@ -120,7 +169,7 @@ func (h *Home) SetLight(lightId string, body UpdateLightJSONRequestBody) error {
// GROUPED LIGHT
//--------------------------------------------------------------------------------------------------------------------//

func (h *Home) GetGroupedLights() ([]GroupedLightGet, error) {
func (h *Home) GetGroupedLights() (map[string]GroupedLightGet, error) {
resp, err := h.api.GetGroupedLightsWithResponse(context.Background())
if err != nil {
return nil, err
Expand All @@ -130,14 +179,38 @@ func (h *Home) GetGroupedLights() ([]GroupedLightGet, error) {
return nil, newApiError(resp)
}

return *(*resp.JSON200).Data, nil
data := *(*resp.JSON200).Data
lights := make(map[string]GroupedLightGet)

for _, light := range data {
lights[*light.Id] = light
}

return lights, nil
}

func (l *GroupedLightGet) IsOn() bool {
return *l.On.On
}

func (l *GroupedLightGet) Toggle() *On {
v := !(*l.On.On)
return &On{On: &v}
}

func (h *Home) UpdateGroupedLight(lightId string, body GroupedLightPut) error {
_, err := h.api.UpdateGroupedLightWithResponse(context.Background(), lightId, body)
if err != nil {
return err
}
return nil
}

//--------------------------------------------------------------------------------------------------------------------//
// SCENE
//--------------------------------------------------------------------------------------------------------------------//

func (h *Home) GetScenes() ([]SceneGet, error) {
func (h *Home) GetScenes() (map[string]SceneGet, error) {
resp, err := h.api.GetScenesWithResponse(context.Background())
if err != nil {
return nil, err
Expand All @@ -147,23 +220,44 @@ func (h *Home) GetScenes() ([]SceneGet, error) {
return nil, newApiError(resp)
}

return *(*resp.JSON200).Data, nil
data := *(*resp.JSON200).Data
scenes := make(map[string]SceneGet)

for _, scene := range data {
scenes[*scene.Id] = scene
}

return scenes, nil
}

// NewOpenHueClient Creates a new NewClientWithResponses for a given server and hueApplicationKey.
func (h *Home) UpdateScene(sceneId string, body ScenePut) error {
resp, err := h.api.UpdateSceneWithResponse(context.Background(), sceneId, body)
if err != nil {
return err
}

if resp.HTTPResponse.StatusCode != http.StatusOK {
return newApiError(resp)
}

return nil
}

//
// Internal
//

// newClient creates a new ClientWithResponses for a given Bridge IP and API key.
// This function will also skip SSL verification, as the Philips HUE Bridge exposes a self-signed certificate.
func newClient(bridgeIP, apiKey string) (*ClientWithResponses, error) {
p, err := sp.NewSecurityProviderApiKey("header", "hue-application-Key", apiKey)
if err != nil {
return nil, err

apiKeyAuth := func(ctx context.Context, req *http.Request) error {
req.Header.Set("hue-application-key", apiKey)
return nil
}

// skip SSL Verification
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}

client, err := NewClientWithResponses("https://"+bridgeIP, WithRequestEditorFn(p.Intercept))
if err != nil {
return nil, err
}

return client, nil
return NewClientWithResponses("https://"+bridgeIP, WithRequestEditorFn(apiKeyAuth))
}

0 comments on commit 220538a

Please sign in to comment.