-
Notifications
You must be signed in to change notification settings - Fork 7
/
IASZoneChannel.go
74 lines (59 loc) · 1.76 KB
/
IASZoneChannel.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
package main
import (
"reflect"
"github.com/ninjasphere/go-ninja/channels"
)
// TODO: This should check if this is a motion or presence sensor, and output channels accordingly.
// TODO: This should expose battery alarm
// TODO: This should expose tamper alarm
// BUG: Multiple status events are being received for a single actual event sent from the device
type IASZoneCluster struct {
Channel
presence *channels.PresenceChannel
}
type IASZoneStatus struct {
Alarm1 bool
Alarm2 bool
Tamper bool
Battery bool
SupervisionReports bool
RestoreReports bool
Trouble bool
AC bool
Reserved1 bool
Reserved2 bool
Reserved3 bool
Reserved4 bool
Reserved5 bool
Reserved6 bool
Reserved7 bool
Reserved8 bool
}
func (c *IASZoneCluster) init() error {
log.Debugf("Initialising IAS Zone cluster of device % X", *c.device.deviceInfo.IeeeAddress)
stateChange := c.device.driver.gatewayConn.OnZoneState(*c.device.deviceInfo.IeeeAddress, *c.endpoint.EndpointId)
go func() {
for {
state := <-stateChange
status := &IASZoneStatus{}
readMask(int(*state.ZoneStatus), status)
c.presence.SendState(status.Alarm1)
}
}()
c.presence = channels.NewPresenceChannel()
err = c.device.driver.Conn.ExportChannel(c.device, c.presence, c.ID+"presence")
if err != nil {
log.Fatalf("Failed to announce presence channel: %s", err)
}
return nil
}
func readMask(mask int, target interface{}) {
targetValue := reflect.Indirect(reflect.ValueOf(target))
for i := 0; i < targetValue.NumField(); i++ {
value := (mask >> uint(i) & 1) > 0
f := targetValue.Field(i)
if f.CanSet() {
targetValue.Field(i).SetBool(value)
}
}
}