The indi_mr package

Defines functions to set the indi, redis and mqtt server parameters.

indi_server redis_server mqtt_server

These three functions set up server parameters such as host, port, passwords etc, and return named tuples which are then used as arguments to the following blocking functions which convert between the INDI protocol and redis storage, and transfers INDI data over MQTT.

inditoredis:

Receives XML data from indiserver (typically port 7624) and stores in redis. Reads data published via redis, and outputs to indiserver.

driverstoredis:

Given a list of drivers, runs them and stores received XML data in redis. Reads data published via redis, and outputs to the drivers. Does not require indiserver.

inditomqtt:

Receives XML data from indiserver (typiclly port 7624) and publishes via MQTT. Receives data from MQTT, and outputs to indiserver.

driverstomqtt:

Given a list of drivers, runs them and publishes received XML data via MQTT. Reads data published via MQTT, and outputs to the drivers. Does not require indiserver.

mqtttoredis:

Receives XML data from MQTT and stores in redis. Reads data published via redis, and outputs to MQTT.

mqtttoport:

Opens a server port. If a client is connected, forwards data from MQTT to the client, if data received from the client, passes it to MQTT.

Functions in indi_mr

These first three functions are used to create named tuples.

For example:

from indi_mr import indi_server, redis_server, mqtt_server

indi_host = indi_server(host='localhost', port=7624)
redis_host = redis_server(host='localhost', port=6379)
mqtt_host = mqtt_server(host='localhost', port=1883)

These variables ‘indi_host’, ‘redis_host’ and ‘mqtt_host’ are then used as inputs to further functions which require definitions of the hosts.

indi_mr.indi_server(host='localhost', port=7624)

Creates a named tuple to hold indi server parameters

Parameters
  • host (String) – The name or ip address of the indiserver, defaults to localhost

  • port (Integer) – The port number of the indiserver, defaults to standard port 7624

Returns

A named tuple with host and port named elements

Return type

collections.namedtuple

indi_mr.redis_server(host='localhost', port=6379, db=0, password='', keyprefix='indi_', to_indi_channel='to_indi', from_indi_channel='from_indi')

Creates a named tuple to hold redis server parameters

The to_indi_channel string is used as the channel which a client can use to publish data to redis and hence to indiserver. It can be any string you prefer which does not clash with any other channels you may be using with redis.

The from_indi_channel string must be different from the to_indi_channel string. It is used as the channel on which received XML data is published which the client can optionally listen to.

Parameters
  • host (String) – The name or ip address of the redis server, defaults to localhost

  • port (Integer) – The port number of the redis server, defaults to standard port 6379

  • db (Integer) – The redis database, defaults to 0

  • password (String) – The redis password, defaults to none used.

  • keyprefix (String) – A string to use as a prefix on all redis keys created.

  • to_indi_channel (String) – Redis channel used to publish data to indiserver.

  • from_indi_channel (String) – Redis channel used to publish alerts.

Returns

A named tuple with above parameters as named elements

Return type

collections.namedtuple

indi_mr.mqtt_server(host='localhost', port=1883, username='', password='', to_indi_topic='to_indi', from_indi_topic='from_indi', snoop_control_topic='snoop_control', snoop_data_topic='snoop_data')

Creates a named tuple to hold MQTT parameters

The topic strings are used as MQTT topics which pass data across the MQTT network, each must be different from each other, and should not clash with other topic’s you may be using for non-indi communication via your MQTT broker.

Parameters
  • host (String) – The name or ip address of the mqtt server, defaults to localhost

  • port (Integer) – The port number of the mqtt server, defaults to standard port 1883

  • username (String) – The mqtt username, defaults to none used

  • password (String) – The mqtt password, defaults to none used.

  • to_indi_topic (String) – A string to use as the mqtt topic to send data towards indiserver.

  • from_indi_topic (String) – A string to use as the mqtt topic to send data from indiserver.

  • snoop_control_topic (String) – A topic carrying snoop getProperties requests

  • snoop_data_topic (String) – A topic carrying snoop data

Returns

A named tuple with above parameters as named elements

Return type

collections.namedtuple

The to_indi_topic should be a string, the same string should be used for every connection, so, for example, clients will send data with this topic, and servers/drivers will subscribe to the topic to receive that data.

Similarly the from_indi_topic should be another, different string, again used for every connection.

The same rule follows for the snoop_control_topic and snoop_data_topic.

