How to create Scout that discover devices via Wifi?

Jun 11, 2014 at 6:45 PM
I want to create a scout that would communicate with a few Wifi/RESTful API-based environmental sensors such as Wink Spotter. However, most of the scout examples use UPnP as a discovery protocol, I wonder if it's possible to create Scout that would first take the username and the password that's related to the RESTful-based online service, and then get access to the sensor stream.

Could anyone point me to an example of such use-case? Thanks!
Coordinator
Jun 11, 2014 at 7:23 PM

Hi –

A close example of what you need is the Foscam scout/driver combination.

The Foscam scout looks for the camera on the local WiFi network, checks if the default credentials work, and if not, it will display a page for the user to enter the credentials. These credentials are then handed over to the driver (as DriverParams), which uses them to connect to the camera. All interactions with the camera are using REST calls.

In your setting, here is what I think needs to happen:

1. In the GetDevices() call, the Scout should return a virtual device.

2. When the user clicks on the device, the Scout displays an html page to ask for credentials

3. It also points the platform to the driver to use and the parameters to use (credentials)

4. The driver will be started with the supplied parameters, which will also be saved to the config files for the future

5. Your driver should use these credentials to communicate with the REST service

Let me know if something is unclear or if you get stuck.

Cheers.

Jun 11, 2014 at 8:11 PM
Thanks! I would try it out.
Jun 11, 2014 at 11:06 PM
Hello,
I tracked the AxisCam project since it seems to use username and password to establish connection as well. However, I lost track of the function calls flow. I know once clicking on the "Add Devices" button in the front-end, the AddDeviceUnconfiguredDevicesForScout.html will show up, and then if a device is clicked, the AddDeviceFinalDevice.html will show up.

My question is, when will the front-end jump into the AxisCam/index.html? That is, the front-end configuration page for a scout. Thanks in advanced.
Coordinator
Jun 12, 2014 at 12:40 AM

The control jumps into AxisCam/index.html when you click on the device on an axis camera on AddDeviceUnconfiguredDevicesForScout.html.

For simple scouts (e.g., WebCam), their index.html simply redirects you to AddDeviceFinalDevice.html.

More complex scouts should exit their control flow to AddDeviceFinalDevice.html. There is a helper function GoToFinalSetup() in common.js that several of our scouts use.

Happy to answer additional questions.

Cheers.

Coordinator
Jun 12, 2014 at 7:11 AM

As another reference, please see the code at http://research.microsoft.com/~ratul/downloads/Hub.zip

I wrote this today to demonstrate the pipeline I mentioned earlier. It is meant to fetch weather data from OpenWeatherMap APIs. The code is done yet. In particular, the driver is simply a copy of Dummy driver (and does not what it is supposed to); the Scout functionality is there but lightly tested. Eventually, I’ll finish and upload to codeplex, but I am passing along this in-progress sample in case it helps you.

In the zip, you’ll find one project for the Scout and one for the Driver. To run this code:

1. Copy the projects in your Scouts and Drivers directory, and add them to the Scouts and Drivers folders in your solution.

2. Add the scout information to your ScoutDb.xml (under HomeStore)

3. Rebuild the solution

4. Run Platform and go to the Dashboard

5. Under settings -> configure scouts -> check the openweathermap scout

6. Now go to Add Devices, where the weather device should show up

7. Clicking on that device will bring up the scout control flow and eventually start the driver and end up on the AddDeviceFinalDevice.html

This should let you trace how things are engineered.

Cheers.

Coordinator
Jun 12, 2014 at 8:44 AM

Sorry, that download URL does not work. Use this: http://1drv.ms/1hQqkZC

Jun 12, 2014 at 2:43 PM
Thanks Ratulm, the code seems very helpful, I would try it out today.

Another related question is that I want to connect LoT to API services such as Fitbit, which requires OAuth –– I would need to store consumer key and secret at some where. I could put the consumer key and secret at the scout-level, and have the user walk through the Fitbit Authorization at the device setup page. However, using this method, whoever reuse my Fitbit Scout in the future would be able to access my consumer key and secret. Another way to do so is to put the authorization process completely in the Application level, however, in this way, we leave scout with little function. Assume there will be more Web-based sensors with OAuth process such as CubeSensors, Sentri, Fitbit coming up, what's your suggested process of connecting to them?

