Using iBeacons and Eddystone in Xamarin Forms

I’m working on a project where I need to get temperature from a wireless sensor into my phone app.  The exact sensor doesn’t matter – it just needs to be inexpensive.  Decent battery life would also be nice.  And so began yet another typical “searching for a sensor” trip for me.

After a little research, I ordered a SensePeanut.  Looked great.  Decent prototype cost. Available off-the-shelf and in a package.  Just what I need!  Except I got it in hand only to find out that you can get data from it only using their app, which they don’t give out the source for.  Soon they’ll have a “cloud SDK” that will let me get the data, but for a whole host of reasons, that just isn’t an option.

So I did a bit more research.  I needed a sensor that provided a “direct to the sensor” SDK.  I ended up ordering some proximity beacons from Estimote.  Proximity isn’t what I’m after, but they also can transmit temperature so it seemed promising.

Well last weekend I finally got time to start writing code.  Turns out that the SDKs they provide are, at least as far as I can tell, native binary SDKs for iOS and Android.  I’m a C# dev this week and I really want this to be cross platform, but they don’t have a Xamarin SDK.  Someone at Xamarin did create an SDK for the devices a few years back, but that project doesn’t actually work with the latest Android SDK – discovery returns nothing.  Evidently that’s not uncommon when using a library built against an older Android SDK.

Well it’s turns out that the existing Xamarin library is really just a bindings library that wraps the Java SDK.  So let me get the latest Estimote SDK and recompile.  Well, evidently the Estimote SDK is now deployed through JCenter (think NuGet for Java).  That appears to require that I install Java tools and I really have no desire to pollute my working machine with a toolchain I don’t intend to use.  No idea what can of worms that might open.

They don’t appear to have an AAR download, nor do they have the source for the SDK available – only source for some sample apps.

A little reverse-engineering with JCenter, however, let me to find the URL to direct-download the AAR.  I pulled it down and created a Xamarin Bindings Library project targeting it.  This is my first attempt at a Binding Library, but how hard could it be, right?  Turns out that the project generates a load of error, and this is not at all uncommon for a Bindings Library. Auto-generating wrapper code is hard, I realize that.  But I really don’t have the desire, or especially the time at this point, to climb the learning curve for Bindings Libraries, especially since I just want to read a simple temperature.

Maybe the existing Xamarin project can be used against the new Estimote AAR?  Surely the original dev had to solve these errors, right?  I loaded up the existing project and stuffed in the newer AAR.  Build and…still a bunch of errors.  Admittedly only about half the errors than the new project had, so it’s progress, but still isn’t getting me data.

I then spent a few hours reading and working on the project.  It’s a steep learning curve with not a whole lot of “Bindings-Libraries-for-Dummies” tutorials out there.  I got rid of maybe half the errors (the easy ones) and then got stuck.

Time to pivot again.  There’s got to be a way to do this.  Back to researching.  I found a Windows 10 C# library that can read data from iBeacons and Eddystone.  The Estimote can be configured to transmit the temperature in an Eddystone telemetry packet so that seems at least somewhat promising.  At least I have full source for the library.

I ran the sample app on my laptop and, lo-and-behold, I see temperature data which is hugely promising. Again, it’s a Windows 10 library but I’ve been making a career out of making desktop code mobile for a long time so it’s certainly in my wheelhouse.

First task was to port the library to .NET Standard so I’d have some expectation I’d be able to use it over on Android and iOS.  That required extracting the actual Bluetooth packet discovery out to an interface that was platform-specific.  The starting code was pretty well thought out and constructed so the task was not too hard and I actually had a UWP app receiving and displaying the data in just a couple hours.

The next job was to create the Android implementation of the Bluetooth discovery bits.  The UWP platform provided the Bluetooth data in a really nice format.  I’m sure it looks that way since the starting code I was working with was built specifically for it.  Fitting the reality of the packets that we get in Android into that structure wasn’t straightforward, but since Bluetooth and Eddystone are well documented it also wasn’t overly difficult.  It took me about a day of working with it to understand the spec well enough to get the incoming packets integrated into library.

