#protocols #devices #client-connection #astronomical #network-protocol #equipment #networking

indi

Client library for interfacing with the Instrument Neutral Distributed Interface (INDI) protocol

7 releases (stable)

3.2.0 Dec 4, 2023
3.0.1 Jun 9, 2023
3.0.0 May 2, 2023
2.0.0 Mar 15, 2023
0.1.0 Dec 14, 2022

#4 in #equipment

32 downloads per month

MIT/Apache

135KB
3.5K SLoC

indi

This crate provides support for the Instrument Neutral Distributed Interface (INDI) network protocol used to provide a network interface into controlling astronomical equipment. See; https://www.indilib.org/index.html for more details on INDI.

For documentation see: https://docs.rs/indi/

Contributing

Contributions are welcome.

In general, we follow the "fork-and-pull" Git workflow.

  1. Fork the repo on GitHub
  2. Clone the project to your own machine
  3. Commit changes to your own branch
  4. Push your work back up to your fork
  5. Submit a Pull request so that we can review your changes

NOTE: Be sure to merge the latest from "upstream" before making a pull request!


lib.rs:

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");
}

Dependencies

~32MB
~488K SLoC