How To: Create a Scout

In HomeOS, scouts discover devices on the network during the installation phase, and then facilitate selecting the appropriate driver to use. When adding devices, the flow is conducted as follows:

  1. The scout discovers the devices in its environment.
  2. The scout makes the platform aware of the devices.
  3. The user can query the platform for discovered devices that are not already part of the system.
  4. The user selects a device to add.
  5. The device setup is accomplished via one or more HTML pages.

    a. The initial pages enable device configuration that is specific to the device type.
    b. The final page is the general HomeOS device addition page, where the device's location and associated apps can be configured.

The driver for the device is started as part of loading the final HTML configuration page. The scout is responsible to:
1. Discover devices and report to the platform when queried.
2. Host the UI (HTML pages backed by WCF services) for custom device configuration.
3. Hand over control to the platform by pointing to the generic device addition page.

This tutorial will show you how to create your own HomeOS Scout by using the "dummy" example scout as a starting point.

Note: If you have not already done so, you'll need to get the source code and configure your development environment prior to beginning this tutorial.

How a scout works

The core requirements for a scout are fairly minimal. Scouts should inherit the IScout interface

public interface IScout

{

    void Init(string baseUrl, string baseDir, ScoutViewOfPlatform platform, VLogger logger);

    List<HomeOS.Hub.Common.Device> GetDevices();

    void Dispose();

}

All three functions are invoked by the platform. Init() is called when starting the scout. GetDevices() is called to query for devices in the environment. Dispose() is called when the platform wants to terminate the scout (e.g., when the platform is shutting down).

The call to Init() should return quickly. If a scout will take a long time to initialize, the work should be done on a separate thread called SafeThread.

The platform will call GetDevices() to query the scout for discovered devices. This call should return all devices that the scout finds. The scout does not need to worry about whether the device is already configured or not, as the platform will make that determination and act accordingly. However to help make that determination, the scout should assign a unique ID to each device.

Note: Device ID names should be deterministic, that is, the same ID should be consistently assigned to the device across different invocations of the scout and platform. For example, you could incorporate the device's MAC address into the ID.

The GetDevices() call should also return quickly, as the user may be waiting for its results. If triggering discovery for the devices is time consuming, we recommend having scout discover devices in the background and keep a list of recently discovered devices. This list can then be cloned and returned to platform when GetDevices() is called. The Foscam scout uses this approach. If triggering the discovery is quick, then for simplicity the scout may do that in response to the GetDevices() call. The webcam scout takes this approach. The result of GetDevices() is a list of objects of type Device (defined in Common\Common\Device.cs). 

Create a New Project for your Scout

  1. Open core.sln in Visual Studio.
  2. Right click the Scout folder and select Add, New Project.
  3. In the left pane select Visual C#, then choose Class Library from the list.
  4. Under Location click Browse.
  5. Click the Scouts folder, then click Select Folder.
  6. Name the new project Dummy2 and click OK.

Set Project Options

In this step we will set a command line argument that tells the platform which configuration file we want to use (in this case DummyConfig).

  1. In Solution Explorer, right-click the Platform project and select Properties.
  2. Click the Debug tab.
  3. Under Start Options, Command line arguments, enter the following:
-c ..\..\Configs\DummyConfig -l stdout -p false

Use Dummy Scout as a Starting Point

  1. Copy the contents of Scout\Dummy\DummyScout.cs and paste it into Class1.cs in the Dummy2 project.
  2. In Solution Explorer right-click Class1.cs and rename it to Dummy2Scout.cs.
  3. In Solution Explorer copy DummyScoutSvc.cs and Index.html and paste them into the Dummy2 project.
  4. Rename DummyScoutSvc.cs to Dummy2ScoutSvc.cs. Do not rename Index.html.
  5. Open Dummy2Scout.cs and change the namespace to HomeOS.Hub.Scouts.Dummy2.
  6. Open Dummy2ScoutSvc.cs and change the namespace to HomeOS.Hub.Scouts.Dummy2.

Add references

  1. In Solution Explorer right-click the Dummy2 project and select Add Reference....
  2. In Reference Manager, click Browse. The assemblies can be found in \Hub\output\binaries\Platform.
  3. Select the following assemblies:

    • HomeOS.Hub.Common.dll
    • HomeOS.Hub.Platform.DeviceScout.dll
    • HomeOS.Hub.Platform.Views.dll
  4. Click Add, then click OK to add the references.
  5. In Solution Explorer right-click the Dummy2 project and select Add Reference... one more time.
  6. In the left pane click Assemblies, then click Framework and select the following items:

    1. System.ServiceModel
    2. System.ServiceModel.Web
  7. Click OK to add the references.

