Radio telemetry with Nexmo and Python

I crawled further down the cable duct and got an attack of claustrophobia. It was in the depths of a Norwegian winter and despite the heat being generated by the TransOcean 8's vast diesel room I was half frozen. I crawled a bit further, dragging the armoured cable behind me. Only a few more metres to go and I'd drop, literally, into the pit room where I'd already installed my junction box. TO8's pit room was the biggest I'd seen, with twelve main pits. Most rigs I'd been on only had three. TO8 was the mother of all wildcat rigs, ploughing its trade in godforsaken stretches of the North Sea. Despite the dark storm raging outside the TO8 was rock steady, a testament to is immovable bulk, kept in position by state-of-the-art GPS and huge computer-controlled thrusters. I lugged the cable a bit further. Nearly there. I dropped down into the pit room, exhausted, and pondered how much easier my life would be if I didn't have to lug cables around. So far, I reckoned I'd wired up fifty sensors, and I was probably half-done. The most dangerous to install had been the kelly height sensor. I'd been winched up into the derrick by a roughneck who'd just worked 12 hours straight. At one point I think he fell asleep standing up, leaving me dangling in mid air. I quickly tie-wrapped the kelly bottle onto the kelly block, a makeshift sensor as simple as it was ingenious - a pressurized system of water and air - you went up - more water pressure on a strain gauge, you went down, less pressure. I shouted down to the roughneck and slowly descended. We both shuffled off the drill deck, thinking of sleep.

The most claustrophic install had been the rotary table RPM sensor. I'd had to squueze into a tiny crawl space under the rotary table, the spinning clutch powered by a vast electric motor, that turned the entire drill string, a couple of miles of the stuff, probing down into the prehistoric rock formations.

I dropped down into an empty pit and grumbling to myself started welding in a bracket for the mud-level sensor, and wished the whole mess of cables, the bane of my life, would just go away...

So what is radio telemetry?

The above little vignette hints at a problem. When you have a biggish data acquisition project you usually have to end up installing literally miles of cable, which is a right Royal pain in the bum. A better way is to use radio telemetry. In the age of the Internet of Things this should be quite possible, and it is, within certain limitations.

Radio telemetry is the ability to send data, especially data from sensors, via radio waves rather than through electrical cables.

Radio telemetry is especially useful in scenarios where the source at edge-of-network is physically very remote, or possibly even moving. Obviously, when you try to run cables from the GPS sensor on a train and wire it back to your logging unit you are in for some trouble! ;)

Telemetry by radio waves is more or less essential where the sensor is moving. You could simply store the data locally for downloading later, but this does not give you the real-time data you need in many scenarios. By real-time here we are not talking high frequency updates - we might only need to know the position of the train every 30 seconds or so.

Example scenarios

So, just to recap, radio telemetry is very useful where the source of the data is:

  1. Remote
  2. Moving

Some examples:

In this article I am specifically looking at sending small amounts of low-frequency telemetry data via SMS, using the Nexmo SMS API and a little bit of Python.

Overview

So what are we looking at specifically in this article?

With low cost boards available you have the potential for very cheap sensor electronics. A Raspberry Pi or Arduino are suitable for low cost multi-channel data acquisition from a variety of sensors. They are also capable of carrying out various control tasks such as temperature control and motor control.

