package wemodiscovery import ( "encoding/xml" "fmt" "net/http" "io/ioutil" "time" "github.com/fromkeith/gossdp" "git.lerch.org/lobo/wemo/logger" ) var responses []gossdp.ResponseMessage type belkinListener struct { // Response func(message gossdp.ResponseMessage) } func (l belkinListener) Response(message gossdp.ResponseMessage) { responses = append(responses, message) } // Scan detects Belkin devices on the network. The devices that are returned have // limited information in the Scan field, to get more detailed information you will // have to call Load() on the device func Scan(dt DeviceType, waitTimeSeconds int) ([]*Device, error) { responses = []gossdp.ResponseMessage{} l := belkinListener{} c, err := gossdp.NewSsdpClientWithLogger(l, &logger.LeveledLogger{}) if err != nil { return nil, fmt.Errorf("failed to start ssdp discovery client: %s", err) } defer c.Stop() go c.Start() err = c.ListenFor(string(dt)) if err != nil { return nil, fmt.Errorf("discovery failed: %s", err) } time.Sleep(time.Duration(waitTimeSeconds) * time.Second) devices := make([]*Device, len(responses)) for i, response := range responses { devices[i] = &Device{Scan: response} } return devices, nil } // Load fetches all of the device specific information and updates the calling struct. The timeout // parameter specifies how long to wait to connect and get a response before giving up func (d *Device) Load(timeout time.Duration) error { client := http.Client{Timeout: timeout} resp, err := client.Get(d.Scan.Location) if resp != nil { defer resp.Body.Close() } if err != nil { return fmt.Errorf("error fetching device info: %s", err) } b, err := ioutil.ReadAll(resp.Body) if err != nil { return fmt.Errorf("error reading response from device: %s", err) } var root root root.Device = d err = xml.Unmarshal(b, &root) if err != nil { return err } return nil }