Data Analytics Python Guide

Warning

This is a legacy Python DA module reference guide. While the DA apps written using the legacy DA module will continue to work in the newer firmware, please note that this is not actively maintained.

The Data Analytics functionality can be implemented as a Python script using the Python ZIOTC (Zebra IOT Connector) module resident on the reader. The script relies on Python’s asyncio module.

The Python ZIOTC module is meant to abstract the underlying connections between the IoT Connector components (i.e. Radio Control and Reader Gateway) and allow the script to filter, analyze, and act on the data itself.

The minimal flow of the script is as follows:

  1. Define a new message callback function to operate on the incoming data. This function will be called whenever there is new data to be filtered.

    def new_msg_callback(msg_type, msg_in):
        pass
    

    For more details see New Message Callback

  2. Open the ZIOTC module. This will extablish connections between the script and the other IoT Connector components.

    import ziotc
    ziotcObject = ziotc.ZIOTC()
    
  3. Register the previously defined function from step 1. This notifies the ZIOTC module to use the callback funtion when new messages arrive.

    ziotcObject.reg_new_msg_callback(new_msg_callback)
    
  4. Run the ZIOTC loop. This will cause any messages arriving to flow through the callback function.

    ziotcObject.loop.run_forever()
    

New Message Callback

The user-defined new message callback function is the core of the script. The callback definition must contain 2 parameters, msg_type and msg_in. The function can then process the input message and send out an output message based on the input. All messages shall be Python bytearrays

For example, the following callback function, only sends out a data message if the beginning of the tag’s ID begins with a prefix.

prefix = "38"
def new_msg_callback(msg_type, msg_in):
    if msg_type == ziotc.ZIOTC_MSG_TYPE_TAG_INFO_JSON:
        msg_in_json = json.loads(msg_in.decode('utf-8'))
        tag_id_hex = msg_in_json["data"]["idHex"]

    if tag_id_hex.startswith(prefix):
        ziotcObject.send_next_msg(ziotc.ZIOTC_MSG_TYPE_DATA, msg_in)

Input Message types

The new message callback will be called each time a new message arrives from the Radio Control. The incoming msg_type is a constant defined in the ziotc.py module. The currently available value for incoming messages is:

ZIOTC_MSG_TYPE_TAG_INFO_JSON = 0

The ZIOTC_MSG_TYPE_TAG_INFO_JSON type is a JSON tag information message (after decoding from the bytearray). The format is identical to the format of tag messages coming directly from the Radio Control.

Output Message types

Messages can be sent to the Reader Gateway and off the reader by calling:

ziotcObject.send_next_msg(msg_type, msg_out)

msg_type is a constant defined in the ziotc.py module. The currently available value for outgoing messages are:

ZIOTC_MSG_TYPE_DATA= 3
ZIOTC_MSG_TYPE_CTRL= 4
ZIOTC_MSG_TYPE_GPO = 5

The ZIOTC_MSG_TYPE_DATA type will send the message to the Reader Gateway to output on the Data Interface. The ZIOTC_MSG_TYPE_CTRL type will send the message to the Reader Gateway to output on the Management Event Interface. The ZIOTC_MSG_TYPE_GPO type will send the message to the GPIO-LED module.

Data Analytics Passthru

In addition to processing data from the Radio Control and passing new, or filtered, data through to the Reader Gateway, messages can be passed through the Reader Gateway directly to the Data Analytics script. These messages can be sent to the Reader Gateway via the Management Command/Response interface. In order to process the passed through messages, a pass through callback must be defined and registered with the ZIOTC object.

The pass through callback takes in a single parameter. It is a bytearray of the incoming message.

Important

The function must return a response message that is also a bytearray.

This functionality enables a mechanism to configure the Data Analytics Script. The following code snippet continues the example above and allows for a single command “prefix” to be sent to the script. If only “prefix” is sent, the script returns the current value the script is using to filter tags. If prefix is followed by another string, it will update the “prefix” to the new value.

def passthru_callback(msg_in):
    global prefix
    parts = msg_in.decode('utf-8').split(" ")
    print(parts)

    if parts[0] == "prefix":
        if len(parts) == 1:
            response = "prefix set to {}".format(prefix)
            response = bytearray(response.encode('utf-8'))
        else:
            prefix = parts[1]
            response = "prefix set to {}".format(prefix)
            response = bytearray(response.encode('utf-8'))

    else:
        response = b"unrecognized command"

    return response

ziotcObject.reg_pass_through_callback(passthru_callback)

Sample Python DA app

Below is the full script based on the code snippets above.

import ziotc
import json

prefix = "43"
def passthru_callback(msg_in):
    global prefix
    parts = msg_in.decode('utf-8').split(" ")
    print(parts)

    if parts[0] == "prefix":
        if len(parts) == 1:
            response = "prefix set to {}".format(prefix)
            response = bytearray(response.encode('utf-8'))
        else:
            prefix = parts[1]
            response = "prefix set to {}".format(prefix)
            response = bytearray(response.encode('utf-8'))

    else:
        response = b"unrecognized command"

    return response

def new_msg_callback(msg_type, msg_in):
    if msg_type == ziotc.ZIOTC_MSG_TYPE_TAG_INFO_JSON:
        msg_in_json = json.loads(msg_in.decode('utf-8'))
        tag_id_hex = msg_in_json["data"]["idHex"]

        if tag_id_hex.startswith(prefix):
            ziotcObject.send_next_msg(zitoc.ZIOTC_MSG_TYPE_DATA, msg_in)

ziotcObject = ziotc.ZIOTC()
ziotcObject.reg_new_msg_callback(new_msg_callback)
ziotcObject.reg_pass_through_callback(passthru_callback)
ziotcObject.loop.run_forever()