Poi Labs was looking for a back-end system for its Bluetooth beacon-based mobile solution. It wanted one that did not require a lot of time spent on system maintenance. It also wanted to be able to scale this back end automatically for any workload. Microsoft worked with Poi Labs to address these needs, focusing on platform as a service (PaaS) in Microsoft Azure and placing Azure App Service at the center of the solution.

The project team decided to use Azure App Service and the API Apps feature of App Service to take calls from mobile apps. Azure Service Bus/Event Hubs would receive processed messages and Azure Functions would do the processing of those messages coming from it. Azure Cosmos DB would be the main database for storing the JSON data/documents.

To speed up database lookup operations, we plugged Azure Redis Cache between the Azure App Service/API Apps and Azure Cosmos DB. We decided to use Azure Table storage as our custom logging storage. In the end, we used the Web Apps feature of Azure App Service to host an administration user interface that would host Power BI Embedded reports for admin users so clients could view their reports. This report offers details on this solution.

Technologies used:

Core team

  • Faruk Celik – Senior Technical Evangelist, Microsoft
  • Gokhan Mericliler – CEO, Poi Labs
  • Mustafa Sapcilar – CTO, Poi Labs
  • Ergin Aktas – Senior Software Developer, Poi Labs
  • Fedai Kaya – Software Developer, Poi Labs
  • Osman Tasci – Data Analyst, Poi Labs

Customer profile

Poi Labs is a technology company based in Istanbul, Turkey, that creates connections between the physical and digital world.

Poi Labs started its journey by developing indoor navigation technology for the visually impaired. Turkey has more than 500,000 visually impaired people who face social isolation problems because of difficulties in finding their way around on their own. With this in mind, Poi Labs developed a beacon and Wi-Fi sensors that communicate with mobile devices through Bluetooth and Wi-Fi signals, enabling indoor navigation even in areas where GPS doesn’t work. Using this technology, Poi Labs made an area of 1 million square meters and 17 shopping malls accessible. This indoor navigation technology led to Poi Labs becoming Turkey’s first and only member of the Wayfindr Community.

Poi Labs’ beacon network, named Poi Network, is now available in more than 50 cities and at almost 15,000 points of interest within Turkey and growing. The Poi Network allows retailers to provide an enhanced customer experience. The signals generated from Wi-Fi and beacon devices are gathered at Poi platforms and transformed into meaningful insights. The shopping app Hopi works with Poi Labs in order to analyze customer preferences and choices. Consequently, it knows the customers and provides location-based promotions. Poi Labs represented Turkey as a finalist at the World Retail Awards 2015.

Problem statement

Poi Labs had developed its back end using web services technology on its IIS servers hosted in its on-premises environment. Mobile apps were reaching this back end with no performance issues. The Poi Network reached across the country with around 15,000 beacons; 5,000 of those were placed in the member stores of Hopi, one of Poi Labs’ biggest clients.

Hopi was bringing 4 million (and growing) mobile application users to this back-end system and the team had concerns about whether it could handle this much workload. In addition, Poi Labs wanted the ability to create a system that can handle new clients with the power of Microsoft Azure.

Beacon placements in stores

POI Labs Beacon placed in a store - 1 POI Labs Beacon placed in a store - 2 POI Labs Beacon placed in a store - 3 POI Labs Beacon placed in a store - 4

Proposed solution

Microsoft planned a five-day engagement with Poi Labs. The plan called for:

  • Envisioning
  • Architecture work
  • Hacking (three days)

The team at work on the Poi Labs Azure architecture

POI Labs - Team is working on architecture

Architecture diagram

App Service Architecture Diagram

The Poi Labs team already had started to develop a Node.js version of their back end using Azure Cosmos DB as a back-end database. We moved this back-end API to App Service/API Apps and configured the autoscaling settings for the app by making load tests.

Poi Labs’ beacons in the field were sending their “advertisement” messages after encoding the message inside the beacon hardware.

Inside a Poi Labs beacon

Inside POI Labs Beacon - 1 Inside POI Labs Beacon - 2


Poi Labs had made this UUID hardware-encoding design as a business decision to prevent third parties from using the beacon network. The first thing in the code was to “decode” this encrypted message in their API code. The encoded message was just an encoded UUID. Typically, the app would need to make a lookup in a datastore to make this UUID meaningful. The following code example shows a signal message coming from a mobile app to the back end. (Necessary values are obfuscated for security reasons.)

