Creating a Client Program

A client program is a program which consumes moment data produced by the radar. Creating a client program is not very difficult. The software repository ships with three different example client programs:

  1. Client.ipynb – Listens for moment data coming from the radar, and plots line plots of reflectivity, Doppler velocity, and I/Q of the first channels. It also saves the moment data to disk.
  2. PPIClient.ipynb – Listens for moment data coming from the radar, and plots the returned signal on a PPI plot. It also saves the moment data to disk.
  3. Simple Data Receiver.ipynb – A minimalist client program that only receives data and dumps it to disk. This program does not rely on anything in this repository.

Conceptually, a client program is pretty simple. A program must do the following steps:

  1. Open a Nanomsg subscribe socket and connect to the radar’s IP address and port.
  2. nn_recv() from the socket. Every recv() will return a radial’s worth of data. The data format is described in Moment Data Format.
  3. Decode the data using MessagePack [1]
  4. Do something useful with the data.
  5. Repeat steps 2-4.

Footnotes

[1]

Most of the data is encoded using the MessagePack EXT type. This was done to efficiently serialize homogeneous arrays. The following code snippet can be used to take in data (in Python)

from itertools import count

import msgpack
import nanomsg
import numpy as np
import struct


def ext_hook_unpack(code, data):
    """
    This is a simplified version of the function wni.util.ext_hook_unpack.
    """
    if code == 0:
        real, imag = struct.unpack('ff', data)
        ret = complex(real, imag)
    elif code == 1:
        dtype, shape, array_data = msgpack.unpackb(data)
        flat_array = np.fromstring(array_data, dtype=np.sctypeDict[dtype])
        ret = flat_array.reshape(shape)
    else:
        raise ValueError('unknown code {}'.format(code))
    return ret


def unpackb(data):
    """This function unpacks numpy arrays for you.  Call it instead of msgpack.unpackb"""
    return msgpack.unpackb(data, ext_hook=ext_hook_unpack, encoding='utf-8')


sock = nanomsg.Socket(nanomsg.SUB)
# subscribe to the data stream
sock.set_string_option(nanomsg.SUB, nanomsg.SUB_SUBSCRIBE, b'')
sock.connect("tcp://156.110.99.53:25000")
# set a timeout so the program doesn't hang forever
sock.recv_timeout = 5000

for i in count(1):
    raw_data = sock.recv()
    as_dict = unpackb(raw_data)
    print('\rreceived data {}: az {:.2f}°'.format(i, as_dict['az']), end='')