diff options
-rw-r--r-- | bridge.go | 40 | ||||
-rw-r--r-- | bridge_test.go | 10 | ||||
-rw-r--r-- | lights.go | 82 | ||||
-rw-r--r-- | lights_test.go | 9 |
4 files changed, 105 insertions, 36 deletions
@@ -5,10 +5,12 @@ import ( "log" "os" "encoding/xml" + "encoding/json" "net/http" "io/ioutil" "runtime" "fmt" + "bytes" ) type Bridge struct { @@ -57,9 +59,9 @@ func GetBridgeInfo(self *Bridge) { trace(fmt.Sprintf("Bridge status error: %d", response.StatusCode), nil) os.Exit(1) } + defer response.Body.Close() body, error := ioutil.ReadAll(response.Body) - defer response.Body.Close() if error != nil { trace("Error parsing bridge description xml.", nil) os.Exit(1) @@ -74,6 +76,42 @@ func GetBridgeInfo(self *Bridge) { self.Info = *data } +// Error Struct - REST Error Response Format +// http://www.developers.meethue.com/documentation/error-messages +type Error struct { + response struct { + Type string `xml:"type"` + Address string `xml:"address"` + Description string `xml:"description"` + } `xml:"error"` +} + +// CreateUser posts to ./api on the bridge to create a new whitelisted user. +// If the button on the bridge was not pressed then _____todo_____ +func CreateUser(bridge *Bridge, deviceType string) (string, error) { + // Construct the http POST + params := map[string]string{"devicetype": deviceType} + request, err := json.Marshal(params) + if err != nil { + return "", err + } + + // Send the request to create the user and read the response + uri := fmt.Sprintf("http://%s/api", bridge.IPAddress) + response, err := http.Post(uri, "text/json", bytes.NewReader(request)) + if err != nil { + return "", err + } + defer response.Body.Close() + body, err := ioutil.ReadAll(response.Body) + fmt.Println(string(body)) + + // TODO: decode and return + // TODO: handle errors. http://www.developers.meethue.com/documentation/error-messages + + return "", err +} + // Log the date, time, file location, line number, and function. // Message can be "" or Err can be nil (not both) func trace(message string, err error) { diff --git a/bridge_test.go b/bridge_test.go index 546470c..b9b0137 100644 --- a/bridge_test.go +++ b/bridge_test.go @@ -1,11 +1,13 @@ package hue import ( - "log" "testing" ) func TestNewBridge(t *testing.T) { - bridge := NewBridge("192.168.1.128", "319b36233bd2328f3e40731b23479207") - log.Println(bridge) -}
\ No newline at end of file + NewBridge("192.168.1.128", "319b36233bd2328f3e40731b23479207") +} + +func TestCreateUser(t *testing.T) { + CreateUser(NewBridge("192.168.1.128", "319b36233bd2328f3e40731b23479207"), "linux") +} @@ -1,12 +1,13 @@ package hue import ( - "log" "fmt" "os" "net/http" "io/ioutil" "encoding/json" + "strings" + "errors" ) type Light struct { @@ -21,7 +22,7 @@ type Light struct { 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"` @@ -30,35 +31,58 @@ type Light struct { SWVersion string `json:"swversion"` } + + //http://192.168.1.128/api/319b36233bd2328f3e40731b23479207/lights/ -// http://<bridge_ip>/api/<username>/lights/ // GetAllLights retreives the state of all lights that the bridge is aware of. -func GetAllLights(bridge *Bridge) { - response, error := http.Get( - fmt.Sprintf("http://%s/api/%s/lights/", bridge.IPAddress, bridge.Username)) - if error != nil { - trace("", error) - os.Exit(1) - } else if response.StatusCode != 200 { - trace(fmt.Sprintf("Bridge status error %d", response.StatusCode), nil) - os.Exit(1) - } - - body, error := ioutil.ReadAll(response.Body) - defer response.Body.Close() - if error != nil { - trace("", error) - os.Exit(1) +func GetAllLights(bridge *Bridge) []Light { + // 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) + os.Exit(1) + } else if response.StatusCode != 200 { + trace(fmt.Sprintf("Bridge status error %d", response.StatusCode), nil) + os.Exit(1) + } + + // Read the response + body, err := ioutil.ReadAll(response.Body) + defer response.Body.Close() + if err != nil { + trace("", err) + os.Exit(1) + } + 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) + os.Exit(1) + } + lights = append(lights, data) } - - data := Light{} - error = json.Unmarshal(body, &data) - if error != nil { - trace("", error) - os.Exit(1) + return lights +} + +// 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 + } } - - log.Println(data) - -}
\ No newline at end of file + return Light{}, errors.New("Light not found.") +} diff --git a/lights_test.go b/lights_test.go index 66f01c1..5639630 100644 --- a/lights_test.go +++ b/lights_test.go @@ -3,8 +3,13 @@ package hue import ( "testing" ) - + func TestGetAllLights(t *testing.T) { bridge := NewBridge("192.168.1.128", "319b36233bd2328f3e40731b23479207") GetAllLights(bridge) -}
\ No newline at end of file +} + +func TestGetLight(t *testing.T) { + bridge := NewBridge("192.168.1.128", "319b36233bd2328f3e40731b23479207") + GetLight(bridge, "Bathroom Light") +} |