Integrate Your Device

Custom Device Example using the IES-2051 Flowmeter

For the custom device integration example we’ll be using the IES-2051 flowmeter. The ION IES-2051 device is a high-accuracy LoRaWAN turbine flowmeter. The device communicates flow information hourly, and upon a button press.

DIY LoRaWAN device integrations are simple, and GATE-Ware makes them even simpler. Let’s IES-2051’s data packet:

IES-2051 Hourly Flow Data Packet:

Byte Location:   Data:              Range & Description:     
Byte  0          Sensor type        0 to 255 - The 2051 is IES product type 4, this never changes
Byte  1          Firmware version   0 to 255 - Represents current firmware version
Byte  2          Transmit count     0 to 255 - Increments for each packet
Bytes 3-6        Total Gallons      0 to 4B  - Counts gallons up to 4 billion
Bytes 7-8        Flow Time          0 to 65K - Counts flow time in seconds
Bytes 9-10       Flow Events        0 to 65K - Counts "events" where water flowed for 3 seconds or more

Create a Transform:

To create an integration let’s use GATE-Ware’s Transform feature, which allows the user to incur the cost of integration just once. Transforms also give the user the added benefit of including any edge processing on the gateway’s hardware, where it doens’t increase your cloud costs.

The transform below is effectively a parser + some simple edge processing. Let’s consider the recipe:

  1. Parse the bytes into variables, according to the device frame
  2. Use a couple of the variables to process a simple leak check at the edge.

The Code, using Python:

Transforms can be written in any language that the MultiTech Conduit’s Linux build will run. Here we chose to use Python for our Transform:

#!/usr/bin/env python3

import json
from base64 import b64decode
from sys import stdin,stdout

def main():
    # Read the last message from a file named /tmp/last_message.json
    try:
        with open('/tmp/last_message.json', 'r') as f:
            last_message = json.loads(f.read())
    except:
        last_message = {}

    # Read the message from stdin
    message = json.loads(stdin.read())

    #--------------------#
    # DEVICE INTEGRATION #
    #--------------------#

    # Decode the base64 encoded payload field into a byte array
    bytes = b64decode(message['data'])

    # The first byte is an integer representing the sensor type
    message['sensorType'] = bytes[0]

    # The second byte is the firmware_version
    message['firmwareVersion'] = bytes[1]

    # The third byte is the transmitCount
    message['transmitCount'] = bytes[2]

    # The next 4 bytes are a float representing the gallons
    message['gallonsOdometer'] = int.from_bytes(bytes[3:7], byteorder='big') / 1000

    # The next 2 bytes are the flowTime (in seconds)
    message['flowTime'] = int.from_bytes(bytes[7:9], byteorder='big')

    # The next 2 bytes are the eventCount
    message['eventCount'] = int.from_bytes(bytes[9:11], byteorder='big')

    # Write the message object to a file named /tmp/last_message-[deviceeui].json
    with open('/tmp/last_message-'+ message.get('deveui') +'.json', 'w') as f:
        f.write(json.dumps(message, 
            ensure_ascii=True, # no unicode
            separators=(',', ':')))

    #------------------------------------------#
    # EDGE PROCESSING EXAMPLE - LEAK DETECTION #
    #------------------------------------------#

    # If the last_message is not an empty object
    if last_message:

        # Let's set the criteria for a detection:
        # - Water flowing for 1 hour without a break 
        # - Consider a button press

        if (last_message.get('eventCount') == message.get('eventCount') and last_message.get('flowTime') + 3600 < message.get('flowTime')):
            message['warning'] = 'Detected a potential leak!'

            # Write the message to stdout
            stdout.write(json.dumps(message, 
                ensure_ascii=True, # no unicode
                separators=(',', ':'))) # no whitespace

if __name__ == "__main__":
    main()

Have a quick scan through the code above - block comments highlight two sections where integration then edge processing take place. This source was written for use with the IES-2051, but can easily be adapted to other devices by simply adjusting the parser for a different data packet.

Transforms are incredibly flexible, can be accomplished in under 50 lines of code (mostly cut and paste), and you avoid paid vendor lock-in.

Not interested in writing code, but still want to avoid a telco style monthly fee? Hit us up at info@threelabs.io and we can help you integrate your device quickly.