Demo SensorCore SDK from your Windows Phone using SignalR with Azure Websites

Demo SensorCore SDK from your Windows Phone using SignalR with Azure Websites

Last weekend I gave a session at KulenDayz about SensorCore SDK. While trying to prepare a good demo, I realized I had 3 possibilities - fake data by shaking my phone (not a good demo), prerecord data and use a simulator (boring demo) or display data in real time as I walk and run around the room. The choice was obvious - wear my running shoes and do a real-time demo!

The first step was to decide what to do on the server side to make it possible. I knew I had to make it fast, as close to real-time as possible. I thought that it would be possible to accomplish that by making a bunch of REST calls on events when certain values in app changed, with some polling to keep showing the values. I would be posting small chunks of data anyway. But then I remembered that I've read about SignalR library, a cool library which makes it really easy to push content to clients in real-time. Did I need to push to a bunch of clients at the same time? No, essentially just up to 5. But I figured this was an opportunity for me to learn something new.

The next question was - where do I host this? Well, that was easy. Azure offers up to 10 free websites, and a free website was all I needed for this. Visual Studio 2013 has a great Azure integration, so all I needed to do was create a new ASP.NET project (empty website) and choose to host on Azure. I could do everything from Visual Studio from there on. If you need more info about using SignalR with Azure WebSites, read this great tutorial.

Server side

Since I won't be going into too many SignalR details, you might be interested into reading more about it before going further with this article. If that's the case, you can read more about setting up your first SignalR app in this step-by-step tutorial.

After creating a new (empty website) project, the first step was to install Microsoft.AspNet.SignalR NuGet package. After that I added a couple of new files and classes. The first one was OWIN startup class, simply called Startup.cs.

public class Startup  
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
    }
}

Next step was creating a hub class with a method which will be called by the Windows Phone client. I will be sending just the number of (walking) steps and current activity, but it can be extended to more detailed log of activities. The sky is the limit.

public class SensorCoreHub : Hub  
{
    public void Send(string steps, string activity)
    {
        Clients.All.broadcastMessage(steps, activity);
    }
}

And of course, I needed a startup html page, so I added a file called index.html. The complete code for this html file can be found here:

https://gist.github.com/igrali/8becc0ede6818a1336f5

Basically, the hub executes the JavaScript function which takes steps and activity as parameters, and updates the text of elements with ids stepcount and activity.

I just hit Publish and it was done!

Simple UI of my ASP.NET Azure web service using SignalR

Client side

I did a simple client side demo app for SensorCore SDK using just the StepCounter and ActivityMonitor. I won't go into too much details about SensorCore SDK because it's been so well covered by the guys at Nokia/Microsoft in the official documentation and the sample apps. Anything more than that would be duplicating really well written content.

Other than the SensorCore SDK NuGet package, I also had to use the SignalR library for Windows Phone. To initialize it, I just connected to the endpoint where I hosted the website.

HubConnection connection = new HubConnection("http://*************.azurewebsites.net");  
IHubProxy hubProxy = connection.CreateHubProxy("SensorCoreHub");  
await connection.Start();  

When the physical activity changes, the event gets raised and then I do two things - change the information displayed in the app and send the latest data using the hubProxy.

private async void activityMonitor_ReadingChanged(IActivityMonitor source, ActivityMonitorReading value)  
{
    currentActivity = value.Mode.ToString();
    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            ActivityText.Text = currentActivity;
        }
    );

    try
    { 
        await hubProxy.Invoke("Send", steps.ToString(), currentActivity);
    }
    catch (InvalidOperationException exception)
    {
        // it happens.
    }
}

I poll the walking steps count all the time, sending only the difference between the current step count and the step count at the moment when app was launched (this is because the SensorCore StepCounter only gives you info about absolute steps - since the beginning of time, or at least the last time you cleared your data or updated your phone which has the hardware support for SensorCore SDK with Lumia Cyan :) )

I poll the steps all the time on a separate thread.

Task.Factory.StartNew(async () =>  
    {
        while (true)
        {
            await CallSensorcoreApiAsync(async () =>
                {
                    var currentReading = await stepCounter.GetCurrentReadingAsync();

                    steps = currentReading.WalkingStepCount - initialSteps;

                    try
                    {
                        await hubProxy.Invoke("Send", steps.ToString(), currentActivity);
                    }
                    catch (InvalidOperationException exception)
                    {
                        // it happens.
                    }

                    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            StepCountText.Text = steps.ToString();
                        }
                    );
                }
            );

            await Task.Delay(500);
        }
    }
);

Result

You know how demos sometimes fail and then there's a weird exception or something simply doesn't work as expected and you have no idea why because it worked so well at home? Well guess what - this demo worked perfectly for me during the session. :) The steps were pretty accurately measured, the change in activity reflected almost in real-time (there's a certain lag in SensorCore to prevent false detections).

I didn't wear my running shoes, but it was fun. :)

So, if you're looking to do something interesting for your SensorCore demo - I suggest trying this.

I'll be posting the whole code on GitHub and then update the article accordingly.

Igor Ralic

igor ralic

View Comments
Microsoft Certified Solutions Developer: Windows Store Apps in C#