-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbodh.py
183 lines (151 loc) · 5.59 KB
/
bodh.py
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
import click
import requests
import json
import csv
from os import path, makedirs
from time import sleep
from config_path import ConfigPath
from random import uniform
default_host = "https://bodh.iotready.co"
conf_path = ConfigPath( 'bodh', 'iotready.co', '.json' )
file_path = conf_path.saveFilePath( mkdir=False )
@click.group()
def cli():
pass
@cli.command()
@click.option('--host', default=default_host, prompt="Bodh host", help='Bodh host (for self-hosted).')
@click.option('--apikey', prompt='Admin API key', help='Admin API key to save.')
def configure(host, apikey):
"""Save host and apikey in the user's config directory."""
config = {
"api_key": apikey.strip(),
"host": host.strip(),
}
with open(file_path, "w") as f:
json.dump(config, f)
click.echo('Stored config at: %s' % file_path)
def read_saved_config():
path = conf_path.readFilePath()
assert path, "Could not locate config file. Please run `bodh configure` first."
with open(file_path, "r") as f:
config = json.load(f)
host = config['host']
api_key = config['api_key']
assert host and api_key, "Could not detect host or API key. Please run `bodh configure` again."
return host, api_key
@cli.command()
@click.option('--deviceid', prompt='Device ID', help='ID of device to register')
def register(deviceid):
"""Register a device using the apikey."""
host, api_key = read_saved_config()
url = host + "/api/devices"
payload = {
"device": {
"id": deviceid
}
}
headers = {
'Accept': 'application/json',
'x-api-key': api_key,
'Content-Type': 'application/json'
}
res = requests.post(url, data = json.dumps(payload), headers = headers)
data = res.json()
base_path = "certs/{}".format(deviceid)
mkdir(base_path)
for key, url in data.items():
download_file(url, base_path)
click.echo("Use the saved certifcates to connect device with ID {} to AWS IoT!".format(deviceid))
def download_file(url, base_path):
r = requests.get(url, allow_redirects=True)
file_name = get_file_name(url)
file_path = path.join(base_path, file_name)
print("Downloading", file_path)
with open(file_path, 'wb') as f:
f.write(r.content)
def get_file_name(url):
return url.split('?')[0].split('/')[-1]
def mkdir(path):
makedirs(path, exist_ok=True)
@cli.command()
@click.option('--deviceid', prompt='Device ID', help='ID of device for which to send a test event.')
@click.option('--interval', prompt='Interval', default=5, type=int, help='Interval between test events (min = 5s).')
@click.option('--maxcount', prompt='Max Count', default=10, type=int, help='Max events to send.')
def simulate(deviceid, interval, maxcount):
"""Sends `maxcount` test events using the apikey."""
# if interval < 5:
# interval = 5
# print("Using min interval of 5s")
host, api_key = read_saved_config()
url = host + "/api/events"
headers = {
'Accept': 'application/json',
'x-api-key': api_key,
'Content-Type': 'application/json'
}
for i in range(0, maxcount):
payload = {
"event": {
"device_id": deviceid,
"data": {
"current1": round(uniform(100, 600),2),
"current2": round(uniform(100, 600),2),
"current3": round(uniform(100, 600),2),
"voltage1": round(uniform(23500, 24500),2),
"voltage2": round(uniform(23500, 24500),2),
"voltage3": round(uniform(23500, 24500),2),
"temperature": round(uniform(70, 95),2),
}
}
}
res = requests.post(url, data=json.dumps(payload), headers=headers)
data = res.json()
click.echo(data)
sleep(interval)
@cli.command()
@click.option('--devicelist', prompt='Device List', help='CSV file containing list of devices to import. See template.csv for format.')
@click.option('--creatething', default=False, type=bool, prompt='Create AWS IoT Thing', help='Should we create these things on AWS IoT?')
def bulkimport(devicelist, creatething):
"""Register devices imported from a CSV file."""
host, api_key = read_saved_config()
url = host + "/api/devices"
headers = {
'Accept': 'application/json',
'x-api-key': api_key,
'Content-Type': 'application/json'
}
skip = False
try:
with open('last_synced.txt', 'r') as f:
last_device_id = f.read()
if last_device_id:
skip = True
except:
last_device_id = ''
pass
with open(devicelist, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
if row['id'] == last_device_id:
skip = False
if skip:
continue
payload = {
"device": {
"id": row['id']
}
}
res = requests.post(url, data = json.dumps(payload), headers = headers)
data = res.json()
if creatething:
base_path = "certs/{}".format(deviceid)
mkdir(base_path)
for key, url in data.items():
download_file(url, base_path)
click.echo("Use the saved certifcates to connect device with ID {} to AWS IoT!".format(deviceid))
else:
click.echo(data)
with open('last_synced.txt', 'w') as f:
f.write(row['id'])
if __name__ == '__main__':
cli()