Solution Overview

Tested Platforms

Website Design

The main html file, index.html, uses the starter template of bootstrap.js library. This allows for responsive design support with navigation and a flexible grid.

Control Panel Design

On initial loading of the page, you will see a top navigation and grid of control cards. These cards are instances of modules that are loaded dynamically from the server.

A module is a template including html, javascript and css that is loaded from the server. A module can be instantiated multiple times with different settings. The instances are what get rendered as cards in the User Interface. The list of module instances to render on the page is retrieved from modules/instances.json.

To load the module instances as cards on the page, the Control Panel does the following from ModuleLoader.loadControlPanel:

  1. Retrieves modules/instances.json containing a listing of module instances
  2. For each module it loads these files: index.html (html template), script.js (js), styles.css (css)
  3. Iterates each instance finding all matching the current module and renders them to the page
  4. Each module is loaded in a bootstrap grid div <div class="col-xs-18 col-sm-6 col-md-3"></div> so that it adapts to smaller screen sizes

Note: The UI code in ModuleLoader is designed to only show maximum 4 modules per row. So a new row is created for every 4 module instances.

Module Design

Each module has a module id. The module's id is defined by its directory name (e.g. modules/thermostat has module id "thermostat").

In order to be loaded, the module's directory must have the following files:

Two modules are available out-of-the-box:

  1. Thermostat under modules/thermostat
  2. Light and Fan Control under modules/light-control

Retrieving Data from the Server

Control panel data updates are retrieved from data.json by the moduleDataManager object every 15s (see js/home-automation.js for the source code). In order to receive these updates, a module must register a listener via moduleDataManager.addListener(...). Note that the data is refreshed from the server every 15 seconds and since the application currently has no server-side code it just retrieves the original values. So if you flip switches of a card then the values would automatically go back to their old values.

Updating Data on the Server

Modules must use HTTP POST $.ajax({url: url, method: "post"}) requests to post updates back to the server. These updates need to be sent to modules/{custom-module-id}/data/{module-instance-id}.json.

Creating a Custom Control Panel Module

To create your own custom control panel module, follow these steps:

  1. Make a copy of an existing module under the modules directory
  2. Rename the copy (no whitespace in the name) - this will be your module id
  3. Modify these files in module's directory:
    • index.html - modify the html using bootstrap js controls and underscore js templating language. Note that the objects available to underscore js are the items retrieved from instances.json
    • script.js - change the name of the javascript object and modify the code in registerEventListeners and receiveData functions
    • styles.css - implement styles so they are specific to the module's html only so you don't break the control panel UI
  4. Add your module id in modules/modules.txt
  5. Create instances of your module in modules/instances.json
  6. Update the json files in the module's data folder to match the instance names and modify the json data as needed
  7. Update the data.json file (since in this test there are no real server interactions)