The story of a SCP-based tracking solution
This is a blog post that I postponed for more than one year. I will shortly go through the stuff that I implemented in 2015-2016 for my bachelor degree on SCP (back then, it was still named HCP). You can find the code on my GitHub together with instructions on how to set it up on a SCP account.
Some time ago I decided to build a somewhat complex showcase for a shipment management and tracking solution, targeted at the transport insurance domain. This was a nice spin off from an older UI5 application that I had built with some colleagues for a basic, related scenario.
In a nutshell, from a functional point of view, my new system would be able to:
- Store all the “business” data related to a shipment (e.g. route, schedule, insurance conditions, etc.).
- Record the position and environmental parameters of a shipment.
- Expose this data, enabling real-time tracking.
- Send notifications via email to all specified people when certain conditions were broken during a transport.
- Perform simple analytic scenarios by using all the collected data (e.g. comparing the evolution of several shipments, viewing various statistics, etc.).
It was clear from that start that I would need to make some GPS and internet-enabled tracking devices with sensors attached, which would periodically report the current position and sensor values. I would also need a cloud-based application to collect, process and expose all this data.
Seeing the whole lot of fuss around the SAP Cloud Platform at the time, I’ve decided to try it out and see how and if it would work out. Luckily enough, I had access to a paid SCP account and even got to play around with whatever I wanted on it (thanks msg).
Thus, I ended up designing the following solution:
I’ve built the whole persistent data model by using HANA CDS and exposed most of it through OData (via XSODATA). Later, I even included geospatial columns to the CDS entities for storing the route paths and sensor reading locations.
Here I bumped in the first major problem: I had to change the coordinate system for a CDS entity column. Too bad you could not really do this by using SAP tooling, so in the end I had to use some ugly-but-working workarounds to modify the tables.
Because at the time I started, the trial SCP had a pretty unstable HANA offering (no MDCs) and the paid account did not yet include the IoT service, I decided to build my own device configuration component which I named the “Administration” component.
It was responsible for allowing the user to define new routes, schedules, sensors, devices, transports and people. Basically it had some simple XSJS (classic) services for actions that were not covered by the OData services and some nice UI5 + Google Maps UIs.
The “Tracking” component was pretty simple, it had only one XSJS endpoint which could be used by any internet-enabled device to report the position and sensor values in JSON format.
I would have liked to enable plain HTTP (with no S at the end) for this endpoint to allow a wider range of devices to use it. But I learnt that you cannot do this for a HANA instance in the cloud, even though there is a special setting for this, which apparently didn’t work.
This component also had a UI which directly used the OData service to show the current shipment positions on a map (I actually made some simple wrapper UI5 controls for the Google Map and Markers).
The last HANA component was the “Analytic” one. I built several XSJS services and SQLScript procedures for:
- Showing the evolution in time / geographically of a shipment.
- Comparing shipments.
- Dynamically creating statistics.
- Wrapping some PAL functions for forecasting the future evolution of the statistics.
To display all these analytic scenarios, I used of course the very nice charting library that UI5 has built-in.
All the user interfaces that I made “in the cloud”, I then deployed as separate HTML applications on the SCP account and registered them on the Fiori Launchpad.
Sometimes the Launchpad would have some strange issues with loading UI5 libraries or controls, but I circumvented them by forcing the UI5 apps to load everything from the start (by including them in the sap.ui.define dependency list of e.g. the Component).
For sending notifications, a Java microservice was made and hosted directly on the SCP. The HANA tracking component would trigger HTTP (REST) requests to the Java service in order to send emails.
Something very strange (at least in my opinion) was that the SCP Java app and the HANA instance did not “trust each other” even though they belonged to the same account. So some certificate swapping was needed.
Arduino Tracking Device
My first real tracking device was an Arduino board. Because I had no working GSM module, I actually connected it to a serially commanded Bluetooth module and then through Bluetooth to a C# application on my laptop.
Because I wanted all UIs to be UI5-ish, I tried and even succeeded in embedding UI5 inside a C# desktop application.
Android Tracking Device
The second tracking device was an Android application. Fairly simple to build, the only noticeable thing was that, because I also wanted to have an UI5-ish user interface, I again embedded UI5 directly in the Android application. The alternative would be to build a Cordova / Kapsel hybrid application, but I just went with this simpler and more flexible approach.
The main motivation for this device was purely pragmatical: I needed to feed some real life data into the app and I had some volunteers (my roommates) with Android phones to do the collecting for me. The app is offline-enabled; it stores the data into CSV files which are then uploaded to the HANA services when instructed (i.e. when the volunteers had WI-FI).
It was surely a bumpy road. I encountered a lot of undocumented (at the time) limitations and bugs. The development environment was far from ideal; thank god the Web-based Workbench was finally merged with the WebIDE.
Nevertheless, the SCP offers a very good feature set and helped me a lot in achieving my goals.
I hope that my code will be of use for someone else as well. It is not always the best solution from a purely technical point of view, but it is a working example.