-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathdynamo.go
211 lines (174 loc) · 4.8 KB
/
dynamo.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package main
// This module will talk to DynamoDB and get a list of all the defined
// buttons and return them in an array structure.
//
// MAGIC! Button 100000+ contains state information
// Don't define a button with these IDs!
//
// Alexa limits you to maybe 100 (or 300?) buttons
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
"log"
"strconv"
)
// There must be a better way of doing this!
const (
DB_MAX_VAL = 99999
DB_TOKEN_PSWD = 100000
DB_TOKEN_AUTH = 100001
DB_TOKEN_ALEXA_ID = 100002
DB_TOKEN_ALEXA_SECRET = 100003
DB_TOKEN_INSECURE = 100004
DB_API_ENDPOINT = 100005
TABLE_NAME = "Smart_Home_Virtual_Buttons"
)
// This is all we care about for a button; the ID and the name
type Button struct {
ButtonID int `json:"buttonid"`
Name string `json:"buttonname"`
State int `json:"buttonstate"`
}
// This will query DynamoDB and get a list of all the buttons.
func get_buttons(all bool) []Button {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB client
svc := dynamodb.New(sess)
result, err := svc.Scan(&dynamodb.ScanInput{
TableName: aws.String(TABLE_NAME),
})
if err != nil {
log.Fatalf("Got error calling Scan: %s", err)
return nil
}
// For each button add them to the slice
var buttons []Button
for c := 0; c < len(result.Items); c++ {
b := Button{}
dynamodbattribute.UnmarshalMap(result.Items[c], &b)
// If the button has no name then set a default one
if b.Name == "" && b.ButtonID <= DB_MAX_VAL {
b.Name = fmt.Sprintf("switch-%06d", b.ButtonID)
}
if all || b.ButtonID <= DB_MAX_VAL {
buttons = append(buttons, b)
}
}
return buttons
}
func get_button_by_id(id int) Button {
var button Button
buttons := get_buttons(true)
for _, v := range buttons {
if v.ButtonID == id {
button = v
}
}
return button
}
func get_button_by_name(name string) Button {
var button Button
button.ButtonID = -1
buttons := get_buttons(true)
for _, v := range buttons {
if v.Name == name {
button = v
}
}
return button
}
func get_button_name(id int) string {
return get_button_by_id(id).Name
}
func set_button_name(id int, token string) string {
if id < 0 {
return "Bad ID number: " + strconv.Itoa(id)
}
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB client
svc := dynamodb.New(sess)
input := &dynamodb.UpdateItemInput{
TableName: aws.String(TABLE_NAME),
// Update command
UpdateExpression: aws.String("set buttonname = :t"),
// Where clause
Key: map[string]*dynamodb.AttributeValue{
"buttonid": {N: aws.String(strconv.Itoa(id))},
},
// Bind variable
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":t": {S: aws.String(token)},
},
ReturnValues: aws.String("UPDATED_NEW"),
}
_, err := svc.UpdateItem(input)
if err != nil {
return "Error updating button: " + err.Error()
}
return "Update Success"
}
func set_button_state(id int, state int) string {
if id < 0 || id > DB_MAX_VAL {
return "Bad ID number: " + strconv.Itoa(id)
}
// Push an immediate update to Alexa
push_update(id, state, false)
// Update DynamoDB
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB client
svc := dynamodb.New(sess)
input := &dynamodb.UpdateItemInput{
TableName: aws.String(TABLE_NAME),
// Update command
UpdateExpression: aws.String("set buttonstate = :t"),
// Where clause
Key: map[string]*dynamodb.AttributeValue{
"buttonid": {N: aws.String(strconv.Itoa(id))},
},
// Bind variable
ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
":t": {N: aws.String(strconv.Itoa(state))},
},
ReturnValues: aws.String("UPDATED_NEW"),
}
_, err := svc.UpdateItem(input)
if err != nil {
return "Error updating button: " + err.Error()
}
return "Update Success"
}
func toggle_button_state(id int) string {
button := get_button_by_id(id)
newstate := 1
if button.State != 0 {
newstate = 0
}
return set_button_state(id, newstate)
}
func delete_button(id int) string {
sess := session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
// Create DynamoDB client
svc := dynamodb.New(sess)
input := &dynamodb.DeleteItemInput{
TableName: aws.String(TABLE_NAME),
Key: map[string]*dynamodb.AttributeValue{
"buttonid": {N: aws.String(strconv.Itoa(id))},
},
}
_, err := svc.DeleteItem(input)
if err != nil {
return "Error Deleting button: " + err.Error()
}
return "Delete Success"
}