App Development Tutorial 1

Contents

Tutorial 1: Getting Started

This tutorial will give you a basic introduction to creating smart home automation apps using the CHAOS platform. At the end of this tutorial you will be able to create, run and test a traditional "Hello World" app.

If you haven't already, please download the CHAOS Demonstrator software, available here.

Developing CHAOS Apps

First let's look at how to start, edit and run a new CHAOS app.

New App

To create a new app click the 'New' button. You will be presented with a dialog asking for the name of your new app. Let's use the name "Hello World" for this app:

New App Dialog


Click "OK" and the CHAOS demonstrator will automatically create skeleton code for a CHAOS app that looks like this:

from __future__ import print_function
from ChaosApps import BaseChaosApp

class ChaosApp(BaseChaosApp):
        def run(self):
                self.appName='Hello World'
                self.print("Skeleton App '"+self.appName+"' Running")

                #Connect devices to other devices and functions here...

        def initAppGui(self):
                self.print("'" + self.appName + "': CHAOS has asked for the current HTML of the phone app GUI for this CHAOS App")

                htmlString = """appGuiConstructionString"""

                return htmlString

        def appGuiInteractionCallback(self,someData):
                self.print(self.appName + ": Some information has arrived for this CHAOS App from the phone GUI ")

        def stop(self):
                self.print("Disconnecting any created signals and then stopping '" + self.appName + "'")


Users familiar with Python will see that a CHAOS app is a Python class called ChaosApp which inherits from a base class, called BaseChaosApp. If you're not familiar with Python; don't worry, just know that this is the structure necessary for a CHAOS app.

App Structure

A basic CHAOS app has 4 methods (or function):

  1. run(self): As soon as the app is started, the run() method is executed to perform the necessary setup steps. This is where instance variables (variables which exist only for this app and are accessible from all methods in this app) can be created and connections between devices and other devices and methods are defined. We will discuss the setup of connections to and from devices later, sufficed to say that the run method is where most of the app is setup for running. At the very minimum the appName variable must be assigned a value here, or CHAOS will not be able to handle the app.
  2. initAppGui(self): This function is called by CHAOS when it wants to know how to construct the phone GUI for this app. This function should return a block of HTML code describing what to present to the user for this app in the phone dashboard. If the "initAppGui(self):" function returns an empty string, nothing will be rendered for this app in the phone GUI. Any buttons which call the javascript method sendMessage(this,'...') will cause the app method "appGuiInteractionCallback(self,someData)" to be called.
  3. appGuiInteractionCallback(self,someData): When the javascript method sendMessage(this,'...') is called in the phone GUI, it will send a message to the relevant CHAOS app which will in turn call the appGuiInteractionCallback(self,someData) method in that app. The someData argument passed into this method will contain the string which was the second argument in the sendMessage(this,'...') javascript method call. In this way, messages from buttons pushed in the GUI can be routed back to the very app which constructed the buttons.
  4. stop(self): This method will be executed just before the app is stopped. This method is rarely necessary. Since Python handles it's own garbage collection, this method is just for tearing down connections from a signal of one device to a slot in another device as this type of connection won't automatically be deleted when this app is destroyed. This will be explained in a later tutorial.

Saving and Running the App

Now that a skeleton app has been created, we can run the app. If you make any changes to the app you should press "Save" first, the click "Run" to start (or restart) the app:

Test caption text

When we click "Run" the following should appear in the debug console:

SkeletonAppDebugConsole.png

When you consider the skeleton code, you can see that the line "Skeleton App 'Hello World' Running" is printed out when the run(self) method is called and the line "'Hello World': CHAOS has asked for the current HTML..." is printed out when the initAppGui(self) method is called. Hence, it should be evident that when the "Run" button is pushed, CHAOS first calls run(self) to setup the app and then calls initAppGui(self) to populate the phone GUI.

Stopping the App

You should rarely need to explicitly stop an app since when you press "Run" it will automatically stop the app if it is already running, before starting it again. However, if you wish to stop the app without restarting it, it can be stopped from within the App Drawer.

If you hover the mouse over the App Drawer button:

AppDrawerButton.png

you will be presented with the App Drawer:

OpenAppDrawer.png

In the App Drawer, apps which are currently running are coloured green and apps which are not running are coloured yellow. The "Stop" button on each app can be used to stop an individual app. Also, using the App Drawer you can press the "Run" button on each individual app to run several apps at once to test how they coexist.

Hello World

All that we've learned so far is worthless until we can follow a tradition as old as the hills, and create a "Hello World" app.

Objective

The purpose of this example is to output the line "Hello World" in a new line in the Debug Console. Here is an example of what it would look like:

HelloWorldDebugConsole.png

Note that the extra "Hello World" is outputted just after the app is created and just before the phone GUI HTML is requested. Confirm to yourself that you can produce this behaviour before going any further.

Solution

Attempt to get the desired result yourself first, then expand this box to view one possible solution:

Example Solution:

from __future__ import print_function
from ChaosApps import BaseChaosApp

class ChaosApp(BaseChaosApp):
        def run(self):
                self.appName='Hello World'
                self.print("Skeleton App '"+self.appName+"' Running")

                #Connect devices to other devices and functions here...

                self.print("Hello World")

        def initAppGui(self):
                self.print("'" + self.appName + "': CHAOS has asked for the current HTML of the phone app GUI for this CHAOS App")

                htmlString = """appGuiConstructionString"""

                return htmlString

        def appGuiInteractionCallback(self,someData):
                self.print(self.appName + ": Some information has arrived for this CHAOS App from the phone GUI ")

        def stop(self):
                self.print("Disconnecting any created signals and then stopping '" + self.appName + "'")

As we can see here, the self.print("...") command is useful for debugging and understanding what an app is doing in the background. The user will not see this output; the user will only see what is displayed on the phone app.

Wrap Up

This tutorial has covered how to create and run a CHAOS app. We also learned how to produce text outputs in the debug console. The next tutorial will introduce the detection of sensor events from the home environment.

Next>