The tuples created by the above functions are then used as parameters for the following functions.

indi_mr.inditoredis

An INDI client which reads data from indiserver (port 7624) converts the XML to redis key-value storage. In the other direction, subscribes to XML data published via Redis and transmits to indiserver. Enables a GUI or web client to communicate to indiserver purely via redis.

indi_mr.inditoredis(indiserver, redisserver, log_lengths={}, blob_folder='')

Blocking call that provides the indiserver - redis conversion

Parameters
  • indiserver (namedtuple) – Named Tuple providing the indiserver parameters

  • redisserver (namedtuple) – Named Tuple providing the redis server parameters

  • log_lengths (dictionary) – provides number of logs to store

  • blob_folder (String) – Folder where Blobs will be stored

For further information on the log_lengths parameter see Log Lengths.

So a minimal script using defaults to run inditoredis could be:

from indi_mr import inditoredis, indi_server, redis_server

# define the hosts/ports where servers are listenning, these functions return named tuples
# which are required as arguments to inditoredis().

indi_host = indi_server(host='localhost', port=7624)
redis_host = redis_server(host='localhost', port=6379)

# blocking call which runs the service, communicating between indiserver and redis

inditoredis(indi_host, redis_host, blob_folder='/path/to/blob_folder')

# Set the blob_folder to a directory of your choice

Note that BLOB’s - Binary Large Objects, such as images are not stored in redis, but are set into a directory of your choice defined by the blob_folder argument.

indi_mr.driverstoredis

indi_mr.driverstoredis(drivers, redisserver, log_lengths={}, blob_folder='')

Blocking call that provides the drivers - redis conversion

Parameters
  • drivers (List) – List of executable drivers

  • redisserver (namedtuple) – Named Tuple providing the redis server parameters

  • log_lengths (dictionary) – provides number of logs to store

  • blob_folder (String) – Folder where Blobs will be stored

For further information on the log_lengths parameter see Log Lengths.

A minimal script using defaults to run driverstoredis could be:

from indi_mr import driverstoredis, redis_server

redis_host = redis_server(host='localhost', port=6379)

# blocking call which runs the service, communicating between the drivers and redis

driverstoredis(["indi_simulator_telescope", "indi_simulator_ccd"], redis_host, blob_folder='/path/to/blob_folder')

# The list of two simulated drivers shown above should be replaced by a list of your own drivers.

MQTT Networking

As an alternative to inditoredis or driverstoredis, the functions below provide communications via an MQTT server.

The MQTT network transmits data between drivers and clients, and also sends snooping data between devices. Each of the functions requires a unique mqtt_id which is a string identifying the attachment to the MQTT network. Each function can also take a ‘subscribe_list’ which indicates the remote connections it ‘listens to’.

For example, the functions mqtttoredis and mqtttoport are ‘client connections’ and their subscribe_list should contain the mqtt_id’s of the driver functions (inditomqtt and driverstomqtt) which those clients wish to connect to.

Similarly inditomqtt and driverstomqtt should have subscribe_list’s which contain the client mqtt_id’s which connect to them. For most simple cases, the lists can all be left empty, which, as default, allows all connections - so the clients will see all attached devices.

indi_mr.inditomqtt

Intended to be run on a device with indiserver, appropriate drivers and attached instruments.

Receives/transmitts XML data between indiserver on port 7624 and an MQTT server which ultimately sends data to the remote web/gui server.

indi_mr.inditomqtt(indiserver, mqtt_id, mqttserver, subscribe_list=[])

Blocking call that provides the indiserver - mqtt connection. If subscribe list is empty then this function subscribes to received data from all remote mqtt_id’s. If it contains a list of mqtt_id’s, then only subscribes to their data.

Parameters
  • indiserver (namedtuple) – Named Tuple providing the indiserver parameters

  • mqtt_id (String) – A unique string, identifying this connection

  • mqttserver (namedtuple) – Named Tuple providing the mqtt server parameters

  • subscribe_list (List) – List of remote mqtt_id’s to subscribe to

Example Python script running on the machine with indiserver and the connected instruments:

from indi_mr import inditomqtt, indi_server, mqtt_server

# define the hosts/ports where servers are listenning, these functions return named tuples.

indi_host = indi_server(host='localhost', port=7624)
mqtt_host = mqtt_server(host='10.34.167.1', port=1883)

# blocking call which runs the service, communicating between indiserver and mqtt