I got a hold of Andreas Jakl, the original library author, let him know about my fork, and requested collaborator status.  He was gracious and added me to the project so my changes have all be back-integrated into the original tree, as well as fixes to the original sample non-Xamarin UWP app to use the new libraries.  We’re in teh process of getting the new stuff out as NuGet packages.

Getting BLE temperature data into my app certainly wasn’t as straightforward as I had hoped when I first ordered a sensor.  In fact, the journey to get there was nothing like what I’d hoped, or even expected once I started trying to write code for it.  In the end, however, I got it working (well in UWP and Android anyway, iOS will have to wait until I start porting the app that started this whole thing) and the work is public and open source.  I still have to manage the beacons with vendor-specific apps, which still irritates me, but at least we all now have a generic way to receive data from BLE beacons in our .NET apps.

 

Sensors as a Service are a Disservice

Building up an IoT solution, at least in just about any work that I do, tends to require data from sensors.  Preferably cheap sensors.  And in many cases wireless sensors.  This has been problematic for years.  It used to be that the sensors were expensive, or the wireless was terribly unreliable but as Moore’s Law has marched forward, you can now get some reliable, inexpensive sensors with good battery life.  Unfortunately sensor vendors seem to be opting for a new type of friction – instead of making money on selling us sensors, they’ve decided that making money off of the data from the sensor is the route they should go.

It’s common to hear from the vendors that integration into your solution is simple.  After all, they provide SDKs that allow you to access your data.  Except the SDK is a REST API to their cloud.  A fair number of installations I work on don’t have internet connectivity available.  What then?  Or the connectivity is through a cellular connection, so I have to pay to send the data up to the cloud, then pay to bring it back to a gateway sitting two feet from the device?

Even when I have internet access, having the sensor data in some separate cloud just adds unnecessary complexity.  Let’s say I am working on a solution where I want to store a location and a temperature periodically.  The “sensor as a service” architecture means that I send the location data to my server, the temperature data to the sensor vendors server, then when I want to display that data in a temporally consistent manner, I have to pull from both sources (assuming both are up) and then merge the results based on timestamps (and hoping that the timestamps are identical of course)?

It amazes me that vendors think this is an elegant, or even viable solution.  Sure, I can come up with uses cases where having my sensor data in someone else’s cloud makes sense.  But for every one of those, I can think of at least ten scenarios where I just want to be able to connect right to the sensor from a gateway, very often in close proximity to the sensor, and pull the data into my own app.  From there I can do analytics, aggregation or whatever I need.

Sensors as a service are not what we need.  Proprietary APIs or vendor-only, closed source consumer mobile apps are near useless.  What we, as innovators and as a development community are simple, low-cost sensors with open (preferable standards-based) SDKs that allow our apps to directly connect to, configure and get data from sensors.  Where appropriate, I’d also like clear documentation of any packet data that gets sent to and from the sensor.  If the vendor provides an app for communicating with the sensors, I want to source for that app because it’s highly likely it does things I’m going to want to do.  Essentially, I want to take the sensor out of the box and then spend a minimal amount of time writing code to get to something that proves that it’s going to work for me.  If I can’t at least read sensor data into a console or test app in under two hours then the sensor vendor has failed.

Refresh of MTConnect Client SDK

Last week I had a call with a couple guys looking to implement an MTConnect Client into their system.  I decided to take that as an opportunity to revisit some MTConnect SDK code I wrote a few years back and apply at least a little modernity to the code base.

So what I did was:

The source code on Github contains a sample Client application that lets you quickly view, graph and store MTConnect data.  This is what it looks like when graphing X and Y axis positions from the public, sample MTConnect Agent.

mtconnect_client

Unit Testing REST Clients

