move scanning features into wemo golang package
This commit is contained in:
parent
5945effb3c
commit
3b5f835f11
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
node_modules
|
||||
wemo
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
let Wemo = require('wemo-client');
|
||||
let wemo = new Wemo();
|
||||
|
||||
wemo.discover(function(err, deviceInfo) {
|
||||
console.log('Wemo Device Found: %j', deviceInfo);
|
||||
|
||||
// Get the client for the found device
|
||||
let client = wemo.client(deviceInfo);
|
||||
|
||||
// You definitely want to listen to error events (e.g. device went offline),
|
||||
// Node will throw them as an exception if they are left unhandled
|
||||
client.on('error', function(err) {
|
||||
console.log('Error: %s', err.code);
|
||||
});
|
||||
|
||||
// Handle BinaryState events
|
||||
client.on('binaryState', function(value) {
|
||||
console.log('Binary State changed to: %s', value);
|
||||
});
|
||||
|
||||
// Turn the switch on
|
||||
//client.setBinaryState(1);
|
||||
});
|
120
diag/package-lock.json
generated
120
diag/package-lock.json
generated
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"name": "wemo",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
|
||||
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.14"
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
|
||||
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"ip": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
|
||||
"integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.14",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
|
||||
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node-ssdp": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/node-ssdp/-/node-ssdp-3.3.0.tgz",
|
||||
"integrity": "sha512-hFBkfUJytKC2x64jljojAbktG8aOL0C1YuNjCK54ZGBBg2382J3oTuK17T+aFgmy47noKHE5arLnYppo0JjcLw==",
|
||||
"requires": {
|
||||
"async": "^2.6.0",
|
||||
"bluebird": "^3.5.1",
|
||||
"debug": "^3.1.0",
|
||||
"extend": "^3.0.1",
|
||||
"ip": "^1.1.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"wemo-client": {
|
||||
"version": "0.15.0",
|
||||
"resolved": "https://registry.npmjs.org/wemo-client/-/wemo-client-0.15.0.tgz",
|
||||
"integrity": "sha512-zf266rvxXMtC7y9nR1Xu/yeYQCGgUPjYRQ1E4LZPxNiC5csDLIZBFklpUU3alcxSr+vqUpVtLDZz/iWiLX8sVw==",
|
||||
"requires": {
|
||||
"debug": "^2.6.9",
|
||||
"entities": "^1.1.1",
|
||||
"ip": "^1.1.5",
|
||||
"node-ssdp": "^3.2.5",
|
||||
"xml2js": "^0.4.19",
|
||||
"xmlbuilder": "^8.2.2"
|
||||
}
|
||||
},
|
||||
"xml2js": {
|
||||
"version": "0.4.19",
|
||||
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
|
||||
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
|
||||
"requires": {
|
||||
"sax": ">=0.6.0",
|
||||
"xmlbuilder": "~9.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"xmlbuilder": {
|
||||
"version": "9.0.7",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
|
||||
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
|
||||
}
|
||||
}
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz",
|
||||
"integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"name": "wemo",
|
||||
"version": "1.0.0",
|
||||
"description": "Movie mode for downstairs",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wemo-client": "^0.15.0"
|
||||
}
|
||||
}
|
13
go.mod
Normal file
13
go.mod
Normal file
|
@ -0,0 +1,13 @@
|
|||
module git.lerch.org/lobo/wemo
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
git.lerch.org/lobo/wemo/wemodiscovery v0.0.0
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
golang.org/x/tools v0.0.0-20190723021737-8bb11ff117ca // indirect
|
||||
)
|
||||
|
||||
replace git.lerch.org/lobo/wemo/wemodiscovery v0.0.0 => ./wemodiscovery
|
26
go.sum
Normal file
26
go.sum
Normal file
|
@ -0,0 +1,26 @@
|
|||
github.com/fromkeith/gossdp v0.0.0-20180102154144-1b2c43f6886e h1:cG4ivpkHpkmWTaaLrgekDVR0xAr87V697T2c+WnUdiY=
|
||||
github.com/fromkeith/gossdp v0.0.0-20180102154144-1b2c43f6886e/go.mod h1:7xQpS/YtlWo38XfIqje9GgtlPuBRatYcL23GlYBtgWM=
|
||||
github.com/go-home-iot/gossdp v0.0.0-20160327224030-49870f3db38d h1:ebIOreKlyZrQkj2SV6m6f6H9A6T7UcHY8YAfuYvY4Hc=
|
||||
github.com/go-home-iot/gossdp v0.0.0-20160327224030-49870f3db38d/go.mod h1:nUnTkSnQ3tPjjZaxpQJU7boXxTla6IJGT/1jUZrFtfw=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 h1:LepdCS8Gf/MVejFIt8lsiexZATdoGVyp5bcyS+rYoUI=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190723021737-8bb11ff117ca/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
|
||||
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
|
||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
90
wemo.go
Normal file
90
wemo.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.lerch.org/lobo/wemo/wemodiscovery"
|
||||
)
|
||||
|
||||
type basementPost struct {
|
||||
MovieMode bool
|
||||
}
|
||||
|
||||
type controlData struct {
|
||||
Bar, Basement, Jack string
|
||||
BasicEvent string
|
||||
}
|
||||
|
||||
var command string
|
||||
|
||||
func main() {
|
||||
command = os.Getenv("CMD")
|
||||
|
||||
if len(os.Args) > 1 {
|
||||
if os.Args[1] == "scan" {
|
||||
scan()
|
||||
os.Exit(0)
|
||||
}
|
||||
movieMode(true)
|
||||
time.Sleep(60 * time.Second)
|
||||
movieMode(false)
|
||||
os.Exit(0)
|
||||
}
|
||||
// POST /basement { movieMode: true } OR { movieMode: false }
|
||||
http.HandleFunc("/basement", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Not found", 404)
|
||||
return
|
||||
}
|
||||
postBodyBytes, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
http.Error(w, "Could not read body", 500)
|
||||
return
|
||||
}
|
||||
var postBody basementPost
|
||||
json.Unmarshal(postBodyBytes, &postBody)
|
||||
fmt.Fprintf(w, "MovieMode: %t", postBody.MovieMode)
|
||||
movieMode(postBody.MovieMode)
|
||||
})
|
||||
|
||||
http.HandleFunc("*", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Not found", 404)
|
||||
})
|
||||
|
||||
log.Fatal(http.ListenAndServe(":8081", nil))
|
||||
}
|
||||
|
||||
func movieMode(desiredState bool) {
|
||||
fmt.Fprintf(os.Stdout, "setting movieMode: %t", desiredState)
|
||||
// addresses := readAddresses()
|
||||
}
|
||||
|
||||
func readAddresses() controlData {
|
||||
var rc controlData
|
||||
bytes, err := ioutil.ReadFile("controlData.json")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not read controlData.json: %s", err)
|
||||
return rc
|
||||
}
|
||||
json.Unmarshal(bytes, &rc)
|
||||
return rc
|
||||
}
|
||||
|
||||
func scan() {
|
||||
devices, err := wemodiscovery.Scan(wemodiscovery.DTAllBelkin, 2)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error during scan: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, device := range devices {
|
||||
device.Load(1 * time.Second)
|
||||
fmt.Fprintf(os.Stdout, "Device %s: %s %s %s\n", device.Scan.DeviceId, device.Scan.Location, device.FriendlyName, device.Scan.Urn)
|
||||
}
|
||||
}
|
42
wemodiscovery/device.go
Normal file
42
wemodiscovery/device.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package wemodiscovery
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/fromkeith/gossdp"
|
||||
)
|
||||
|
||||
// Device contains information about a device that has been found on the network
|
||||
type Device struct {
|
||||
Scan gossdp.ResponseMessage
|
||||
DeviceType string `xml:"deviceType"`
|
||||
FriendlyName string `xml:"friendlyName"`
|
||||
Manufacturer string `xml:"manufacturer"`
|
||||
ManufacturerURL string `xml:"manufacturerURL"`
|
||||
ModelDescription string `xml:"modelDescription"`
|
||||
ModelName string `xml:"modelName"`
|
||||
ModelNumber string `xml:"modelNumber"`
|
||||
ModelURL string `xml:"modelURL"`
|
||||
SerialNumber string `xml:"serialNumber"`
|
||||
UDN string `xml:"UDN"`
|
||||
UPC string `xml:"UPC"`
|
||||
MACAddress string `xml:"macAddress"`
|
||||
FirmwareVersion string `xml:"firmwareVersion"`
|
||||
IconVersion string `xml:"iconVersion"`
|
||||
BinaryState int `xml:"binaryState"`
|
||||
ServiceList []Service `xml:"serviceList>service"`
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// Service contains information about a service exposed by the Belkin device
|
||||
type Service struct {
|
||||
ServiceType string `xml:"serviceType"`
|
||||
ServiceID string `xml:"serviceId"`
|
||||
ControlURL string `xml:"controlURL"`
|
||||
EventSubURL string `xml:"eventSubURL"`
|
||||
SCPDURL string `xml:"SCPDURL"`
|
||||
}
|
||||
|
||||
type root struct {
|
||||
Device *Device `xml:"device"`
|
||||
}
|
34
wemodiscovery/device_type.go
Normal file
34
wemodiscovery/device_type.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package wemodiscovery
|
||||
|
||||
// DeviceType represents an identifier for the type of Belkin device you want to
|
||||
// scan the network for
|
||||
type DeviceType string
|
||||
|
||||
const (
|
||||
// DTBridge - belkin bridge
|
||||
DTBridge DeviceType = "urn:Belkin:device:bridge:1"
|
||||
|
||||
// DTSwitch - belkin switch
|
||||
DTSwitch = "urn:Belkin:device:controllee:1"
|
||||
|
||||
// DTMotion - belkin motion sensor
|
||||
DTMotion = "urn:Belkin:device:sensor:1"
|
||||
|
||||
// DTMaker - belkin maker
|
||||
DTMaker = "urn:Belkin:device:Maker:1"
|
||||
|
||||
// DTInsight - belkin insight
|
||||
DTInsight = "urn:Belkin:device:insight:1"
|
||||
|
||||
// DTLightSwitch - belkin light switch
|
||||
DTLightSwitch = "urn:Belkin:device:lightswitch:1"
|
||||
|
||||
// DTDimmer - belkin dimmer
|
||||
DTDimmer = "urn:Belkin:device:dimmer:1"
|
||||
|
||||
// Get everything
|
||||
DTAll = "ssdp:all"
|
||||
|
||||
// Get everything
|
||||
DTAllBelkin = "urn:Belkin:device:**"
|
||||
)
|
8
wemodiscovery/go.mod
Normal file
8
wemodiscovery/go.mod
Normal file
|
@ -0,0 +1,8 @@
|
|||
module git.lerch.org/lobo/wemo/wemodiscovery
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/fromkeith/gossdp v0.0.0-20180102154144-1b2c43f6886e
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
|
||||
)
|
8
wemodiscovery/go.sum
Normal file
8
wemodiscovery/go.sum
Normal file
|
@ -0,0 +1,8 @@
|
|||
github.com/fromkeith/gossdp v0.0.0-20180102154144-1b2c43f6886e h1:cG4ivpkHpkmWTaaLrgekDVR0xAr87V697T2c+WnUdiY=
|
||||
github.com/fromkeith/gossdp v0.0.0-20180102154144-1b2c43f6886e/go.mod h1:7xQpS/YtlWo38XfIqje9GgtlPuBRatYcL23GlYBtgWM=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
75
wemodiscovery/scan.go
Normal file
75
wemodiscovery/scan.go
Normal file
|
@ -0,0 +1,75 @@
|
|||
package wemodiscovery
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/fromkeith/gossdp"
|
||||
)
|
||||
|
||||
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, gossdp.DefaultLogger{})
|
||||
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
|
||||
}
|
Loading…
Reference in New Issue
Block a user