1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// http://www.developers.meethue.com/documentation/lights-api
package hue
import (
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
"strings"
"errors"
"bytes"
)
type Light struct {
State struct {
On bool `json:"on"` // On or Off state of the light ("true" or "false")
Bri int `json:"bri"` // Brightness value 1-254
Hue int `json:"hue"` // Hue value 1-65535
Saturation int `json:"sat"` // Saturation value 0-254
Effect string `json:"effect"` // "None" or "Colorloop"
XY [2]float32 `json:"xy"` // Coordinates of color in CIE color space
CT int `json:"ct"` // Mired Color Temperature (google it)
Alert string `json:"alert"`
ColorMode string `json:"colormode"`
Reachable bool `json:"reachable"`
} `json:"state"`
Type string `json:"type"`
Name string `json:"name"`
ModelID string `json:"modelid"`
ManufacturerName string `json:"manufacturername"`
UniqueID string `json:"uniqueid"`
SWVersion string `json:"swversion"`
}
// LightState used in SetLightState to ammend light attributes.
type LightState struct {
On bool
Bri uint8
Hue uint16
Sat uint8
XY [2]float32
CT uint16
Alert string
Effect string
TransitionTime string
BrightnessIncrement int // TODO: -254 to 254
SaturationIncrement int // TODO: -254 to 254
HueIncrement int // TODO: -65534 to 65534
CTIncrement int // TODO: -65534 to 65534
XYIncrement [2]float32
}
// SetLightState will modify light attributes such as on/off, saturation,
// brightness, and more. See `SetLightState` struct.
func SetLightState(bridge *Bridge, lightID string, newState LightState) error {
// Construct the http POST
req, err := json.Marshal(newState)
if err != nil {
trace("", err)
return err
}
// Send the request and read the response
uri := fmt.Sprintf("http://%s/api/%s/lights/%s/state",
bridge.IPAddress, bridge.Username, lightID)
resp, err := http.Post(uri, "text/json", bytes.NewReader(req))
if err != nil {
trace("", err)
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
trace("", err)
return err
}
// TODO: Parse the response and return any error
fmt.Println(string(body))
return nil
}
//http://192.168.1.128/api/319b36233bd2328f3e40731b23479207/lights/
// GetAllLights retreives the state of all lights that the bridge is aware of.
func GetAllLights(bridge *Bridge) ([]Light, error) {
// Loop through all light indicies to see if they exist
// and parse their values. Supports 100 lights.
var lights []Light
for index := 1; index < 101; index++ {
response, err := http.Get(
fmt.Sprintf("http://%s/api/%s/lights/%d", bridge.IPAddress, bridge.Username, index))
if err != nil {
trace("", err)
return lights, err
} else if response.StatusCode != 200 {
trace(fmt.Sprintf("Bridge status error %d", response.StatusCode), nil)
}
// Read the response
body, err := ioutil.ReadAll(response.Body)
defer response.Body.Close()
if err != nil {
trace("", err)
return lights, err
}
if strings.Contains(string(body), "not available") {
// Handle end of searchable lights
//fmt.Printf("\n\n%d lights found.\n\n", index)
break
}
// Parse and load the response into the light array
data := Light{}
err = json.Unmarshal(body, &data)
if err != nil {
trace("", err)
}
lights = append(lights, data)
}
return lights, nil
}
// GetLight will return a light struct containing data on a given name.
func GetLight(bridge *Bridge, name string) (Light, error) {
lights, _ := GetAllLights(bridge)
for index := 0; index < len(lights); index++ {
if lights[index].Name == name {
return lights[index], nil
}
}
return Light{}, errors.New("Light not found.")
}
|