aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bridge.go40
-rw-r--r--bridge_test.go10
-rw-r--r--lights.go82
-rw-r--r--lights_test.go9
4 files changed, 105 insertions, 36 deletions
diff --git a/bridge.go b/bridge.go
index 90f7719..1106682 100644
--- a/bridge.go
+++ b/bridge.go
@@ -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")
+}
diff --git a/lights.go b/lights.go
index 1138312..7c0fda2 100644
--- a/lights.go
+++ b/lights.go
@@ -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")
+}