inditomqtt(indi_host, 'indi_server01', mqtt_host)

Substitute your own MQTT server ip address for 10.34.167.1, and your own mqtt id for ‘indi_server01’.

To be specific, the mqtt_id should be unique for every connection to the MQTT network.

When choosing an mqtt_id, consider using a prefix, to avoid clashing with other users of the MQTT broker, such as indi_server01, or indi_client01.

indi_mr.driverstomqtt

Connects INDI drivers and attached instruments to the MQTT network without needing indiserver.

indi_mr.driverstomqtt(drivers, mqtt_id, mqttserver, subscribe_list=[])

Blocking call that provides the drivers - mqtt connection. If subscribe list is empty then this function subscribes to received data from all remote client mqtt_id’s. If it contains a list of mqtt_id’s, then only subscribes to their data.

Parameters
  • drivers (List) – List of executable drivers

  • mqtt_id (String) – A unique string, identifying this connection

  • mqttserver (namedtuple) – Named Tuple providing the mqtt server parameters

  • subscribe_list (List) – List of remote mqtt_id’s to subscribe to

Example Python script running on the machine with the connected instruments:

from indi_mr import driverstomqtt, mqtt_server

# define the host/port where the MQTT server is listenning, this function returns a named tuple.

mqtt_host = mqtt_server(host='10.34.167.1', port=1883)

# blocking call which runs the service, communicating between drivers and mqtt

driverstomqtt(["indi_simulator_telescope", "indi_simulator_ccd"], 'indi_drivers01', mqtt_host)

# The list of two simulated drivers shown above should be replaced by a list of your own drivers.

Substitute your own MQTT server ip address for 10.34.167.1, and your own mqtt id for ‘indi_drivers01’.

indi_mr.mqtttoredis

Intended to be run on the same server running a redis service, typically with the gui or web service which can read/write to redis.

An INDI client which receives XML data from the MQTT server and converts to redis key-value storage, and reads data published to redis, and sends to the MQTT server.

indi_mr.mqtttoredis(mqtt_id, mqttserver, redisserver, subscribe_list=[], log_lengths={}, blob_folder='')

Blocking call that provides the mqtt - redis connection

Parameters
  • mqtt_id (String) – A unique string, identifying this connection

  • mqttserver (namedtuple) – Named Tuple providing the mqtt server parameters

  • redisserver (namedtuple) – Named Tuple providing the redis server parameters

  • subscribe_list (List) – List of remote mqtt_id’s to subscribe to.

  • log_lengths (dictionary) – provides number of logs to store

  • blob_folder (String) – Folder where Blobs will be stored

For further information on the log_lengths parameter see Log Lengths.

Example Python script running at the redis server:

from indi_mr import mqtttoredis, mqtt_server, redis_server

# define the hosts/ports where servers are listenning, these functions return named tuples.

mqtt_host = mqtt_server(host='10.34.167.1', port=1883)
redis_host = redis_server(host='localhost', port=6379)

# blocking call which runs the service, communicating between mqtt and redis

mqtttoredis('indi_client01', mqtt_host, redis_host, blob_folder='/path/to/blob_folder')

Set the blob_folder to a directory of your choice and substitute your own MQTT server ip address for 10.34.167.1, and mqtt id for ‘indi_client01’.

indi_mr.mqtttoport

Transfers XML data between the MQTT server and a server port, which, in turn, can connect to an INDI client.

indi_mr.mqtttoport(mqtt_id, mqttserver, subscribe_list=[], port=7624)

Blocking call that provides the mqtt - port connection. If subscribe list is empty then this function subscribes to received data from all remote mqtt_id’s. If it contains a list of mqtt_id’s, then only subscribes to their data.

Parameters
  • mqtt_id (String) – A unique string, identifying this connection

  • mqttserver (namedtuple) – Named Tuple providing the mqtt server parameters

  • subscribe_list (List) – List of remote mqtt_id’s to subscribe to.

  • port (integer) – Port to listen at, default 7624

Example Python script:

from indi_mr import mqtttoport, mqtt_server

# define the mqtt server

mqtt_host = mqtt_server(host='10.34.167.1', port=1883)

# blocking call which runs the service, communicating between mqtt and the port

mqtttoport("indi_port01", mqtt_host, port=7624)

Substitute your own MQTT server ip address for 10.34.167.1, and mqtt id for ‘indi_port01’.