{
	"clientData": {
		"secret": "29CC8EED-56D2-44FA-A2DF-20F9ED05120E",
		"device": "HTC One_M2",
		"vendorId": "",
		"osVersion": "26",
		"beaconMode": "standart",
		"sdkVersion": "9.2",
		"clientRequestTime": 9425962202,
		"platform": "Android",
		"lat": 64.0662545,
		"lon": 64.6690699,
		"uniqueId": "6529966",
		"clientIp": "5.9.26.96, 962.952.90.922:96904"
	},
	"beaconSignal": {
		"timestamp": 9425962206,
		"range": "FAR",
		"rssi": -69,
		"serviceUUID": "2AA90000-0A46-995F-D94E-5A466C6EEBB4",
		"majorId": 29,
		"minorId": 49252,
		"pois": ["c69e9a6b-9ada-46ca-a069-69249642ce6a"]
	},
	"createdAt": 9425962206,
	"id": "5969fd5e-696d-4999-a494-c26f2226c292",
	"_rid": "JJd6AL+lAwRSGWEAAAAAAA==",
	"_self": "dbs/JJd6AA==/colls/JJd6AL+lAwQ=/docs/JJd6AL+lAwRSGWEAAAAAAA==/",
	"_etag": "\"9f005a22-0000-0000-0000-52999e9a0000\"",
	"_attachments": "attachments/",
	"_ts": 9425962945
}, {
	"clientData": {
		"secret": "29DD4FED-56D2-44RA-B2CF-21F8EDE5F20E",
		"device": "HTC One_M2",
		"vendorId": "",
		"osVersion": "26",
		"beaconMode": "standart",
		"sdkVersion": "9.2",
		"clientRequestTime": 9425962992,
		"platform": "Android",
		"lat": 64.0662545,
		"lon": 64.6690699,
		"uniqueId": "6529966",
		"clientIp": "5.9.26.96, 962.952.90.922:92024"
	},
	"beaconSignal": {
		"timestamp": 9425962996,
		"range": "FAR",
		"rssi": -40,
		"serviceUUID": "2AA90000-0A46-995F-D94E-5A466C6EEBB4",
		"majorId": 29,
		"minorId": 4224,
		"pois": ["c69e9a6b-9ada-46ca-a069-69249642ce6a"]
	},
	"createdAt": 9425962996,
	"id": "e46d6dc4-4be5-4fc9-a956-92652f9ca6d0",
	"_rid": "JJd6AL+lAwQjGWEAAAAAAA==",
	"_self": "dbs/JJd6AA==/colls/JJd6AL+lAwQ=/docs/JJd6AL+lAwQjGWEAAAAAAA==/",
	"_etag": "\"9f002b22-0000-0000-0000-52999e990000\"",
	"_attachments": "attachments/",
	"_ts": 9425962965
}, {
	"clientData": {
		"secret": "29DD4DED-4612-44FA-A2DF-20F9ED05F20E",
		"device": "HTC One_M2",
		"vendorId": "",
		"osVersion": "26",
		"beaconMode": "standart",
		"sdkVersion": "9.2",
		"clientRequestTime": 9425962922,
		"platform": "Android",
		"lat": 64.0662545,
		"lon": 64.6690699,
		"uniqueId": "6529966",
		"clientIp": "5.9.26.96, 962.952.90.922:29646"
	},
	"beaconSignal": {
		"timestamp": 9425962926,
		"range": "FAR",
		"rssi": -40,
		"serviceUUID": "2AA90000-0A46-995F-D94E-5A466C6EEBB4",
		"majorId": 29,
		"minorId": 20620,
		"pois": ["c69e9a6b-9ada-46ca-a069-69249642ce6a"]
	},
	"createdAt": 9425962926,
	"id": "9bd46c00-effd-42d9-b924-b64d2449926e",
	"_rid": "JJd6AL+lAwQCGWEAAAAAAA==",
	"_self": "dbs/JJd6AA==/colls/JJd6AL+lAwQ=/docs/JJd6AL+lAwQCGWEAAAAAAA==/",
	"_etag": "\"9f000a22-0000-0000-0000-52999e040000\"",
	"_attachments": "attachments/",
	"_ts": 9425962955
}

We preferred Azure Cosmos DB because Poi Labs wanted to go with a NoSQL document database. To speed up this lookup, they decided to make the lookup in their application’s in-memory first. If it’s not in the in-memory, it would go to Azure Cosmos DB. To make this lookup better, they wanted to have caching. We suggested they plug Azure Redis Cache in between this lookup to not waste time querying it in Azure Cosmos DB.

After the lookup is completed, the API was returning an HTTP 200 OK message to the mobile app, but another async call in Node.js code needed to send a message to the Azure event hub so we could take the signal data out of it. After this signal message reached the event hub, we decided to take the data into Azure Blob storage as our raw-data storage. But we needed to take more actions with the signal messages.

Here Azure App Service/Function App came to the rescue. Our messages were flowing through the event hub, so we decided to go with Event Hub triggers for Azure Functions. Because Poi Labs team members were comfortable with Node.js, we chose Node.js as the language to use in the Azure Functions app as well.

In the Azure Functions app, we implemented their business logic rules and also reached to the Azure Cosmos DB collection to store the signals. In addition to those two things, Hopi was asking this system to send an HTTP request to its back end running in another system. We implemented this in Azure Functions very quickly.

“… As we’re not getting any workload during the night, Azure App Service automatically decreases the number of App Service instances and this helps optimize our costs. This is a very important point for us.”

— Ergin Aktas, Senior Software Developer, Poi Labs

Poi Labs also needed to run a batch job, which it calls an “end of the day process,” every night to create heatmaps out of all those signals. Poi Labs preferred to make this again in Azure App Service/API apps code using a cron package named node-cron. This was making the necessary calculations and writing the outputs into another collection in Azure Cosmos DB, which was needed by Poi Labs as well as its customers.

To address both of those requests, we decided to use Power BI Embedded because it supports connecting to an Azure Cosmos DB database in addition to lots of other data sources. The team quickly created Power BI reports using Power BI Desktop and embedded this Power BI report into their app with Power BI Embedded.

Sample screenshot for a Poi Labs customer

POI Labs - Team is working on architecture


The following video shows the heatmap of end users for a short period of time:

Conclusion

As a result of this joint effort:

  • Poi Labs now can handle as many customers and beacons as needed because Microsoft Azure allows them to scale the system very easily.
  • The Poi Labs data analysis team can use the raw data that is continuously stored in Azure Blob storage as the base for their data analysis projects to make predictions using Machine Learning.

Interview with Poi Labs CTO Mustafa Sapcilar and Senior Software Developer Ergin Aktas (English subtitles):

Additional resources