UI Simple

From MiOS
(Difference between revisions)
Jump to: navigation, search
Line 148: Line 148:
 
''Living Room'', ''Bedroom'', etc.  Next is a list of all the rooms, broken down by section.  Choosing a room lists the scenes in that room, followed by the devices.
 
''Living Room'', ''Bedroom'', etc.  Next is a list of all the rooms, broken down by section.  Choosing a room lists the scenes in that room, followed by the devices.
  
Therefore if a device is assigned to a room, it will appear in 2 places, in both the room and in the device's category.  The same is true for scenes.
+
Therefore if a device is assigned to a room, it will appear in 2 places, in both the room and in the device's category.  The same is true for scenes. Here is a typical top-level menu:
  
 
[[Image:uispec_mainmenu.png]]
 
[[Image:uispec_mainmenu.png]]

Revision as of 00:27, 23 August 2010

MIOS is a lightweight home automation system. The 'brain' of the MIOS software is the back-end, the engine, which runs stand-alone on a variety of internet-connected devices, such as PC's, Mac's, Wi-Fi access points, and dedicated home automation gateways. MIOS also includes a portal at mios.com, which acts as secure relay to MIOS systems that may be behind firewalls. Users can register for an account at mios.com, and that account can be linked to one or more MIOS systems to provide the user remote access to his MIOS system from anywhere. It is easy to control a MIOS system with simple http get's (normal internet requests). The URL you will open is generally data_request?id=xxx, where xxx is some sort of request or control command.

This document describes how to create a simple user interface to control a MIOS system using the simplified lu_sdata (LuaUPnP Simple Data) request. This document describes a simple control-only user interface, meaning it let's the user run scenes and control devices, but does not provide any means to change configuration or do advanced tasks. Whatever device is running the user interface (cell phone, web page, television, etc.) will be referred to as the "controller", and the MIOS engine, or system, that is being controlled by the controller is the "engine".

You can test out all the commands a normal web browser. For example, if your engine is on the same local network as your web browser, and your engine has the IP address: 192.168.2.150, you can view the status of all scenes and devices by opening this link in your browser: http://192.168.2.150:3480/data_request?id=lu_sdata and if you want to turn on device #5 you open this link in your browser: http://192.168.2.150:3480/data_request?id=lu_action&DeviceNum=5&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1

The user interface has only two screens, or modes: 1) Basic setup which only consists of identifying the engine the user will control, and 2) Normal usage which consists of running scenes (pre-defined groups of commands), and controlling devices.

Mode 1: Basic setup and locating the engine

The first thing the user interface should do is find the engine on the internet. There are 2 different ways to control an engine:

1) Directly, using an IP address, where the engine is either on the same local area network as the controller or has a static IP or port forward that's publicly accessible from the internet, such as in the example links above.

2) Through one of the MIOS secure forward servers, which acts as a relay to an engine that may be behind a firewall. The URL is identical except that instead of using the IP you use a mios forward server followed by the /username/password/serial_number, where the username/password are from the user's mios.com account that he linked to his engine, and serial_number is the unique id of the engine. So, assuming you want to turn on device #5 on engine #10266 and the user linked it his mios account with the username "john" and password "tokyo", you would open this URL (note it's identical to the URL above): https://fwd2.mios.com/john/tokyo/10266/data_request?id=lu_action&DeviceNum=5&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1

NOTE: Because method #2 is much slower than method #1 when both the engine and the controller are on the same network, it is generally preferred to use method #1 when the controller is in the home, and method #2 when the controller is away from the home and needs to talk to the engine through the homeowner's firewall. If you are putting your UI in something that is only on a local network, like a TV, and you do not want to give the user the ability to control an engine outside the home, you may only implement method #1. If the UI is running on something that a mobile phone that has NO wi-fi and can only connect through the mobile network, then you may want to implement method #2 only. Normally, though, a user interface should be able to use both method #1 and method #2, and this is how we spec it for our UI's.

When the controller first starts, display this:

Enter your mios.com username: [__input_box__] [go]
__I don't have a mios.com account or I want to specify the IP address.__

Where [go] is a button, [__input_box__] is for the user to type in the username, and the __I don't have... is a link, or button, or similar. If the user clicks the 'I don't have' link, display this:

Enter the IP: [__input_box__]  [go]

When the user clicks 'go' attempt to the open this url: http://ip:3480/data_request?id=lu_alive (substitute the actual IP), and if you get back an "OK" in the response, store the IP address in your controller locally (ie a conf file, registry, etc) and continue to the next step. If you don't get an OK, display an error and go back.

