Challenge Overview
The goal of this challenge is to build NodeJS REST API for a home automation phonegap application.
Challenge Requirements
General Notes
-
- Prefix all endpoints with /api/
-
- You will use MongoDB, NodeJS, ExpressJS stack in this challenge.
Mongo Collections Definition
You will define the following collections :
User
-
- full_name (string)
-
- email (valid email address)
-
- password (salted)
House
Stores house basic metadata
-
- name (string)
-
- image (this full URL to the house image)
-
- user_id
House_users
-
- house_id
-
- user_id
-
- role (admin, operator, user, viewer)
House_info
Stores the savings setup
-
- house_id (reference House)
-
- type (one of the values : homeowner, landlord, resident) (required)
-
- number_of_resident (integer) (optional)
-
- resident_type (one of the values : student, family, senior, shared house) (optional)
-
- room_type - array of json objects, each item will have two fields (optional)
-
- type (one of the values : very small, small, medium, large, very large)
-
- quantity (integer)
-
-
- building_type (one of the values : Apartment, Dorm, Family Home ) (optional)
-
- unit_type - (used when type == landlord) array of json objects, each item will have following fields (optional)
-
- unity_type (one of the values : efficiency, 1br, 2br, 3br, 4br)
-
- number_of_units (integer)
-
- people (integer)
-
-
- temperature_unit (Celsius or Fahrenheit, by default Fahrenheit)
House_stats
Stores house stats
-
- house_id
-
- timestamp
-
- predicted_next_month_savings (will be % between 0% and 100%)
-
- last_month_savings (will be % between 0% and 100%)
-
- current_temperature
-
- outside_temperature
-
- current_humidity
Room
-
- house_id
-
- name (represents the room name)
-
- image (this is full URL to the room image)
-
- description
-
- size (one of the values : very small, small, medium, large, very large)
-
- vents_count
-
- windows_count
-
- current_tempreture
Room_schedule
Stores room schedule
-
- items : array of 24hrs values, each object has following fields :
-
- start_time : range between 00:00 to 23:59
-
- end_time : range between 00:00 to 23:59 (must be larger than start_time)
-
- value : the desired temperature value in that particular time period
-
-
- create_date (used to pull latest schedule)
Room_tempreture
Store room temperature
-
- room_id
-
- user_comfort_level (cold/cool/perfect/warm/hot/custom)
-
- target_temperature_value (float value)
-
- create_date (used to pull latest room temperature)
Room_plot
Store room historical data :
-
- year (YYYY): The year of the sample
-
- month (MM): The month of the sample
-
- day (DD): The day of the sample
-
- hour (HH): The hour of the sample (0-24)
-
- minute (MM): The minute of the sample
-
- second (float): The second of the sample
-
- inDST (0/1): Daylight Savings Time flag. 1 is true (data collected in DST), 0 is false (data collected not in DST)
-
- timetamp : this is the timestamp value of collected sample data, broken down values are in year/month/day/hour/minute/second fields
-
- light (ohms): Float value. Ranges from “infinite” (99999999) to 0, “pitch black” to very bright
-
- temp_analog (Fahrenheit): Float value. Analog temperature sensor
-
- IR: Float value. Values for infrared or motion range from 0 (no activity) to 3.34 (sensor tripped).
-
- temp_digital (Fahrenheit): Float value. Digital temperature sensor
-
- current_temp : float value
-
- outside_temp : float value
-
- desired_temp : float value
-
- fast_humidity (%): Float value. The sensor’s quick calculation of humidity
-
- slow_humidity (%) : Float value. The sensor’s slower calculation of humidity
Room_alerts
Store alerts per room
-
- room_id
-
- type : warning/error
-
- timestamp
-
- details (string)
-
- status : current/resolved
Room_energy_savings
-
- room_id
-
- pre_system_energy_expenditure (float): Energy per day expended before sys install
-
- post-system_energy_expenditure (float): Energy per day expended after sys install
-
- energy_savings (float): Energy saved per day
-
- timestamp
API Endpoint
Role Authorization
-
- Admin : can change the permissions/roles of other users, in addition to the roles below.
-
- User : can set temperatures, addition to the roles below.
-
- Operator : can set up the houses, rooms, enter details (cannot set temperatures)
-
- Viewer : can view the data, the plots, the setup, but cannot change anything.
We need the following API Endpoints :
Signup
-
- Route : POST /signup
-
- input parameters are :
-
- fullname (required)
-
- password (required)
-
- email (required)
-
-
- create new user model, password should be hashed.
-
- no role will be set for signed up user.
-
- response should be the created document.
Login
-
- Route : POST /signin
-
- Input parameters :
-
- email
-
- password
-
-
- Validate username/password and login the user.
-
- If the authorization are valid, then use JWT to generate token, with configurable expiration date, then return generated authorization token in response.
-
- The token is required by all endpoints except login, signup, forgot password, reset password.
Me
-
- Returns current logged in user information
-
- Route : GET /me
-
- Logic :
-
- Return the user document (excluding password) of the current logged in user
-
Get Houses
-
- This endpoint is used to return houses of the user.
-
- Route : GET /houses
-
- Logic :
-
- Retrieve all houses where house#user_id == logged in user
-
-
- Return response in json format.
Get House Details
-
- This endpoint is used to return house information
-
- Route : GET /houses/{id}
-
- Input parameter :
-
- id : represents house id
-
-
Logic :
-
- Retrieve house document of the passed id
-
- Retrieve the house_info document of the passed id
-
- Retrieve the house_stats document of the passed id
-
- Add house_info and house_stats as child objects to house document and return it in json format.
-
House Current Stats
-
- Used to retrieve the current stats displayed in 02A ~ Initial Screen.jpg
-
- Route : GET /house/{id}/stats
-
- Input parameters :
-
- id : represents the house id
-
-
- Logic :
-
- Retrieve the house_stats of the passed house id
-
- Retrieve the house#temperature_unit of the passed house id
-
- Return the information in json format
-
-
Response fields :
-
- house_stats fields
-
- house#temperature_unit
-
Set Room
-
- Used to add or update room.
-
- Route : POST /rooms
-
- Input parameter :
-
- room_id
-
- house_id (for a given house)
-
- bundle_id (represents room name)
-
- description (name of the room)
-
- size
-
- vents_count
-
- windows_count
-
- schedule : array of json objects with following fields :
-
- start_time : range between 00:00 to 23:59
-
- end_time : range between 00:00 to 23:59 (must be larger than start_time)
-
- value : the temperature value
-
-
-
- All fields are optional if update operation, excluding room_id.
-
- All fields are required if create operation, excluding room_id.
-
- Logic :
-
- Validate input parameters
-
- If room_id is provided then validate room exists, otherwise, return error.
-
- If room_id not provided : Create new ‘room’ document.
-
- If room_id is provided then update the room document.
-
- ‘Create new ‘room_schedule’ document
-
- schedule array will be stored in room_schedule#items array
-
- create_date : set to current date
-
-
- Return the created/updated room and schedule object in json format
-
Get Room
-
- This endpoint is used to get room details
-
- Route : GET /rooms/{id}
-
- Input parameter :
-
- id : represents the room id
-
-
- Logic :
-
- Retrieve room document of the passed id
-
- Retrieve latest room_schedule document of the passed id
-
- Retrieve latest room_tempreture document of the passed id
-
- Add room_schedule and room_tempreture as child objects of house document and return it in json format.
-
Get Alerts
-
- This retrieves Alerts of selected rooms
-
- Route : GET /alerts
-
- Input parameter :
-
- ids (required) : array of room ids, if missing
-
- status (optional) : corresponds to room_alerts#status, if missing, we return all alerts
-
-
- Logic :
-
- Retrieve the room_alerts documents of the passed in ids and status, and populate the room name of each document.
-
-
- Return documents in json format.
Set Room Temperature
-
- This endpoint is used to handle saving changes made in 04 ~ Set Temperature.jpg screen.
-
- Route : POST /room/{id}/temperature
-
- Input parameter :
-
- id (path parameter): represents the room id
-
- user_comfort_level (required)
-
- target_temperature_value (required)
-
-
- Logic :
-
- Insert new Room_temperature document using the provided values
-
- Set create_date to current date.
-
- Return created document as response in json format.
-
Get Room Temperature
-
- Used to retrieve room latest temperature value.
-
- Route : GET /room/{id}/temperature
-
- Input Parameter :
-
- id : the room id
-
-
- Logic :
-
- Retrieve latest room_temperature record of the passed room id
-
-
- Response will be in json format.
Get Room Temperature Plot Data
-
- Used to retrieve plot data for chart in 05A ~ View Data.jpg screen.
-
- Route : GET /rooms/plot
-
- Input parameters :
-
- ids (required) : comma separated room ids
-
- start_date (optional)
-
- end_date (optional)
-
-
- Logic :
-
- Validate dates parameters and id.
-
- If start_date and end_date are not set then it should return data of the past 24hrs.
-
- Aggregate Room_plot of the passed room ids (compute the average for the groups of data, grouping as below), depends on the start/end date range group the data :
-
- 1 day : group by hour
-
- 3 days : group by 6 hrs
-
- 7 days : group by 12 hours
-
- < 30 days : group by day
-
- > 30 days : group by week
-
-
- Calculate the average Room_energy_savings values for the passed rooms and start/end date range and return the fields :
-
- avg_pre_system_energy_expenditure
-
- avg_post-system_energy_expenditure
-
- avg_energy_savings
-
-
- Response will be 3 arrays :
-
- 1st array : current_temp/timestamp values
-
- 2nd array : outside_temp/timestamp values
-
- 3rd array : desired_temp/timestamp values
-
-
Set Rooms Schedule
-
- This is used to set multiple rooms schedules
-
- Route : POST /schedules
-
- Input parameter :
-
- room_schedules (required) : it will be an array of array items, each item will contain these fields :
-
- room_id
-
- schedule : an array of json objects with following fields :
-
- start_time : range between 00:00 to 23:59
-
- end_time : range between 00:00 to 23:59 (must be larger than start_time)
-
- value : the temperature value
-
-
-
-
- Logic :
-
- Validate parameters
-
- Create new ‘room_schedule’ document for each room_id
-
- schedule array will be stored in room_schedule#items array
-
- create_date : set to current date
-
-
-
- Return created schedules in response in json format.
Get Rooms Schedule
-
- This endpoint is used to get latest rooms schedule
-
- Route : GET /schedules
-
- Input parameter :
-
- ids : comma separated room ids
-
-
- Logic :
-
- Using create_date return latest room_schedule record of each room_id
-
-
- Return the information in response in json format.
Set House User
-
- This endpoint used to edit or add new user.
-
- Route : POST /users
-
- Input parameters :
-
- house_id (required always)
-
- user_id (required if we want to add existing user to house)
-
- full_name (required if we want to add new user)
-
- email (required if we want to add new user)
-
- role (required always)
-
-
- Logic :
-
- If new user, then create new user record
-
- Send email the user
-
- Store association in house_user collection.
-
-
- Return created user with associated house id in response.
Get User
-
- Get User information
-
- Route : GET /users/{id}
-
- Input parameter :
-
- id : the user id
-
-
- Logic :
-
- Retrieve the user of the provided id
-
- Return the user document in response in json format.
-
Get House Users
-
- Get users of specific house
-
- Route : GET /houses/{id}/users
-
- Input parameter :
-
- id : the house id
-
-
- Logic :
-
- Retrieve the users of the passed house from house_user
-
- Populate all users (exclude password)
-
- Return the users list in json format
-
Get Users
-
- Get list of all users in the application
-
- Route : GET /users
-
- Logic :
-
- Return list of all users in the application
-
- The response should exclude users passwords.
-
Remove House User
-
- Remove user association with a house
-
- Route : DELETE /house/{id}/users/{user-id}
-
- Input parameters :
-
- id : house id
-
- user-id : the user id to be removed
-
-
- Logic : Remove the house_user document of the provided parameters
Calculate Savings
-
- Used to calculate savings in screen 07A ~ Savings Setup.jpg
-
- Route : GET /houses/{id}/calculate
-
- Input parameter :
-
- id : the house id
-
-
- Logic :
-
- Return json object with two fields :
-
- savings_percentage : i.e. 20
-
- savings_per_day: i.e. 100
-
-
Pagination
In all get-all endpoints we need to enforce pagination, these endpoints should have the following parameters :
-
- offset (default 0)
-
- limit (default 10)
The parameters should be returned in the response with the total count of matching records as well, It is preferred if the default values are configurable.
Test Data
-
- Provide sample test data to feed the mongo database for testing purpose, specifically the room_plot collection.
Postman Client JSON
-
- Create postman json file listing all calls and sample data.
-
- Provide description for endpoints (recent postman version support endpoint descriptions)
-
- Get Started with Postman : http://www.getpostman.com/
Documentation
Provide a detailed README documentation for how to setup and configure the application.
Final Submission Guidelines
Deliverable
-
- All source code that implement the requirement.
-
- README in markup language
-
- Verification document contains steps to verify your solution.