This repository has been archived by the owner on Oct 8, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 20
/
client.go
114 lines (95 loc) · 2.2 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package miio
import (
"net"
"sync"
"time"
"github.com/nickw444/miio-go/common"
"github.com/nickw444/miio-go/protocol"
"github.com/nickw444/miio-go/protocol/tokens"
"github.com/nickw444/miio-go/subscription"
)
type Client struct {
sync.RWMutex
subscription.SubscriptionTarget
protocol protocol.Protocol
discoveryInterval time.Duration
quitChan chan struct{}
events chan interface{}
}
// NewClient creates a new default Client with the protocol.
func NewClient() (*Client, error) {
tokenStore, err := tokens.FromFile("tokens.txt")
if err != nil {
return nil, err
}
protocolConfig := protocol.ProtocolConfig{
BroadcastIP: net.IPv4bcast,
TokenStore: tokenStore,
}
p, err := protocol.NewProtocol(protocolConfig)
if err != nil {
return nil, err
}
return NewClientWithProtocol(p)
}
func NewClientWithProtocol(protocol protocol.Protocol) (*Client, error) {
c := &Client{
SubscriptionTarget: subscription.NewTarget(),
protocol: protocol,
quitChan: make(chan struct{}),
}
c.SetDiscoveryInterval(time.Second * 15)
return c, c.init()
}
func (c *Client) init() error {
if err := c.subscribe(); err != nil {
return err
}
return c.discover()
}
func (c *Client) SetDiscoveryInterval(interval time.Duration) {
c.discoveryInterval = interval
c.protocol.SetExpiryTime(interval * 2)
}
func (c *Client) discover() error {
if c.discoveryInterval == 0 {
common.Log.Debugf("Discovery interval is zero, discovery will only be performed once")
return c.protocol.Discover()
}
_ = c.protocol.Discover()
go func() {
c.RLock()
tick := time.Tick(c.discoveryInterval)
c.RUnlock()
for {
select {
case <-c.quitChan:
common.Log.Debugf("Quitting discovery loop")
return
default:
}
select {
case <-c.quitChan:
common.Log.Debugf("Quitting discovery loop")
return
case <-tick:
common.Log.Debugf("Performing discovery")
_ = c.protocol.Discover()
}
}
}()
return nil
}
// Proxy events from protocol level
func (c *Client) subscribe() error {
sub, err := c.protocol.NewSubscription()
if err != nil {
return err
}
go func() {
for event := range sub.Events() {
c.Publish(event)
}
}()
return nil
}