Skip to content

Commit 8b4a8a9

Browse files
authored
Merge branch 'master' into summary
2 parents 730f707 + d1cc43a commit 8b4a8a9

16 files changed

Lines changed: 249 additions & 2550 deletions

File tree

README.md

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,8 @@
1-
# SensorGridAPI
2-
Web API and dashboard for SensorGrid
1+
# SensorGrid API + SensorGrid Dashboard
2+
Web API and dashboard for the Knight Lab Studio SensorGrid project.
33

4-
## API
5-
To get the Django REST API set up:
4+
The API reads data in from the SensorGrid nodes, and then formats that data into JSON objects to be fed in to the dashboard. The dashboard then visualizes that data in a series of graphs and charts.
65

7-
`git clone https://github.com/NUKnightLab/SensorGridAPI.git`
8-
```
9-
git clone https://github.com/NUKnightLab/SensorGridAPI.git
10-
cd SensorGridAPI
11-
```
12-
If you have just installed the project, run:
13-
```
14-
mkvirtualenv sgapienv
15-
```
16-
Or if you have already run it before run this to get into the virtualenv:
17-
```
18-
workon sgapienv
19-
```
20-
After you are in the correct virtualenv, run:
21-
```
22-
pip install -r requirements.txt
23-
```
24-
Now that you have your environment set up and up to date,
25-
```
26-
cd sensorgridapi
27-
```
28-
To create a basic database:
29-
```
30-
./manage.py makemigration <APPNAME>
31-
./manage.py migrate
32-
```
33-
To start a local server and view the admin backend:
34-
```
35-
./manage.py runserver
36-
```
37-
To add an administrator to the site:
38-
```
39-
./manage.py createsuperuser
40-
```
41-
To work on Django in the command line:
42-
```
43-
./manage.py shell
44-
```
45-
## Dashboard
46-
To launch the dashboard:
47-
```
48-
cd sensorgriddashboard
49-
npm install
50-
```
51-
If the installation process runs successfully, you can start the dashboard by running:
52-
```
53-
npm start
54-
```
55-
56-
# API endpoints
57-
`/sensordata/?node_id=<INT>` - Returns an array of sensor data objects with the corresponding ID.
58-
59-
`/sensordata/created_at_lt=<EPOCH>` - Returns an array of sensor data objects created before the epoch timestamp inputted.
60-
61-
`/sensordata/created_at_gt=<EPOCH>` - Returns an array of sensor data objects created after the epoch timestamp inputted.
62-
63-
`/sensordata/?battery&node_id_include` - Returns an array of objects containing a node's ID and battery.
64-
65-
`/sensordata/?battery&node_id=<INT>` - Returns an array of objects containing the battery values of the specified node ID.
66-
67-
`/sensordata/?data&data_type&node_id=<INT>` - Returns an array of objects corresponding to the specified node ID with the value of each sensor's data point and SensorDataSerializer_timestamp corresponding data type.
68-
69-
`/sensordata/?data&data_type&node_id_include` - Returns an array of objects containing each node's ID, data value, and data type.
6+
To see the documentation for the dashboard, click [here](https://github.com/NUKnightLab/SensorGridAPI/blob/master/sensorgriddashboard/README.md).
707

8+
To see the documentation for the API, click [here](https://github.com/NUKnightLab/SensorGridAPI/blob/master/sensorgridapi/README.md).

dummydata/data.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dummydata/makejson.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,51 @@
11
var fs = require("fs")
22

3+
days_in_month = {1:31, 2:28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10:31, 11:30, 12:31}
4+
35
function mkJson() {
46
var sensordata = []
57
var data_types = ['gas', 'pm10', 'pm2.5', 'temp', 'humidity']
68
var node_id_lat = {1: 42.0556589, 2: 42.0413013, 3: 42.0507029, 4: 42.074439, 5: 42.0611052}
79
var node_id_long = {1: -87.6831799, 2: -87.6800576, 3: -87.6741602, 4: -87.6842669, 5: -87.6765987}
8-
for (var mo = 0; mo < 12; mo++) {
9-
for (var day = 1; day <= 28; day++) {
10+
for (var mo = 1; mo <= 12; mo++) {
11+
len_month = days_in_month[mo]
12+
for (var day = 1; day <= len_month; day++) {
1013
for (var hr = 0; hr < 24; hr++) {
1114
var battery = (Math.random() * 5).toFixed(2)
1215
var created_at = new Date(2017, mo, day, hr);
13-
var data_type = Math.floor((Math.random() * 4) + 1)
16+
var data_type = Math.floor((Math.random() * 4) + 1);
1417
var data = 0
1518
if (data_type == 0) {
16-
data = (Math.random() * 5).toFixed(2)
19+
data = (Math.random() * 5).toFixed(1)
1720
}
1821
else if (data_type == 1) {
19-
data = (Math.random() * 10).toFixed(2)
22+
data = (Math.random() * 10).toFixed(1)
2023
}
2124
else if (data_type == 2) {
22-
data = (Math.random() * 3).toFixed(2)
25+
data = (Math.random() * 3).toFixed(1)
2326
}
2427
else if (data_type == 3) {
25-
data = (Math.random() * 90).toFixed(2)
28+
if (mo == 1 || mo == 2 || mo == 12) {
29+
data = (Math.random() * 40).toFixed(1)
30+
}
31+
else if (mo == 3 || mo == 11) {
32+
data = (30 + (Math.random() * 20)).toFixed(1)
33+
}
34+
else if (mo == 4 || mo == 10) {
35+
data = (40 + (Math.random() * 25)).toFixed(1)
36+
}
37+
else if (mo == 5 || mo == 6) {
38+
data = (50 + (Math.random() * 30)).toFixed(1)
39+
}
40+
else if (mo == 7 || mo == 8) {
41+
data = (65 + (Math.random() * 25)).toFixed(1)
42+
}
43+
else if (mo == 9) {
44+
data = (55 + (Math.random() * 20)).toFixed(1)
45+
}
2646
}
2747
else if (data_type == 4) {
28-
data = (Math.random() * 100).toFixed(2)
48+
data = (60 + (Math.random() * 25)).toFixed(1)
2949
}
3050
var message_id = Math.floor(Math.random() * 1000);
3151
var network = Math.floor(Math.random() * 7);
@@ -36,8 +56,8 @@ function mkJson() {
3656
var recieved_at = new Date(2017, mo, day, hr);
3757
var record_id = Math.random().toString(36).substring(2, 8) + Math.random().toString(36).substring(2, 8);
3858
var timestamp = new Date(2017, mo, day, hr);
39-
var version = (Math.random() * 1).toFixed(2);
40-
sensordata.push({battery, created_at, data_type, data, message_id, network, node_id, latitude, longitude, ram,
59+
var version = (Math.floor(Math.random() * 10));
60+
sensordata.push({battery, created_at, data_type: data_types[data_type], data, message_id, network, node_id, latitude, longitude, ram,
4161
recieved_at, record_id, timestamp, version})
4262
}
4363
}

dummydata/postdata.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import json
2+
import requests
3+
import time
4+
from random import randint
5+
6+
# note: pushed data up to 14
7+
up_to = 142
8+
# Tuesday, March 6, 11:20AM
9+
10+
# read in dummy data file created by makejson.js
11+
data = json.load(open('data.json'))
12+
13+
# specify site url
14+
site_url = 'https://sensorgridapi.knightlab.com/sensordata/'
15+
# local server site: 'http://127.0.0.1:8000/sensordata/'
16+
# production site: 'https://sensorgridapi.knightlab.com/sensordata/'
17+
18+
for i in range(up_to, len(data)):
19+
print('posting data ' + str(i))
20+
# posts data to whichever site is specified by the site_url
21+
r = requests.post(site_url, json=data[i])
22+
print(r)
23+
if (r.status_code == 400):
24+
break
25+
time.sleep(randint(0,1))

dummydata/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
requests==2.18.4

sensorgridapi/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# API Setup
2+
To get the Django REST API set up:
3+
4+
```
5+
git clone https://github.com/NUKnightLab/SensorGridAPI.git
6+
cd SensorGridAPI
7+
```
8+
If you have just installed the project, run:
9+
```
10+
mkvirtualenv sgapienv
11+
```
12+
Or if you have already run it before run this to get into the virtualenv:
13+
```
14+
workon sgapienv
15+
```
16+
After you are in the correct virtualenv, run:
17+
```
18+
pip install -r requirements.txt
19+
```
20+
Now that you have your environment set up and up to date,
21+
```
22+
cd sensorgridapi
23+
```
24+
To create a basic database:
25+
```
26+
./manage.py makemigrations <APPNAME>
27+
./manage.py migrate
28+
```
29+
To start a local server and view the admin backend:
30+
```
31+
./manage.py runserver
32+
```
33+
To add an administrator to the site:
34+
```
35+
./manage.py createsuperuser
36+
```
37+
To work on Django in the command line:
38+
```
39+
./manage.py shell
40+
```
41+
42+
# API endpoints
43+
Note that for any endpoint you can include a `node_id=<INT>` to return only the data from that node. On the other hand, the command `node_id_include` will return a subset of the data model with `node_id` values, but will not allow you to filter that subset according to a specific `node_id`.
44+
45+
Below are the most vital endpoints for our SensorGrid Dashboard. To see all endpoints, go to `./sensorgridapi/sensordata/views.py`.
46+
47+
`/sensordata/?node_id=<INT>` - Returns an array of sensor data objects with the corresponding ID.
48+
49+
`/sensordata/created_at_lt=<EPOCH>` - Returns an array of sensor data objects created before the epoch timestamp inputted.
50+
51+
`/sensordata/created_at_gt=<EPOCH>` - Returns an array of sensor data objects created after the epoch timestamp inputted.
52+
53+
`/sensordata/?battery&node_id_include` - Returns an array of objects containing a node's ID and battery.
54+
55+
`/sensordata/?battery&node_id=<INT>` - Returns an array of objects containing the battery values of the specified node ID.
56+
57+
`/sensordata/?data&data_type&node_id=<INT>` - Returns an array of objects corresponding to the specified node ID with the value of each sensor's data point and SensorDataSerializer_timestamp corresponding data type.
58+
59+
`/sensordata/?data&data_type&node_id_include` - Returns an array of objects containing each node's ID, data value, and data type.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.9 on 2018-03-08 16:59
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('sensordata', '0010_auto_20180301_1710'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='sensordata',
17+
name='battery',
18+
field=models.DecimalField(decimal_places=2, max_digits=5, null=True),
19+
),
20+
migrations.AlterField(
21+
model_name='sensordata',
22+
name='data',
23+
field=models.DecimalField(decimal_places=2, max_digits=5, null=True),
24+
),
25+
migrations.AlterField(
26+
model_name='sensordata',
27+
name='version',
28+
field=models.IntegerField(null=True),
29+
),
30+
]

sensorgridapi/sensordata/models.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
# template for sensor grid data
77
class SensorData(models.Model):
8-
battery = models.DecimalField(max_digits=3, decimal_places=2, null=True)
8+
battery = models.DecimalField(max_digits=5, decimal_places=2, null=True)
99
created_at = models.DateTimeField(null=True)
10-
data = models.DecimalField(max_digits=3, decimal_places=2, null=True)
10+
data = models.DecimalField(max_digits=5, decimal_places=2, null=True)
1111
data_type = models.CharField(max_length=100, blank=True, default='')
1212
message_id = models.IntegerField(null=True)
1313
network = models.IntegerField(null=True)
@@ -18,7 +18,7 @@ class SensorData(models.Model):
1818
recieved_at = models.DateTimeField(auto_now_add=True)
1919
record_id = models.CharField(max_length=100, blank=True, default='')
2020
timestamp = models.DateTimeField(auto_now_add=True)
21-
version = models.DecimalField(max_digits=3, decimal_places=2, null=True)
21+
version = models.IntegerField(null=True)
2222

2323
class Meta:
2424
ordering = ('id',)

0 commit comments

Comments
 (0)