I frequently seem to end up writing code that calls REST services – on pretty much every project I work on anymore.  Since I seem to be often writing the same code over and over, I’m working on a library (well a couple libraries) to simplify things and consolidate all that I typically come across.

A challenge in writing a REST client is how to easily unit test it.  I don’t want to have to stand up a server somewhere just to run simple tests, especially if the server needs to return valid and invalid data that needs to change with the test.

So I create a really simple, yet really useful class I’m calling SimpleServer and it’s available as a gist.  It basically allows you to define a URI and then set callback methods for the common HTTP verbs (GET, PUT, POST and DELETE).

Let’s say you want to test out a GET operation.  In the example below the RestConnector encapsulates the goo required to make the HTTP call, but the cool part is how it uses the SimpleServer to test an expected response to a GET at the API root.

        [TestMethod]
        public void GetNoCreds()
        {
            var uri = "http://localhost:8080/";
            var response = "Hello!";

            using (var svr = new SimpleServer(uri, (request) =>
            {
                return response;
            })
            )
            {
                svr.Start();

                using (var rc = new RestConnector(uri))
                {
                    Assert.IsNotNull(rc);
                    var result = rc.GetString("/");

                    Assert.AreEqual(response, result);
                }
            }
        }

Here I’m using the default handler parameter for a GET, but you can individually pass in Func’s for GET, PUT, POST and DELETE which makes testing even fairly complex scenarios both quick and really, really easy.

New MQTT library

I don’t know if the development world needs another .NET MQTT library, but I wrote one a few years ago and finally decided to dust it off and publish it in source form and as a NuGet package.  I considered doing a PCL version, but then I looked at the source and was reminded that the library heavily uses sockets and threads and figured that’s a bit more work than I feel like putting into it right now.

It’s fully functional and pretty solid. I used it in a production app, so it’s not just an experimental library.

Source code is on GitHub.

Package is in NuGet [id: opennetcf-mqtt]

NuGet Updates across the board

As I mentioned a couple weeks ago, I was in the process of unraveling a load of projects that were tied together, trying to get them all into separate code repositories.  I finally got that done and got them all published to NuGet (well not the CF versions of those that support the CF – patience).

And so you now have available:

 

New Open Source Projects

I’m working on a new application that’s going to be open source.  Once it’s a bit further along I’ll provide more details, but essentially it’s a paperless forms solution that encompasses a WPF desktop app, a self-hosted ASP.NET WebAPI service and a Xamarin Forms mobile app all working together.

In the process of getting the foundation up and running, I’m moving a lot of stuff over to Github, but more importantly I’m updating, extending, and creating whole new libraries that can be used for other stuff.  These, too, are open source.

What’s being updated?

  • OpenNETCF.ORM
    I’m primamrily working with SQLite, but I’ve already uncovered and fixed some issues around one-to-many entity relationships
  • OpenNETCF.IoC
    Work and updates to make it more Xamarin/PCL friendly
  • OpenNETCF Extensions
    This thing has been stable and in heavy production use for years.  Support continues for it with some minor changes and improvements in the Validation namespace so far.

What’s New?

  • OpenNETCF.Xamarin.Forms
    Adding things that I’m finding missing or hard in Xamarin’s BCL.  Things like “hey, scale this label to the right size depending on my screen resolution, on any platform”.  Thanks go out to Peter Foot for pointing me in the right direction there.
  • OpenNETCF.MVVM
    No idea why Xamarin didn’t provide a basic navigation framework.  I created one.  Is it awesome?  I don’t know – but it works for my use case (plus 3 other apps I’ve done with it).
  • OpenNETCF.Google.Analytics (moving to it’s own repo soon)
    Again, seems like low-hanging fruit here.  Why isn’t it in the box?  I don’t know, but there’s now a simple, open source library for it.

One note – these are all in active development, so don’t expect a NuGet package updates on them for at least a little while (end of May?).  I’d like to get features in and stable before rolling them out.

Feedback welcome. Testers wanted.  Enjoy.