Thanks.
Jun 12, 2014 at 3:49 PM
I try the OpenWeatherMap code, and is stuck at the scout/device configuration page. It seems that the platform sets the OpenWeatherMap device as configured already, therefore when I pressed "Done" in the scout/device configuration page, the platform could not find the device.

I also check the settings but the there is also no OpenWeatherMap listed. When I go to "Add Devices" again, the OpenWeatherMap is no longer there anymore. Could you explain more about how configuring of devices work? I have no idea why the device is removed from the unconfigured list although the configuration process is not done yet.

Thank you again.
Coordinator
Jun 12, 2014 at 5:21 PM

On being stuck: That is likely happening because of the incompleteness of the driver. I’ll try to work more on the driver today and upload a less incomplete version, but the internal flow of things is as follows:

1. Scouts discover devices and acquire the information necessary for running the driver

2. The scout workflow ends in starting the driver with the right parameters

3. The driver starts and exports a port corresponding to the device

4. Initially, the port is marked unconfigured.

5. After finishing the final configuration (AddDeviceFinalDevice.html), the port is marked configured

On the settings page, you should be able to see both fully configured devices and partially configured devices (for which step 5 has not been completed).

Cheers.

Jun 12, 2014 at 7:40 PM
Found the bug. It's at GetDevices(). The GetDevices() in OwmScout return no device when calling it second time.
Coordinator
Jun 13, 2014 at 8:37 AM

On where to put the OAuth and secrets, I understand that Fitbit access needs an API key (which is application-specific and not user-specific) and an OAuth token (which is user-specific).

Now, unless I am missing something, the following may work:

- You get an API key from Fitbit, and configure the Scout with it, either in code or its app.config file

- As part of device set up, have the user enter their credentials, which will get you the OAuth token you need

- Pass the API key and OAuth token to the driver as parameters, which will be used by the driver to access fitbit data

Applications don’t contain any secrets, and your scout is not programmed with user credentials.

Would this work?

Cheers.

Jun 14, 2014 at 2:15 AM
This is the method I'm using now. It somehow works, I think the problem is just the reusability of a scout. Originally I thought, for example, a Fitbit Scout should be reusable by others, but in this way it cannot.

However, I still face the same problem as your OpenWeatherMap example: Once I setup the credentials and go into the AddDeviceFinalDeviceSetup page, I am not able to complete the driver setup process by clicking "Done". The debug info shows "Problem configuring apps:Service for device not found. Try again."

My guess is that somehow the device is set to configured at this point, so when clicking "Done", the backend would try to find unconfigured ports, which it could not find. However, I am not sure if this is the problem, and need to do more debugging tomorrow. If this is the problem, I also have no idea how to fix it.

Thanks for your patience.
Jun 14, 2014 at 2:23 AM
Some more thoughts about the Scout. I'm just curious how LoT could handle third party sensors using Web-based api. For example, if I am the developer of Basis B1 smartwatch, I probably need to implement a Scout for the LoT platform. However, I would not put any consumer key and secret in the scout, as this should be set by the application. Do you imagine every application developer needs to create their own Scout for the same service, such as Fitbit?

As a application developer that uses Basis B1 smartwatch, I would develop an application that could communicate with the application-backend to fetch the consumer key and secret, and then get access to the Basis B1 API. However, in this way, the Scout loses its function of gatekeeping the input devices.

A user could then go to AppStore and download the app.

*NOTE: Basis B1 does not have a friendly API yet, it's just an example.
Coordinator
Jun 14, 2014 at 8:15 PM

On not being able to complete the setup process, a couple of issues come to mind:

1. Can you verify (e.g., using the debugger) that the Start() function of your driver is being called?

2. When the driver calls the GetPortInfoFromPlatform() is passes in a string that includes the deviceId?

By the way, I didn’t face this issue with my scout and driver. Not sure why you did.

In any case, I’ve put updated code http://1drv.ms/1hQqkZC so you can try it out. If this does not help resolve your issue, I’ll have to take a look at your code as a last resort.

Cheers.

Coordinator
Jun 14, 2014 at 9:22 PM

From: sprite728

