-
Notifications
You must be signed in to change notification settings - Fork 1
/
attrs.go
133 lines (109 loc) · 3.77 KB
/
attrs.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package goiio
// CompareDevice is a type passed to Context.GetDevice
// implementing some kind of comparison function
type CompareDevice func(*Device) bool
// CompareContextAttribute is a type passed to Context.GetAttribute
// implementing some kind of comparison function
type CompareContextAttribute func(*ContextAttribute) bool
// CompareChannel is a type passed to Device.GetChannel
// implementing some kind of comparison function
type CompareChannel func(*Channel) bool
// CompareChannelAttribute is a type passed to Channel.GetAttribute
// implementing some kind of comparison function
type CompareChannelAttribute func(*ChannelAttribute) bool
type attributeOperation func(float64, float64) float64
type attributeOp struct {
name string
op attributeOperation
}
var attributeOps = []attributeOp{
{name: "raw", op: func(c, v float64) float64 { return v }},
{name: "input", op: func(c, v float64) float64 { return v }},
{name: "offset", op: func(c, v float64) float64 { return c + v }},
{name: "scale", op: func(c, v float64) float64 { return c * v }},
}
// GetDevice fetches the first device from the context satisfying the comparison
// function
func (c *Context) GetDevice(comp CompareDevice) *Device {
for _, device := range c.Devices {
if comp(device) {
return device
}
}
return nil
}
// GetDeviceByName fetches the first device with given name
func (c *Context) GetDeviceByName(name string) *Device {
return c.GetDevice(func(d *Device) bool { return d.Name == name })
}
// GetDeviceByID fetches the first device with given name
func (c *Context) GetDeviceByID(id string) *Device {
return c.GetDevice(func(d *Device) bool { return d.ID == id })
}
// GetDeviceByNameOrID fetches the first device that does not mismatch given
// name or id. If only name is given, it behaves like GetDeviceByName and when
// only id is given like GetDeviceByID. When both are given, it matches on
// both attributes and when none are given, it matches any first device.
func (c *Context) GetDeviceByNameOrID(name, id *string) *Device {
return c.GetDevice(func(d *Device) bool {
if name != nil && d.Name != *name {
return false
}
if id != nil && d.ID != *id {
return false
}
return true
})
}
// GetAttribute fetches the first attribute from the context satisfying the comparison
// function
func (c *Context) GetAttribute(comp CompareContextAttribute) *ContextAttribute {
for _, attr := range c.ContextAttributes {
if comp(attr) {
return attr
}
}
return nil
}
// GetAttributeByName fetches the first attribute with given name
func (c *Context) GetAttributeByName(name string) *ContextAttribute {
return c.GetAttribute(func(c *ContextAttribute) bool { return c.Name == name })
}
// GetChannel fetches the first channel from the device satisfying the comparison
// function
func (d *Device) GetChannel(comp CompareChannel) *Channel {
for _, ch := range d.Channels {
if comp(ch) {
return ch
}
}
return nil
}
// GetChannelByID fetches the first attribute with given ID
func (d *Device) GetChannelByID(id string) *Channel {
return d.GetChannel(func(c *Channel) bool { return c.ID == id })
}
// GetAttribute fetches the first attribute from the channel satisfying the comparison
// function
func (c *Channel) GetAttribute(comp CompareChannelAttribute) *ChannelAttribute {
for _, attr := range c.Attributes {
if comp(attr) {
return attr
}
}
return nil
}
// GetAttrByName fetches the first attribute with given name
func (c *Channel) GetAttrByName(name string) *ChannelAttribute {
return c.GetAttribute(func(ca *ChannelAttribute) bool { return ca.Name == name })
}
func (c *Channel) GetValue() float64 {
var current float64
for _, attrOp := range attributeOps {
a := c.GetAttrByName(attrOp.name)
if a != nil {
current = attrOp.op(current, a.Value)
}
}
return current
}