With suppliers like Ada Fruit providing cheap SMS modules for Pi and 'shields' for Arduino - the sky is, quite literally, the limit. You could acquire data on multiple channels and then send that information via SMS - it does not matter how remote the sensor is (as long as there's mobile coverage), or whether the sensor is moving or not.

By way of example, messages might be sent as follows:

  1. TANK1=25.1M, TANK2=13.2M, TANK3=43.9M(ALARM), TANK4=9.7M
  2. (21.62514414481643, -2.3010920480245426)=233.7Kg
  3. DANGER: Warp drive is overheating! Please call +44-700000000 immediately!

Note, you can identify the source of the data by the incoming message phone number, so you don't need to include that in the message unless more than one unit are sharing an "SMS hub". Actually in many scenarios the idea of an SMS hub could be quite useful.

Limitations

When using SMS as a radio telemetry system, there are some limitations to take into account:

  1. The rate at which you can send SMS messages. (Nexmo throttles to around 30 API calls a second)
  2. The message length of a single SMS. (Theoretically there is a standard but different carriers have different restrictions)

For small data applications these retrictions will be fine. If you have especially large chunks of data, that data can be spread over multiple messages. I would not go over three messages though because not all carriers deliver as many as six.

Legal

I'm not sure you could use your typical 'unlimited SMS plan' in such a scenario. You would have to contact your provider. If you are sending a lot of SMS messages your provider might kick up about it. Still one SMS an hour for 24 SMS per day is not going to be too problematic - my daughter used to send several hundred SMS a day when she was about 15! I think for hobby testing and so on, which is what we are talking about here, you should be fine.

If in doubt check with your provider and possibly a lawyer!

Getting set up

  1. Install Ngrok. If you plan to run the test code locally you can use Ngrok. See my article on Ngrok for some pointers on how to do this.
  2. You'll need to sign up for a Nexmo account. You'll get a couple of Euros free credit which will let you run a few tests. Renting a virtual number costs around 1.5 Euros a month. There are then small costs per outbound call or SMS, but in the example shown here you'll be testing by sending an inbound SMS with your data in it.
  3. Purchase a Nexmo Number (Long Virtual Number). This is the number you'll send your telemetry SMS to.
  4. Configure a webhook. See the following screenshot:

Webhook

You now need to write some code!

Python backend

Here's the Python code for reacting to the inbound SMS that contains your telemetry data:

# Python 3
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse
from urllib.parse import parse_qs
from pprint import pprint

import time
import json

hostName = "localhost"
hostPort = 9000

OK = 200

class MyServer(BaseHTTPRequestHandler):

    def do_GET(self):

        self.send_response(OK)
        self.send_header("Content-type", "text/html")
        self.end_headers()

        if self.path.startswith('/webhooks/inbound-sms'):

            result = urlparse(self.path)
            params = parse_qs(result.query)
            data = params['text'][0]

            print ("Telemetry data is: %s" % data)


# Run server
myServer = HTTPServer((hostName, hostPort), MyServer)
print(time.asctime(), "Server Starts - %s:%s" % (hostName, hostPort))

try:
    myServer.serve_forever()
except KeyboardInterrupt:
    pass

myServer.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (hostName, hostPort))

Testing the backend

Send a text into your Nexmo Number. You'll see tracing like the following (I've redacted my phone number and Nexmo number):

Sat Apr 28 08:16:40 2018 Server Starts - localhost:9000
127.0.0.1 - - [28/Apr/2018 08:18:28] "GET /webhooks/inbound-sms?msisdn=4400000000&to=4400000000&messageId=0B000000D29DB198&text=Telemetry+data+123456789&type=text&keyword=TELEMETRY&message-timestamp=2018-04-28+07%3A18%3A34 HTTP/1.1" 200 -
Telemetry data is: Telemetry data 123456789

Just to make it a bit easier to read the webhook response parameters (with phone numbers redacted) are in the following format:

{
    'keyword': ['TELEMETRY'],
    'message-timestamp': ['2018-04-16 11:19:22'],
    'messageId': ['0C000000A7438C74'],
    'msisdn': ['440000000000'],
    'text': ['Telemetry+data+123456789'],
    'to': ['4400000001'],
    'type': ['text']
}

The code fishing out the telemetry data. Of course you can do anything you want with this data including: resending it, processing it, storing it to a file and so on.

Note also ther MSISDN is the phone number of the sending device, so you have immediate identification of source. Of course if there are multiple channels on one source the message does still need to identify the channel, for example CH1=23.1, CH2=46.5, CH3=1.2.

It could be a two-way thing

With Nexmo you can have inbound and outbound phone calls and text messages. So, you could for example send a control SMS to your monitoring or control equipment. You could do things like switch on your lights at home, activate sprinklers, or switch off a pump that's overheating. The applications are endless.

Closing words

I have just scratched the surface here of what is an area with enormous potential. I hope you've found this useful. You have at least seen that you can write some Python code to receive data sent in via SMS, and with that the sky is the limit.

As always if you've any questions see my Contact page for details of how to get in touch.

Resources