Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended to include subscriptions to device events #1

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
580a1ce
Early Subscribe Commit
danward79 Jul 4, 2014
5f544ab
More progress with listener
danward79 Jul 5, 2014
ad84f53
Few comments and tweaks
danward79 Jul 5, 2014
b1c8a55
Early bug
danward79 Jul 5, 2014
f587832
Typo
danward79 Jul 5, 2014
416bc16
Added Struct to use in storing subscriptions
danward79 Jul 8, 2014
b9e2bb2
Added Subscription Example
danward79 Jul 8, 2014
8118df6
ManageSubscription added
danward79 Jul 13, 2014
51b9c92
Event channel added for subscription notification
danward79 Jul 13, 2014
7270e75
Tidy up
danward79 Jul 14, 2014
c27178e
Subscription Management Complete
danward79 Jul 16, 2014
879389c
Typo!
danward79 Jul 16, 2014
8ed6c5b
Create .travis.yml
danward79 Jul 17, 2014
9c437b4
Fixed a couple of bits and tidied up
danward79 Aug 9, 2014
9607edb
Delete .travis.yml
danward79 Aug 10, 2014
0d677c1
Catch failure when network is down
danward79 Aug 10, 2014
307f271
reduced logging
danward79 Aug 18, 2014
3d60795
Update README.md
danward79 Sep 14, 2014
93d1c53
added urn for netcam so it finds NetCam camera
lindsaymarkward Aug 5, 2015
ebefb10
Merge pull request #1 from lindsaymarkward/master
Aug 10, 2015
37843e4
Update context package referenence.
jonseymour Aug 15, 2016
948abd4
Merge branch 'fix-net-context-reference'
jonseymour Aug 15, 2016
b41be5d
Add support for insight device type.
jonseymour Aug 17, 2016
0a42719
Allow calls to services otherthan basic event.
jonseymour Aug 17, 2016
6113bc2
Add support for extracting the power reading from insight devices.
jonseymour Aug 17, 2016
4c2292c
ready for merge
danward79 Nov 2, 2016
559fed0
Merge branch 'catchup'
danward79 Nov 2, 2016
427ddef
Catchup & Clean up
danward79 Nov 2, 2016
b194f84
More golint warning fixes
danward79 Nov 3, 2016
2ecf399
Extract UDN, to support bridge devices
danward79 Nov 28, 2016
63284da
Bridge device discovery
danward79 Nov 30, 2016
e6a3c05
tidy up
danward79 Nov 30, 2016
377ea34
Bulb control added
danward79 Dec 3, 2016
48c3442
Updated to get bulb status
danward79 Dec 4, 2016
5effa9e
Tidy up
danward79 Dec 4, 2016
9500f15
Tidy up
danward79 Dec 12, 2016
9444bf0
Clean up after linter
danward79 Dec 16, 2016
c20c5de
Further clean ups
danward79 Dec 16, 2016
39f9d9c
Added link subscription
danward79 Dec 18, 2016
bb65384
adding tests
danward79 Dec 21, 2016
578c0b1
cml
danward79 Dec 21, 2016
598a8f6
readme link
danward79 Dec 21, 2016
cc52599
readme
danward79 Dec 21, 2016
aee7d3d
test lint errors
danward79 Dec 21, 2016
673977b
Additional tests and travis integration
danward79 Dec 21, 2016
cdd8c55
Merge branch 'master' of https://github.com/danward79/go.wemo
danward79 Jan 24, 2017
f039af6
Addition of basic URN devices
danward79 Jan 25, 2017
43c05e2
Merge branch 'Find-Fix-for-Poor-Discovery-Performance'
danward79 Jan 28, 2017
2052251
Ignore binary
danward79 Jan 28, 2017
3634aeb
Readme update
danward79 Jan 28, 2017
a2e2169
Added wrapper SetState
danward79 Jan 28, 2017
1e6e989
Correction to request close
danward79 Jan 29, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Catchup & Clean up
Merged latest from another fork. There are a lot of golint warnings so
have been clearing those.
danward79 committed Nov 2, 2016
commit 427ddef96d3474fb1c5e65fb26ef312d81b4229c
28 changes: 10 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
go.wemo
=======

<<<<<<< HEAD
I submitted a pull request for the changes I have made to this library. The request is pending, so I have edited the infor below to reflect the location of this library.

