Iot Api Server Backend Django Api

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

IoT API Server Backend Django API

I am looking for a developer who has experience in building APIs.


The scenario is following:
IoT devices are sending batches of JSON data every 1-30 seconds to the API server. The API
server should store this data and allow the user to fetch/filter this data (JSON).
I need a very simple admin interface for setting up the data structure.
Every day 100k sensor_data rows arrive.
It should be a lightweight api server using Postgres.

There should be an admin login where the admin can see the models and data entries
Relationships/Model

 Admin can create a company (his customer)


 Admin can create locations
 A company has many locations
 Admin can create sensors
 A location has many sensors
 A sensor has many sensor_data
Admin:
Username (string)
Password (string)

Company:
ID (int)
company_name (string)
company_api_key (Generated when creating the entity. Will be used for /GET data commands)
(string)

Location:
company_id (int)
location_name (string)
location_country (string)
location_city (string)
location_postal_code (string)
location_meta (string)

Sensor:
location_id (int)
sensor_id (int)
sensor_name (string)
sensor_category (string)
sensor_meta (string)
sensor_cnn_version (integer), default: 52
sensor_api_key (string) (Generated when creating the entity, used for inserting the data from the
IoT)
Sensor Data:
t.string :uuid, null: false, unique: true
t.integer :sensor_id, null: false
t.integer :start_rec_at , null: false
t.integer :stop_rec_at , null: false
t.integer :duration , null: false
t.integer :attention_duration , null: false
t.integer :times_resumed , null: false
t.text :face_descriptor
t.integer :cnn_version , null: false
# attributes
t.integer :age , null: false
t.integer :gender , null: false
t.integer :ethnicity , null: false
t.integer :glasses , null: false
# emotions avg
t.integer :avg_smile , null: false
t.integer :avg_happiness , null: false
t.integer :avg_neutral , null: false
t.integer :avg_surprise , null: false
t.integer :avg_fear , null: false
t.integer :avg_sadness , null: false
t.integer :avg_anger , null: false
t.integer :avg_disgust , null: false
# emotions min
t.integer :min_smile , null: false
t.integer :min_happiness , null: false
t.integer :min_neutral , null: false
t.integer :min_surprise , null: false
t.integer :min_fear , null: false
t.integer :min_sadness , null: false
t.integer :min_anger , null: false
t.integer :min_disgust , null: false
# emotions max
t.integer :max_smile , null: false
t.integer :max_happiness , null: false
t.integer :max_neutral, null: false
t.integer :max_surprise , null: false
t.integer :max_fear , null: false
t.integer :max_sadness , null: false
t.integer :max_anger , null: false
t.integer :max_disgust , null: false
#face hash
t.string :face_hash_uuid
JSON Sensor Data that is being sent by the sensor
{“api_key”:<sensor_api_key>, “json_data”:[{…},{….}]}

The attributes are exactly the sensor_data model attributes, only cnn_version and id has to be
fetched from Sensor model and face_hash_uuid should stay blank for now. The sensor_api_key
in the JSON will tell us which sensor_id to pick. So whenever you receive a JSON, you need to
loop through json_data (array of hashes). If the api key is wrong or no sensor associated to that
key, return 400 error. Use bulk insert for inserting, so we don’t hit the database so many times.

API Endpoints

Standard REST API Endpoints for each model except of Admin and Company
Show all, show single, edit, delete. GET GET PUT DELETE
All API methods require the company_api_key, except inserting sensor_data (it will use the
sensor_api_key).

The auth should be possible through HTTP Header or has URL param &company_api_key=

The most important one is sensor_data, which has to look a bit different
POST /api/v1/sensor_data
(Inserting sensor_data to the DB using sensor_api_key for auth)
It should return HTTP Status 201 (created)

GET /api/v1/sensor_data
(Fetches sensor_data)
Required parameters:
The auth should be possible through HTTP Header or has URL param &company_api_key=
from = <epoch time Integer seconds accuracy datetime range>
to = <epoch time Integer seconds accuracy datetime>
sensor_id = [2,3,4,5,10,220] Array of sensor_ids for which to get the sensor_data
Optional parameters (defaults):
page=1
per_page=100
sort=asc,desc
ethnicity = 0
glasses = 0
face_descriptor = 0
all_emotions = 0
basic_emotions = 0
human_date = 0
with_sensor = 0
with_location = 0
with_company = 0

(Default per page=100), the response should how many total elements and the next_page_url (if
available)
Default sorted by oldest element start_rec_at
Ethnicity = 0 means, the ethnicity column of sensor_data should not be returned
Same for all others glases, face_descriptor etc.
If the value is 1 it should be returned.
basic_emotions = 1 are

selection.push("avg_happiness".to_sym)
selection.push("avg_neutral".to_sym)
selection.push("avg_anger".to_sym)
selection.push("min_happiness".to_sym)
selection.push("min_neutral".to_sym)
selection.push("avg_anger".to_sym)
selection.push("max_happiness".to_sym)
selection.push("max_neutral".to_sym)
selection.push("max_anger".to_sym)

(ignore selection push … it is old ruby code, just look at the “” as attribute name copy/pasted).
all_emotions = 1

selection.push("avg_smile".to_sym)
selection.push("avg_happiness".to_sym)
selection.push("avg_neutral".to_sym)
selection.push("avg_surprise".to_sym)
selection.push("avg_fear".to_sym)
selection.push("avg_sadness".to_sym)
selection.push("avg_anger".to_sym)
selection.push("avg_disgust".to_sym)

selection.push("min_smile".to_sym)
selection.push("min_happiness".to_sym)
selection.push("min_neutral".to_sym)
selection.push("min_surprise".to_sym)
selection.push("min_fear".to_sym)
selection.push("min_sadness".to_sym)
selection.push("min_anger".to_sym)
selection.push("min_disgust".to_sym)

selection.push("max_smile".to_sym)
selection.push("max_happiness".to_sym)
selection.push("max_neutral".to_sym)
selection.push("max_surprise".to_sym)
selection.push("max_fear".to_sym)
selection.push("max_sadness".to_sym)
selection.push("max_anger".to_sym)
selection.push("max_disgust".to_sym)

human_date = 1
means start_rec_at stop_rec_at translated as datetime human readable instead of epoch
integers. UTC
dd.mm,yyyy hh:mm:ss

The standard output will be only this:

:uuid,:sensor_id,:start_rec_at,:stop_rec_at,:age,:gender

Joining table
With_sensor = 1:
Also returning the sensor attributes of the sensor model (don’t include sensor_api_key)
With_location= 1
Also returning the location attributes of the location model
With_company= 1
Also returning the company attributes of the location (don’t include company_api_key)

You might also like