Sensor Web, Geoprocessing, Security & GeoRM, Geostatistics, Semantics, 3D, Ilwis, Earth Observation

Integrating LoRaWAN Sensors with the OGC SensorWeb

November 8th, 2017 @ 11:21 by Norwin Roosen
Posted in 52°North, Innovation Challenge, Sensor Web

In this year’s Student Innovation Challenge held by 52°North, I participated with a software project aiming to extend the open sensor web with a new way to transmit sensor observations. The 8-week challenge under the topic ‘Bridging IoT and Sensor Web Applications’ enabled me to deepen my knowledge on LoRaWAN connected sensors while contributing to the Sensor Web community. My project’s deliverable is an integration between TheThingsNetwork and the OGC SensorWeb, adding the missing component to a full open source stack for LoRaWAN connected sensing platforms.

LPWAN Opportunities

LPWAN – short for Low Power Wide Area Network – is a rather new class of radio communication protocols, mainly targeted at IoT applications. These protocols provide a high transmission range of multiple kilometers (current observed maximum: 702 km) at very low energy usage and data throughput (300 – 3k Bit/s). While this technology finds increasing adoption in the realm of IoT applications, it is not widespread in the classic Sensor Web community, despite enabling new use cases. With its high range and low power requirements, a new class of autonomous low energy sensors becomes feasible, which can be deployed in very remote locations, or in highly mobile environments.

Currently, there is high competition in the market of LPWAN solutions (which are a bundle of a Layer 1 protocol, IP-network backends and physical gateways for network coverage) that are mostly developed by established telco operators as proprietary solutions.  There is, however, one open solution; TheThingsNetwork (TTN). In this network, anybody is allowed to deploy gateways and devices, giving it arbitrary geographic coverage. It provides an open source IP-network bridge, connecting LoRaWAN devices to the internet: Devices send their messages to an MQTT broker, which distributes them further to data-consuming applications after applying deduplication, decoding and authorization.

Project Idea

Because low powered, not-so-smart devices generally cannot provide the complex payloads required by the OGC SensorWeb and LoRaWAN-payloads are very limited in size (max ~250 bytes), there is a translation step necessary to insert minimal measurement payloads into the storage backend.

Working with senseBox, we started experimenting with sensor deployments that would connect via TTN to our custom Sensor Web platform openSenseMap. To get the sensor stations’ messages out of TTN, I implemented a bridge that would fetch the messages, decode them and feed them to our (non standard) openSenseMap API. While doing its job well, this first iteration of the bridge would be rather complicated to set up for each user, as it requires the end user to perform registration and configuration in both openSenseMap and TTN.

Motivated by simplifying this setup-procedure, I wanted to build a second iteration of such a bridge. Additionally, I wanted to target a wider adopted, well standardized platform. Integrating the OGC Sensor Web with TTN seems like a great way of extending an open ecosystem for IoT sensing applications, hopefully fostering its adoption with new use cases.

Architecture of the Integrated Systems

system architecture diagram

System Architecture Diagram

The developed integration acts as a message bridge between the TTN MQTT broker and an OGC storage backend. The specific backends are implemented on a plugin API, implementing the following simple interface. This allows for adding arbitrary future backend implementations.

export interface ITTNMessageBroker {
  init(): Promise<any>
  createMessage(ttnMsg: ITTNMessage): Promise<any>
  submitMessage(message: any): Promise<any>

Per limitations of the TTN architecture (exactly one decoder configuration per TTN application), there has to be one bridge instance and TTN application per sensor configuration differing in the combination of observed phenomena or observation encoding. Additionally, sensor observations can be fed to multiple backends by launching a bridge instance for each backend.

Event Flow

With this architecture, the event flow can be described as follows:

  • Initial deployment
    1. User registers application in TTN
    2. User configures & deploys ttn-ogcswe-integration
    3. Integration configures message decoders & subscribes to messages
  • Sensor setup
    1. User registers sensing device in TTN
    2. User configures & deploys sensor hardware
  • Sensor operation
    1. Device transmits observation
    2. TTN decodes message & passes it to Integration
    3. Integration maps device to sensor in backend, or creates one if not found
    4. Integration sends observation to backend for the found sensor

This means that there’s no need to register a device twice in both TTN and the backend. All configuration is declarative, always in sync between both components, and done only once!

If you are interested in setting up such an integration, you should read a detailed guide on the necessary steps to get data from a LoRaWAN connected sensor into a 52°North SOS.

Implementing the Prototype

There were three main goals that prototype should solve:

  1. Uplink messages from sensors must be received, transformed and then forwarded to the storage backend.
  2. Administrative tasks should be automated where possible or at least deduplicated (device-mapping between components, registration in components, authentication).
  3. Flexible and scalable for various sensor configurations.

Being rather new to the OGC SWE ecosystem, I assumed that the new SensorThings API (STA) would be the ideal target for the bridge. It provides a JSON- and MQTT-interface, which fit the APIs provided by TTN very well. However, as I got briefed by the kind 52°North staff, I realized that STA is just another interface to the same data-storage model that is used by the OGC SOS. While the STA would probably enable a more efficient and bidirectional mapping of devices in both components, we decided to implement the prototype against the SOS Transactional API as implemented by 52°North to avoid pitfalls with the very young STA standard (immature specification and implementations, unclear adoption).

As there are no eventing APIs in the SOS for sensor registrations, it not feasible to automate device registrations on the TTN side. Instead, registrations in TTN must serve as source of truth for the mapping and registration of devices. Because the capabilites of metadata storage for TTN devices are limited, the provided metadata needs to be inflated by the integration to some fullfledged SensorML in order to automate sensor registration in the SOS. As a result, the bridge provides an as-generic-as-possible SensorML template, which is used to register a new sensor in the SOS once a payload of an unknown TTN device is received. This solution is not very flexible and could be improved by implementing the STA backend, which allows one to subscribe to new sensor registrations.

Being familiar with node.js (and having a TTN SDK available for it), but missing a type system in plain JavaScript, I decided to implement the application in TypeScript, which compiles to current JavaScript. A Docker container is provided as well for quick deployments. The project’s code can be found on 52°North’s Github.


To make deployment as simple as possible, configuration of the integration is done via a single declarative YAML file (example), which allows for launching multiple instances in one process. The integration requires neither open ports nor a domain, because it uses MQTT to subscribe to inbound messages. Please have a look at this extensive setup introduction if you want to try it out!

Many thanks to 52°North for the opportunity of participating in this challenge and letting me present the results at this year’s Geospatial Sensor Webs Conference!


No comments yet.

RSS feed for comments on this post.

Leave a comment

Time limit is exhausted. Please reload CAPTCHA.