Refactor Names

  1. Open Dummy2Scout.cs and rename the class DummyScout to Dummy2Scout.
  2. Hover your cursor over the renamed class name, click the icon that appears, and select Rename 'DummyScout' to 'Dummy2Scout'. Visual Studio will then refactor the naming throughout the class.
  3. In Dummy2ScoutSvc.cs, rename the following items:

    • DummyScoutService to Dummy2ScoutService.
    • DummyScout to Dummy2Scout.
    • IDummyScoutContract to IDummy2ScoutContract.
  4. Open Dummy2Scout.cs and refactor the following name: DummyScoutService to Dummy2ScoutService.
  5. In Dummy2Scout.cs, scroll to the GetDevices function and modify the line where device is instantiated. Change the first two parameters to dummy2device, and change the second to last parameter to HomeOS.Hub.Drivers.Dummy2.

Device device = new Device("dummy2device", "dummy2device", "", DateTime.Now, "HomeOS.Hub.Drivers.Dummy2", false);

Update the Project Properties

Here we'll make some settings to ensure that the output of Dummy2 goes to the right place.

  1. In solution explorer, right-click the Dummy2 project and select Properties.
  2. Rename the Assembly name and Default namespace to HomeOS.Hub.Scouts.Dummy2.
  3. Click the Build tab. Under Output change the Output path to ..\..\output\binaries\Scouts\HomeOS.Hub.Scouts.Dummy2\.
  4. Build the project (F6).

The scout is now ready, and you can see the binaries by navigating to the output folder \output\binaries\Scouts\HomeOS.Hub.Scouts.Dummy2\.

Add Scout to the Scouts Database 

We need to add the scout name and short description to the xml file that the platform uses to enumerate scouts. 

1. Open Hub\Platform\HomeStore\ScoutDb.xml and add a line to the bottom with your new scout name.

<Scout Name="HomeOS.Hub.Scouts.Dummy2" DllName="HomeOS.Hub.Scouts.Dummy2.dll" Description="Dummy2 Scout" Rating="5" IconUrl="icon.png" Version="1.0.0.0"/>

Debug DummyScout2

Now we will do a little debugging to see the new scout in action. First we'll need to add an entry for the scout in Scouts.xml. This will expose the scout so that the platform recognizes it. From Solution Explorer, open Platform\Configs\DummyConfig\Scouts.xml, add a new entry for the Dummy2 scout:

<Scout Name="HomeOS.Hub.Scouts.Dummy2" DllName="HomeOS.Hub.Scouts.Dummy2.dll"/>

Alternatively you can also enable the scouts you want to run through the Dashboard.

Go to Add Devices page and click on the Scouts button.

Then, you will see a list of scouts you can select to run:

To test out your scout:

  1. In Solution Explorer, right-click the Platform project and select Rebuild. This will cause the configuration change to be pushed to the correct build output folder.
  2. Open DummyScout2.cs.
  3. Set a breakpoint on the Init() function (around line 22).
  4. From the Debug menu, click Start Debugging (or press F5). A console window will appear, which displays messages from the platform.
  5. On the Visual Studio toolbar, click Continue. This will allow you to make changes in the code while debugging.
  6. Open a browser and go to http://localhost:51430/Guiweb/.
  7. Click Add Devices. You will see dummy2device in the list of devices.
  8. Click the Stop button to stop debugging.

Note: Console commands are defined in Platform\Platform\Platform.cs (look for the Platform console event handling region).

Hosting Device Configuration UI

You can set up a user interface to expose configuration options to users in the dashboard.

The Add Devices page ships by default as part of the dashboard, and is located here: \Hub\Dashboard\DashboardWeb\AddDeviceUnconfiguredDevicesForScout.html.

The JavaScript on this page gets a list of unconfigured devices:

//Expect URL to be called with HomeId and ScoutName parameters, this gets unconfigured devices for that scout

//e.g. http://localhost:51430/GuiWeb/AddDeviceUnconfiguredDevicesForScout.html?HomeId=Brush&ScoutName=HomeOS.Hub.Scouts.WebCam

$(document).ready(

    function () {

        var qs = getQueryStringArray();

        if ((qs.ScoutName != undefined)) { //if ScoutName was passed as a parameter get it

            SCOUTNAME = qs.ScoutName;                

        }

        GetUnconfiguredDevices(SCOUTNAME);

    }

);

 function GetUnconfiguredDevices(sName) {

    var url2 = "";

    var data2 = "";

    if (sName == "") {

        //Get them all

        url2 = "webapp/GetAllUnconfiguredDevices";

    }

    else {

        url2 = "webapp/GetUnconfiguredDevicesForScout";

        data2 = '{"scoutName": "' + sName + '"}';

    }

    new PlatformServiceHelper().MakeServiceCall(url2, data2, GetUnconfiguredDeviceCallback);

}

Now you're ready for the next tutorial: How to: Create a Driver

Last edited Dec 2, 2014 at 2:23 AM by ajbernheimbrush, version 16

Comments

No comments yet.