Crate indi

source ·
Expand description

A general purpose library for interacting with the INDI protocol.

The Instrument Neutral Distributed Interface (INDI for short) protocol is an XML-like communicatinos protocol used in the astronomical community to control and monitor astronomical equipment. For more information on INDI see the project’s website here.

The purpose of this crate is to provide a convinent way to interact with devices using the INDI protocol. Details on the protocol can be found here.

Quickstart

Prerequisites

To compile this crate, you must first have the libcfitsio library installed. For debian based linux distros this can be satisfied by running:

$ sudo apt install libcfitsio-dev

Once that’s complete, using you should be able to use cargo to install the crate.

Simple usage.

The simpliest way to use this crate is to open a TcpStream and read/write INDI commands.

Example
use std::net::TcpStream;
use indi::client::ClientConnection;

fn main() {
    // Connect to local INDI server.
    let connection = TcpStream::connect("127.0.0.1:7624").expect("Connecting to INDI server");

    // Write command to server instructing it to track all properties.
    connection.write(&indi::serialization::GetProperties {
        version: indi::INDI_PROTOCOL_VERSION.to_string(),
        device: None,
        name: None,
    })
    .expect("Sending GetProperties command");

    // Loop through commands recieved from the INDI server
    for command in connection.iter().expect("Creating iterator over commands") {
        println!("Received from server: {:?}", command);
    }
}

Using the Client interface

The simple usage above has its uses, but if you want to track and modify the state of devices at an INDI server it is recommended to use the client interface. The client allows you to get devices, be notified of changes to those devices, and request changes.

Example
use std::time::Duration;
use std::net::TcpStream;

#[tokio::main]
async fn main() {
    // Create a client with a connection to localhost listening for all device properties.
    let client = indi::client::new(
        TcpStream::connect("127.0.0.1:7624").expect("Connecting to INDI server"),
        None,
        None).expect("Initializing connection");

    // Get an specific camera device
    let camera = client
        .get_device::<()>("ZWO CCD ASI294MM Pro")
        .await
        .expect("Getting camera device");

    // Setting the 'CONNECTION' parameter to `on` to ensure the indi device is connected.
    camera
        .change("CONNECTION", vec![("CONNECT", true)])
        .await
        .expect("Connecting to camera");

    // Enabling blob transport for the camera.  
    camera
        .enable_blob(Some("CCD1"), indi::BlobEnable::Also)
        .await
        .expect("Enabling image retrieval");

    // Configuring a varienty of the camera's properties at the same time.
    tokio::try_join!(
        camera.change("CCD_CAPTURE_FORMAT", vec![("ASI_IMG_RAW16", true)]),
        camera.change("CCD_TRANSFER_FORMAT", vec![("FORMAT_FITS", true)]),
        camera.change("CCD_CONTROLS", vec![("Offset", 10.0), ("Gain", 240.0)]),
        camera.change("FITS_HEADER", vec![("FITS_OBJECT", "")]),
        camera.change("CCD_BINNING", vec![("HOR_BIN", 2.0), ("VER_BIN", 2.0)]),
        camera.change("CCD_FRAME_TYPE", vec![("FRAME_FLAT", true)]),
        )
        .expect("Configuring camera");

    // Capture a 5 second exposure from the camera
    let fits = camera.capture_image(Duration::from_secs(5)).await.expect("Capturing image");

    // Save the fits file to disk.
    fits.save("flat.fits").expect("Saving image");
}

Modules

Structs

Enums

Statics

Traits