If the user supplied a mios.com username, open this URL: http://sta1.mios.com/locator_json.php?username=user (substitute 'user' for the actual username). This will return a list of all the engines you can control, both with method #1 and with method #2, meaning you will see both engines on the local network which may or may not be tied to the user's mios.com account, and you will see engines tied to the mios.com account which may or may not be on the local network. As with most of the requests, the returned data is in JSON format. The data you get back is not formatted with new lines and spaces. If you want to be more human readable for debugging, copy/paste the results into http://jsonlint.com and it will format it nicely. The controller needs to have a json library so it can parse the json responses. The data you get back will be like this:

   "units": [
       {
           "serialNumber": "10266",
           "FirmwareVersion": "1.1.1052",
           "ipAddress": "192.168.2.117",
           "name": "skyvera",
           "users": [
               "skyvera",
               "aaronb"
           ],
           "active_server": "fwd2.mios.com",
           "forwardServers": [
               {
                   "hostName": "fwd2.mios.com",
                   "primary": true
               },
               {
                   "hostName": "fwd1.mios.com",
                   "primary": false
               }
           ]
       },
       {
           "serialNumber": "8035",
           "FirmwareVersion": "1.1.1047",
           "ipAddress": "192.168.2.116",
           "users": [
               "ovidiu",
               "alfonsomios",
               "aaronb",
               "mrhtn"
           ],
           "active_server": "fwd1.mios.com",
           "forwardServers": [
               {
                   "hostName": "fwd1.mios.com",
                   "primary": true
               },
               {
                   "hostName": "fwd2.mios.com",
                   "primary": false
               }
           ]
       },
       {
           "serialNumber": "10516",
           "FirmwareVersion": "1.1.1047",
           "ipAddress": "192.168.2.23",
           "users": [
               
           ],
           "active_server": "fwd2.mios.com",
           "forwardServers": [
               {
                   "hostName": "fwd2.mios.com",
                   "primary": true
               },
               {
                   "hostName": "fwd1.mios.com",
                   "primary": false
               }
           ]
       }
   ]

units is an array of JSON objects, one representing each engine. If the tag ipAddress exists for an engine, that means it's available on the local network and can be controlled locally with method #1, otherwise the ipAddress tag will not exist. The users array is a list of all the mios.com usernames which have access to this engine. So, if the username you passed on the locator_json.php URL is also in the users array, then the engine can be controlled remotely with the username, using whatever server is listed in the "active_server" tag. The forwardServers tag lists the primary server for remote access and one or more backups. If the tag "name" exists, that is a name which the user assigned to his engine.

The next screen in the UI should say "What MiOS engine do you want to control?" and then display a list of all the engines with both the serialNumber and name if it exists. You should have 2 icons next to each for 'remote' and 'local' access. In the above example, assuming the username I passed in is "skyvera" 10516 will have the 'local' icon only, since there are no users, and for 8035 it will also be 'local' only because skyvera is not one of the allowed users. For 10266 display both the 'remote' and 'local' icon. At the bottom of the page you can have a legend:

[R icon] - You can access this MiOS engine from anywhere in the world over the internet using your mios.com account

[L icon] - You can access this MiOS engine locally on your home network without going through your mios.com account

Let the user pick the engine he wants to control and store in the controller's local storage the username supplied by the user, and from the JSON file for whatever engine the user picked store the contents of serialNumber, ipAddress, active_server, and store the list of servers in forwardServers.

At this point display:

 mios.com password: [__input_box__]
 [ ] Store my password so I don't have to enter it each time
 [go]

If the user checks the box, store the password. When the user clicks go, if you stored an ipaddress, test it with:

http://ip:3480/data_request?id=lu_alive

and confirm you get an OK. Then test the password with:

https://xxx.mios.com/username/password/serial/data_request?id=lu_alive and substitute xxx.mios.com for the active_server, and substitute the actual username/password/serial. Again, confirm you get back an OK.

If you do not get an OK for both (or the 2nd one if there was no local ip address), display an error and go back:

Unable to connect.  Please check your password.  [ok]

Mode 2: Normal operation

Now that you have stored the connection information (ip address, etc.), you can start the main application. From now on, whenever the user starts the UI, it should go straight into the main application and not ask him for the connection information again, although within the normal operation the user has the option of returning to setup.

The use can choose to control devices and scenes. A device is a light switch, a thermostat, a door lock, etc. Some devices may not have any control options, meaning the user cannot do anything with them, and they are only there to show status, such as a motion sensor or a temperature sensor. Scenes simply groups of actions the user has pre-defined, such as "Go to bed", which may be a scene that turns off all the lights.

The user is able to create rooms and sections to organize the devices and scenes. Devices and scenes can be assigned to a room, and each room can be assigned to a section. Only very large home with many rooms divide the rooms into multiple sections, such as "West Wing", "3rd floor", etc. By default there is only 1 section and all the rooms belong to it.

Devices and rooms may or may not be assigned to a room. Small installations with only a handful of devices typically do not create rooms, and all the devices and sections are left unassigned. When the user does create rooms, he does not need to assign all devices and sections to a room, so some may remain as unassigned.

Each device has a category, such as 'dimmable light', 'thermostat', 'door lock', and so on.

So, a typical top-level menu may have the following options:

Setup to return to Mode 1 and choose a new engine to connect to. If the user interface has a menu or option button the Setup can be there so it does not occupy space on the main menu.

Scenes This lists all the scenes. First list the scenes not assigned to a room, then list the scenes grouped by the room they are assigned to.

Lights, Thermostats, etc. Next the controller lists the categories so the user can just straight to 'thermostats' and see what thermostats, lights, etc. are in the house. The lu_sdata request will provide you with a list of the categories that are actually used in the system.

Devices This lists all the devices that are not assigned to a room

Living Room, Bedroom, etc. Next is a list of all the rooms, broken down by section. Choosing a room lists the scenes in that room, followed by the devices.

Therefore if a device is assigned to a room, it will appear in 2 places, in both the room and in the device's category. The same is true for scenes. Here is a typical top-level menu:

Uispec mainmenu.png



Typically the software for the is written with 2 separate threads: 1. a background poll loop that continuously polls the engine for changes and which updates an object-oriented class structure.

The background poll loop

You should have a global variable in your app with the engine state.


You should have a global variable in your app with the engine state.

Personal tools