[![GoDoc](http://godoc.org/github.com/danward79/go.wemo?status.png)](http://godoc.org/github.com/danward79/go.wemo)
=======
[![GoDoc](http://godoc.org/github.com/savaki/go.wemo?status.png)](http://godoc.org/github.com/savaki/go.wemo)
[![Build Status](https://snap-ci.com/savaki/go.wemo/branch/master/build_image)](https://snap-ci.com/savaki/go.wemo/branch/master)
>>>>>>> 6113bc2e76d18130690a3ab9e1520139559c58de


Simple package to interface with Belkin wemo devices.

### Example - Device discovery

```
```go
package main

import (
@@ -34,7 +29,7 @@ func main() {

### Example - Control a device

```
```go
package main

import (
@@ -63,7 +58,7 @@ func main() {

As a convenience method, you can control lights through a more generic interface.

```
```go
package main

import (
@@ -83,7 +78,7 @@ func main() {

This is an example of discovering devices, subscribing to there events and being notified of changed to there state. Resubscriptions are managed automatically at the timeout specified. Subscriber details and state are maintained in a map.

```
```go
package main

import (
@@ -93,14 +88,14 @@ import (
)

func main() {

listenerAddress := "192.168.0.6:6767"
timeout := 300

api, _ := wemo.NewByInterface("en0")

devices, _ := api.DiscoverAll(3*time.Second)

subscriptions := make(map[string]*wemo.SubscriptionInfo)

for _, device := range devices {
@@ -109,7 +104,7 @@ func main() {
log.Println("Initial Error Subscribing: ", err)
}
}

cs := make(chan wemo.SubscriptionEvent)

go wemo.Listener(listenerAddress, cs)
@@ -125,6 +120,3 @@ func main() {

}
```



1 change: 1 addition & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package wemo ...
// Copyright 2014 Matt Ho
//
// Licensed under the Apache License, Version 2.0 (the "License");
30 changes: 17 additions & 13 deletions device.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package wemo ...
// Copyright 2014 Matt Ho
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,21 +18,26 @@ import (
"encoding/xml"
"errors"
"fmt"
"github.com/savaki/httpctx"
"golang.org/x/net/context"
"io/ioutil"
"log"
"net/http"
"regexp"
"strconv"
"strings"

"golang.org/x/net/context"

"github.com/savaki/httpctx"
//"golang.org/x/net/context"
)

// Device ...
type Device struct {
Host string
Logger func(string, ...interface{}) (int, error)
}

// DeviceInfo ...
type DeviceInfo struct {
Device *Device `json:"-"`
DeviceType string `xml:"deviceType" json:"device-type"`
@@ -41,6 +47,7 @@ type DeviceInfo struct {
SerialNumber string `xml:"serialNumber" json:"serial-number"`
}

// DeviceInfos ...
type DeviceInfos []*DeviceInfo

func (d DeviceInfos) Len() int { return len(d) }
@@ -65,6 +72,7 @@ func unmarshalDeviceInfo(data []byte) (*DeviceInfo, error) {
return &resp.DeviceInfo, nil
}

// FetchDeviceInfo ...
func (d *Device) FetchDeviceInfo(ctx context.Context) (*DeviceInfo, error) {
var data []byte

@@ -79,16 +87,11 @@ func (d *Device) FetchDeviceInfo(ctx context.Context) (*DeviceInfo, error) {
return nil, err
}

<<<<<<< HEAD
//log.Printf("%+v\n", resp.Device)

return &resp.Device, nil
=======
deviceInfo.Device = d
return deviceInfo, nil
>>>>>>> 6113bc2e76d18130690a3ab9e1520139559c58de
}

// GetBinaryState ...
func (d *Device) GetBinaryState() int {
message := newGetBinaryStateMessage()
response, err := post(d.Host, "basicevent", "GetBinaryState", message)
@@ -120,14 +123,17 @@ func (d *Device) GetBinaryState() int {
return result
}

// Off ...
func (d *Device) Off() {
d.changeState(false)
}

// On ...
func (d *Device) On() {
d.changeState(true)
}

// Toggle ...
func (d *Device) Toggle() {
if binaryState := d.GetBinaryState(); binaryState == 0 {
d.On()
@@ -136,13 +142,9 @@ func (d *Device) Toggle() {
}
}

<<<<<<< HEAD
func (self *Device) changeState(newState bool) error {
//fmt.Printf("changeState(%v)\n", newState)
=======
func (d *Device) changeState(newState bool) error {
fmt.Printf("changeState(%v)\n", newState)
>>>>>>> 6113bc2e76d18130690a3ab9e1520139559c58de

message := newSetBinaryStateMessage(newState)
response, err := post(d.Host, "basicevent", "SetBinaryState", message)
if err != nil {
@@ -167,10 +169,12 @@ func (d *Device) changeState(newState bool) error {
return nil
}

// InsightParams ...
type InsightParams struct {
Power int // mW
}

// GetInsightParams ...
func (d *Device) GetInsightParams() *InsightParams {
message := newGetInsightParamsMessage()
response, err := post(d.Host, "insight", "GetInsightParams", message)
3 changes: 2 additions & 1 deletion device_test.go
Original file line number Diff line number Diff line change
@@ -15,8 +15,9 @@ package wemo

import (
"encoding/json"
. "github.com/smartystreets/goconvey/convey"
"testing"

. "github.com/smartystreets/goconvey/convey"
)

func assert(t *testing.T, actual, expected string) {
12 changes: 8 additions & 4 deletions discover.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package wemo ...
// Copyright 2014 Matt Ho
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,12 +21,14 @@ import (

var belkinRE *regexp.Regexp = regexp.MustCompile(`http://([^/]+)/setup.xml`)

// Wemo ...
type Wemo struct {
ipAddr string
Debug bool
}

func (self *Wemo) DiscoverAll(timeout time.Duration) ([]*Device, error) {
// DiscoverAll ...
func (w *Wemo) DiscoverAll(timeout time.Duration) ([]*Device, error) {
urns := []string{
"urn:Belkin:device:controllee:1",
"urn:Belkin:device:light:1",
@@ -36,7 +39,7 @@ func (self *Wemo) DiscoverAll(timeout time.Duration) ([]*Device, error) {

var all []*Device
for _, urn := range urns {
devices, _ := self.Discover(urn, timeout)
devices, _ := w.Discover(urn, timeout)
for _, device := range devices {
all = append(all, device)
}
@@ -45,8 +48,9 @@ func (self *Wemo) DiscoverAll(timeout time.Duration) ([]*Device, error) {
return all, nil
}

func (self *Wemo) Discover(urn string, timeout time.Duration) ([]*Device, error) {
locations, err := self.scan(urn, timeout)
// Discover ...
func (w *Wemo) Discover(urn string, timeout time.Duration) ([]*Device, error) {
locations, err := w.scan(urn, timeout)
if err != nil {
return nil, err
}
1 change: 1 addition & 0 deletions messages.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package wemo ...
// Copyright 2014 Matt Ho
//
// Licensed under the Apache License, Version 2.0 (the "License");
4 changes: 3 additions & 1 deletion network.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package wemo ...
// Copyright 2014 Matt Ho
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,11 +23,12 @@ import (

var ipAddrRE = regexp.MustCompile(`^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/\d{1,3}$`)

// NewByIp ...
func NewByIp(ipAddr string) *Wemo {
return &Wemo{ipAddr: ipAddr, Debug: false}
}

// find the ip address associated with the specified interface
// NewByInterface find the ip address associated with the specified interface
func NewByInterface(name string) (*Wemo, error) {
// find the interface with the selected name
iface, err := net.InterfaceByName(name)
13 changes: 7 additions & 6 deletions scan.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package wemo ...
// Copyright 2014 Matt Ho
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,9 +30,9 @@ const (
)

// scan the multicast
func (self *Wemo) scan(urn string, timeout time.Duration) ([]*url.URL, error) {
func (w *Wemo) scan(urn string, timeout time.Duration) ([]*url.URL, error) {
// open a udp port for us to receive multicast messages
udpAddr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:0", self.ipAddr))
udpAddr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:0", w.ipAddr))
if err != nil {
return nil, err
}
@@ -48,20 +49,20 @@ func (self *Wemo) scan(urn string, timeout time.Duration) ([]*url.URL, error) {
return nil, err
}

if self.Debug {
if w.Debug {
log.Printf("Found multi-cast address %v", mAddr)
}
packet := fmt.Sprintf(M_SEARCH, urn)

if self.Debug {
if w.Debug {
log.Printf("Writing discovery packet")
}
_, err = udpConn.WriteTo([]byte(packet), mAddr)
if err != nil {
return nil, err
}

if self.Debug {
if w.Debug {
log.Printf("Setting read deadline")
}
err = udpConn.SetReadDeadline(time.Now().Add(timeout))
@@ -89,7 +90,7 @@ func (self *Wemo) scan(urn string, timeout time.Duration) ([]*url.URL, error) {
}
}

if self.Debug {
if w.Debug {
log.Printf("Read : %v\n", string(buffer[:n]))
}
}
6 changes: 4 additions & 2 deletions subscribe.go
Original file line number Diff line number Diff line change
@@ -21,6 +21,8 @@ import (
"net/http"
"strconv"
"time"

"golang.org/x/net/context"
)

//SubscriptionInfo struct
@@ -93,7 +95,7 @@ func (d *Device) ManageSubscription(listenerAddress string, timeout int, subscri
*/

// Initial Subscribe
info, _ := d.FetchDeviceInfo()
info, _ := d.FetchDeviceInfo(context.Background())

id, err := d.Subscribe(listenerAddress, timeout)
if err != 200 {
@@ -109,7 +111,7 @@ func (d *Device) ManageSubscription(listenerAddress string, timeout int, subscri
timer.Reset(time.Second * time.Duration(timeout))

// Resubscribe
_, err := d.ReSubscribe(id, timeout)
_, err = d.ReSubscribe(id, timeout)
if err != 200 {

// Failed to resubscribe so try unsubscribe, it is likely to fail but don't care.
Loading