forked from dyrkin/zigbee-steward
-
Notifications
You must be signed in to change notification settings - Fork 0
/
example.go
98 lines (82 loc) · 2.7 KB
/
example.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
package main
import (
"fmt"
"github.com/davecgh/go-spew/spew"
"github.com/dyrkin/zcl-go/cluster"
"github.com/dyrkin/zigbee-steward"
"github.com/dyrkin/zigbee-steward/configuration"
"github.com/dyrkin/zigbee-steward/model"
"sync"
)
//simple device database
var devices = map[string]*model.Device{}
func main() {
conf := configuration.Default()
conf.PermitJoin = true
stewie := steward.New(conf)
eventListener := func() {
for {
select {
case device := <-stewie.Channels().OnDeviceRegistered():
saveDevice(device)
case device := <-stewie.Channels().OnDeviceUnregistered():
deleteDevice(device)
case device := <-stewie.Channels().OnDeviceBecameAvailable():
saveDevice(device)
case deviceIncomingMessage := <-stewie.Channels().OnDeviceIncomingMessage():
fmt.Printf("Device received incoming message:\n%s", spew.Sdump(deviceIncomingMessage))
toggleIkeaBulb(stewie, deviceIncomingMessage)
}
}
}
go eventListener()
stewie.Start()
infiniteWait()
}
func toggleIkeaBulb(stewie *steward.Steward, message *model.DeviceIncomingMessage) {
if isXiaomiButtonSingleClick(message) {
if ikeaBulb, registered := devices["TRADFRI bulb E27 W opal 1000lm"]; registered {
toggleTarget(stewie, ikeaBulb.NetworkAddress)
} else {
fmt.Println("IKEA bulb is not available")
}
}
}
func toggleTarget(stewie *steward.Steward, networkAddress string) {
go func() {
stewie.Functions().Cluster().Local().OnOff().Toggle(networkAddress, 0xFF)
}()
}
func isXiaomiButtonSingleClick(message *model.DeviceIncomingMessage) bool {
command, ok := message.IncomingMessage.Data.Command.(*cluster.ReportAttributesCommand)
return ok && message.Device.Manufacturer == "LUMI" &&
message.Device.Model == "lumi.remote.b186acn01\x00\x00\x00" &&
isSingleClick(command)
}
func isSingleClick(command *cluster.ReportAttributesCommand) bool {
click, ok := command.AttributeReports[0].Attribute.Value.(uint64)
return ok && click == uint64(1)
}
func saveDevice(device *model.Device) {
fmt.Printf("Registering device:\n%s", spew.Sdump(device))
devices[device.Model] = device
}
func deleteDevice(device *model.Device) {
fmt.Printf("Unregistering device:\n%s", spew.Sdump(device))
delete(devices, device.Model)
}
func infiniteWait() {
wg := &sync.WaitGroup{}
wg.Add(1)
wg.Wait()
}
//TODO Remove this
func subscribeForLevelControlEvents(stewie *steward.Steward, device *model.Device) {
if device.Manufacturer == "IKEA of Sweden" && device.Model == "TRADFRI wireless dimmer" {
go func() {
rsp, err := stewie.Functions().Generic().Bind(device.NetworkAddress, device.IEEEAddress, 1,
uint16(cluster.LevelControl), stewie.Configuration().IEEEAddress, 1)
fmt.Printf("Bind result: [%v] [%s]", rsp, err)
}()
}
}