Some more thoughts about the Scout. I'm just curious how LoT could handle third party sensors using Web-based api. For example, if I am the developer of Basis B1 smartwatch, I probably need to implement a Scout for the LoT platform. However, I would not put any consumer key and secret in the scout, as this should be set by the application. Do you imagine every application developer needs to create their own Scout for the same service, such as Fitbit?

As a application developer that uses Basis B1 smartwatch, I would develop an application that could communicate with the application-backend to fetch the consumer key and secret, and then get access to the Basis B1 API. However, in this way, the Scout loses its function of gatekeeping the input devices.

A user could then go to AppStore and download the app.

*NOTE: Basis B1 does not have a friendly API yet, it's just an example.

You are raising some good issues regarding Web-based APIs. Here is how we see things:

We consider HomeOS applications to be able to use the functionality of devices/services, while being agnostic to the exact service or device. So, a HomeOS application should be able to use “Role Smartwatch” without worrying whether that role is provided by Basis B1 or Samsung Galaxy watch. This is enabled by HomeOS drivers that know how to communicate to specific devices and services, and normalize their functionality to the relevant role. So, there will one driver for Basis B1 and one for Samsung Galaxy. HomeOS applications would be able to use both devices similarly.

This model is similar to what you see with Windows today. Applications use print functionality without worrying about the type of printer. It is enabled by having print drivers per printer type, and the drivers provide normalized functionality for the apps to use. The print drivers are usually written by printer manufacturers, but can in theory also be written by third-parties that know how to use that printer.

If HomeOS were a full production platform, then the story would be similar. There would be one driver per watch type, written by (or in coordination with) the watch vendor. But since we are a research platform, you and I have to write these drivers.

Now, coming to the role of scouts. The responsibility of the scout is to help properly configure the driver. To access devices/services, the driver needs configuration elements that are both specific to the device/service (e.g., an API key) and to the user (e.g., username/password). During the device setup process, such information is collected by the scout and passed on to the driver. The scout-and-driver combination go hand in hand, typically developed by the same person (or organization), because the scout needs to know what exactly the driver needs to access the device/service.

I think the main disconnect between our perspectives is that we don’t think in terms of “basis b1 application” or “Samsung galaxy” application, but think in terms of “smartwatch application” along with “basis b1” and “Samsung galaxy” drivers. These drivers are the ones that ultimately talk directly the device/service.

If you are writing a “basis b1 driver” for HomeOS, then hopefully others would not have to write one. They can simply write a “smartwatch application” that uses that drivers. Your driver will need some secrets to run, which can be collected during to the device setup process.

Does this make sense?

Cheers.

Jun 15, 2014 at 1:09 AM
Edited Jun 15, 2014 at 1:13 AM
Hi Ratulm,
Thanks for your explanation, it helps me to better understand the architecture, and I did read LoT's papers before.

I understand the HomeOS and periphery design paradigm, I think the problem I have now is that for OAuth 1a, I need to store the consumer key and secret somewhere, and it seems it would be at Scout. (Consumer key and consumer secret is application-dependent.) However, if I store it at the scout-level, although the user credentials (oauth token and oauth token secret) could be stored at the device level, the scout would not be reusable by others directly. They need to reconfigure the consumer key and consumer secret.

Also, I found where my real bug is -- I forgot to set the view "copy local" property to be false.

Thanks.
Coordinator
Jun 15, 2014 at 5:17 AM

I think the problem I have now is that for OAuth 1a, I need to store the consumer key and secret somewhere, and it seems it would be at Scout. (Consumer key and consumer secret is application-dependent.) However, if I store it at the scout-level, although the user credentials (oauth token and oauth token secret) could be stored at the device level, the scout would not be reusable by others directly. They need to reconfigure the consumer key and consumer secret.

I see what you mean. There are two ways to resolve this situation:

1. Think of your HomeOS scout-driver as an application from fitbit’s perspective, irrespective of who is running it. This is akin to me writing a 3rd-party fitbit app, say, for iPhone and putting that app on Apple’s App Store. Now, whoever uses that app will be using my consumer key and secret. (HomeOS application is now a higher-level concept that fitbit will not be aware of.)

2. If you are not comfortable letting others use your consumer key and secret, then letting them configure a new key/secret seems like the way to go. They will at least be able to reuse your code. This reconfiguration can occur in one of three places in preference order: 1) during the device setup; 2) in app.config of your scout, from where it is read by the code; 3) in code (which means recompilation).

Cheers.