diff options
Diffstat (limited to 'bridge.go')
-rw-r--r-- | bridge.go | 102 |
1 files changed, 45 insertions, 57 deletions
@@ -24,6 +24,7 @@ import ( "runtime" "strconv" "strings" + "time" ) // Bridge struct defines hardware that is used to communicate with the lights. @@ -51,78 +52,76 @@ type BridgeInfo struct { } `xml:"device"` } -// bridge.Get sends an http GET to the bridge +// Get sends an http GET to the bridge func (bridge *Bridge) Get(path string) ([]byte, io.Reader, error) { uri := fmt.Sprintf("http://" + bridge.IPAddress + path) - resp, err := http.Get(uri) + client := &http.Client{Timeout: time.Second * 5} + resp, err := client.Get(uri) + if err != nil { - err = errors.New("Error: Unable to access bridge. ") - log.Println(err) + err = errors.New("unable to access bridge") return []byte{}, nil, err } return HandleResponse(resp) } -// Bridge.Put sends an http PUT to the bridge with +// Put sends an http PUT to the bridge with // a body formatted with parameters (in a generic interface) func (bridge *Bridge) Put(path string, params interface{}) ([]byte, io.Reader, error) { uri := fmt.Sprintf("http://" + bridge.IPAddress + path) - client := &http.Client{} + client := &http.Client{Timeout: time.Second * 5} data, err := json.Marshal(params) if err != nil { - err = errors.New("Error: Unable marshal PUT request interface.") - log.Println(err) + err = errors.New("unable to marshal PUT request interface") return []byte{}, nil, err } //fmt.Println("\n\nPARAMS: ", params) - //log.Println("\nSending PUT body: ", string(data)) - request, err := http.NewRequest("PUT", uri, bytes.NewReader(data)) + request, _ := http.NewRequest("PUT", uri, bytes.NewReader(data)) resp, err := client.Do(request) if err != nil { - err = errors.New("Error: Unable to access bridge.") - log.Println(err) + err = errors.New("unable to access bridge") return []byte{}, nil, err } return HandleResponse(resp) } -// bridge.Post sends an http POST to the bridge with +// Post sends an http POST to the bridge with // a body formatted with parameters (in a generic interface). // If `params` is nil then it will send an empty body with the post request. func (bridge *Bridge) Post(path string, params interface{}) ([]byte, io.Reader, error) { - // Add the params to the request or allow an empty body - request := []byte{} - if params != nil { - reqBody, err := json.Marshal(params) - if err != nil { - err = errors.New("Error: Unable to add POST body parameters due to json marshal error.") - log.Println(err) - return []byte{}, nil, err - } - request = reqBody - } + // Add the params to the request or allow an empty body + request := []byte{} + if params != nil { + reqBody, err := json.Marshal(params) + if err != nil { + err = errors.New("unable to add POST body parameters due to json marshalling error") + return []byte{}, nil, err + } + request = reqBody + } // Send the request and handle the response uri := fmt.Sprintf("http://" + bridge.IPAddress + path) - resp, err := http.Post(uri, "text/json", bytes.NewReader(request)) + client := &http.Client{Timeout: time.Second * 5} + resp, err := client.Post(uri, "text/json", bytes.NewReader(request)) + if err != nil { - err = errors.New("Error: Unable to access bridge.") - log.Println(err) + err = errors.New("unable to access bridge") return []byte{}, nil, err } - return HandleResponse(resp) + return HandleResponse(resp) } -// Bridge.Delete sends an http DELETE to the bridge +// Delete sends an http DELETE to the bridge func (bridge *Bridge) Delete(path string) error { uri := fmt.Sprintf("http://" + bridge.IPAddress + path) - client := &http.Client{} - req, err := http.NewRequest("DELETE", uri, nil) + client := &http.Client{Timeout: time.Second * 5} + req, _ := http.NewRequest("DELETE", uri, nil) resp, err := client.Do(req) + if err != nil { - err = errors.New("Error: Unable to access bridge.") - log.Println(err) + err = errors.New("unable to access bridge") return err } _, _, err = HandleResponse(resp) @@ -134,7 +133,7 @@ func (bridge *Bridge) Delete(path string) error { // and invalid return types. func HandleResponse(resp *http.Response) ([]byte, io.Reader, error) { body, err := ioutil.ReadAll(resp.Body) - defer resp.Body.Close() + defer resp.Body.Close() if err != nil { trace("Error parsing bridge description xml.", nil) return []byte{}, nil, err @@ -146,7 +145,6 @@ func HandleResponse(resp *http.Response) ([]byte, io.Reader, error) { errDesc := errString[strings.Index(errString, "description\":\"")+14 : strings.Index(errString, "\"}}")] errOut := fmt.Sprintf("Error type %s: %s.", errNum, errDesc) err = errors.New(errOut) - log.Println(err) return []byte{}, nil, err } return body, reader, nil @@ -158,15 +156,14 @@ func FindBridges() ([]Bridge, error) { bridge := Bridge{IPAddress: "www.meethue.com"} body, _, err := bridge.Get("/api/nupnp") if err != nil { - err = errors.New("Error: Unable to locate bridge.") - log.Fatal(err) + err = errors.New("unable to locate bridge") return []Bridge{}, err } - bridges := []Bridge{} - err = json.Unmarshal(body, &bridges) - if err != nil { - return []Bridge{}, errors.New("Unable to parse FindBridges response. ") - } + bridges := []Bridge{} + err = json.Unmarshal(body, &bridges) + if err != nil { + return []Bridge{}, errors.New("unable to parse FindBridges response") + } return bridges, nil } @@ -181,13 +178,12 @@ func NewBridge(ip string) (*Bridge, error) { // Test the connection by attempting to get the bridge info. err := bridge.GetInfo() if err != nil { - log.Fatal("Error: Unable to access bridge. ", err) return &Bridge{}, err } return &bridge, nil } -// GetBridgeInfo retreives the description.xml file from the bridge. +// GetInfo retreives the description.xml file from the bridge. // This is used as a check to see if the bridge is accessible // and any error will be fatal as the bridge is required for nearly // all functions. @@ -200,27 +196,25 @@ func (bridge *Bridge) GetInfo() error { err = xml.NewDecoder(reader).Decode(&data) if err != nil { err = errors.New("Error: Unable to decode XML response from bridge. ") - log.Fatal(err) return err } bridge.Info = data return nil } -// Bridge.Login verifies that the username token has bridge access +// Login verifies that the username token has bridge access // and only assigns the bridge its Username value if verification is successful. func (bridge *Bridge) Login(username string) error { uri := fmt.Sprintf("/api/%s", username) _, _, err := bridge.Get(uri) if err != nil { - log.Fatal(err) return err } bridge.Username = username return nil } -// Bridge.CreateUser adds a new user token on the whitelist. +// CreateUser adds a new user token on the whitelist. // The token is the first return value in this function which must // be used with `Bridge.Login`. You cannot use a plaintext username // like the argument provided in this function. @@ -229,20 +223,15 @@ func (bridge *Bridge) CreateUser(deviceType string) (string, error) { params := map[string]string{"devicetype": deviceType} body, _, err := bridge.Post("/api", params) if err != nil { - log.Fatal("Error: Failed to create user. ", err) return "", err } content := string(body) username := content[strings.LastIndex(content, ":\"")+2 : strings.LastIndex(content, "\"")] - userOut := fmt.Sprintf( - "Created user token '%s'. Use Bridge.Login with this token from now on.", - username) - log.Println(userOut) bridge.Username = username return username, nil } -// Bridge.DeleteUser deletes a user given its USER KEY, not the string name. +// DeleteUser deletes a user given its USER KEY, not the string name. // See http://www.developers.meethue.com/documentation/configuration-api // for description on `username` deprecation in place of the devicetype key. func (bridge *Bridge) DeleteUser(username string) error { @@ -307,7 +296,7 @@ func (bridge *Bridge) GetLightByIndex(index int) (Light, error) { return light, nil } -// Bridge.FindNewLights makes the bridge search the zigbee spectrum for +// FindNewLights makes the bridge search the zigbee spectrum for // lights in the area and will add them to the list of lights available. // If successful these new lights can be used by `Bridge.GetAllLights` // @@ -321,13 +310,12 @@ func (bridge *Bridge) FindNewLights() error { uri := fmt.Sprintf("/api/%s/lights", bridge.Username) _, _, err := bridge.Post(uri, nil) if err != nil { - log.Println(err) return err } return nil } -// GetLight returns a light struct containing data on a given name. +// GetLightByName returns a light struct containing data on a given name. func (bridge *Bridge) GetLightByName(name string) (Light, error) { lights, _ := bridge.GetAllLights() for _, light := range lights { |