func (c *Client) streamStructures(callback func(structures map[string]*Structure, err error)) {
	resp, err := c.getStructures(Stream)
	if err != nil {
		callback(nil, err)
		return
	}
	defer resp.Body.Close()
	c.watchStructuresStream(resp, callback)
}
streamStructures connects to the stream, following the redirect and then watches the stream
package nest
import (
	"bufio"
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/http"
	"time"
)
func (c *Client) Structures() (map[string]*Structure, *APIError) {
	resp, err := c.getStructures(NoStream)
	if err != nil {
		return nil, &APIError{
			Error:       "devices_error",
			Description: err.Error(),
		}
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, &APIError{
			Error:       "body_read_error",
			Description: err.Error(),
		}
	}
	if resp.StatusCode != 200 {
		apiError := &APIError{}
		json.Unmarshal(body, apiError)
		return nil, apiError
	}
	structures := make(map[string]*Structure)
	err = json.Unmarshal(body, &structures)
	c.associateClientToStructures(structures)
	return structures, nil
}
func (c *Client) StructuresStream(callback func(structures map[string]*Structure, err error)) {
	c.setRedirectURL()
	for {
		c.streamStructures(callback)
	}
}
func (s *Structure) SetAway(mode int) *APIError {
	requestMode := make(map[string]string)
	switch mode {
	case Home:
		requestMode["away"] = "home"
	case Away:
		requestMode["away"] = "away"
	case AutoAway:
		requestMode["away"] = "auto-away"
	default:
		return generateAPIError("Invalid Away requested - must be home, away or auto-away")
	}
	body, _ := json.Marshal(requestMode)
	return s.setStructure(body)
}
func (s *Structure) SetETA(tripID string, begin time.Time, end time.Time) *APIError {
	apiErr := checkTimes(begin, end)
	if apiErr != nil {
		return apiErr
	}
	eta := &ETA{
		TripID: tripID,
		EstimatedArrivalWindowBegin: begin,
		EstimatedArrivalWindowEnd:   end,
	}
	data, _ := json.Marshal(eta)
	req, _ := http.NewRequest("PUT", s.Client.RedirectURL+"/structures/"+s.StructureID+"/eta.json?auth="+s.Client.Token, bytes.NewBuffer(data))
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		apiError := &APIError{
			Error:       "http_error",
			Description: err.Error(),
		}
		return apiError
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if resp.StatusCode != 200 {
		apiError := &APIError{}
		json.Unmarshal(body, apiError)
		apiError = generateAPIError(apiError.Error)
		apiError.Status = resp.Status
		apiError.StatusCode = resp.StatusCode
		return apiError
	}
	return nil
}
func checkTimes(begin time.Time, end time.Time) *APIError {
	if begin.Before(time.Now()) {
		apiError := &APIError{
			Error:       "eta_error",
			Description: "The begin time must be greater than the time now",
		}
		return apiError
	}
	if end.Before(begin) {
		apiError := &APIError{
			Error:       "eta_error",
			Description: "The end time must be greater than the begin time",
		}
		return apiError
	}
	return nil
}