Steps to writing an INDI client with libindiclient
1) Initialize INDI client, and connect to INDI server
struct indi_t *indi = indi_init(hostname, port);
2) Register a callback to be called when a specified device is discovered. 'devname' is the name of the INDI device to look for. 'device_cb' is a user-defined callback procedure. 'data' is any additional data to pass to the callback
indi_device_add_cb(indi, devname, device_cb, data);
3) Define the callback procedure. This will be called for each property on the chosen device as they appear. The indi_prop_t structure contains info about the property (name, type, value, etc).
void device_cb(struct indi_prop_t *iprop, void *data) {}4) Detect properties by name, and store the relevant property pointers for future use, or register callbacks when the property changes
...
if (iprop->type == INDI_PROP_BLOB) {
printf("Found BLOB property for camera %s\n", iprop->idev->name);
indi_prop_add_cb(iprop, camera_capture_cb, self);
}
...
if (strcmp(iprop->name, "CCD_BINNING") == 0) {
printf("Found CCD_BINNING for camera %s\n", iprop->idev->name);
binning_prop = iprop;
}
...5) Change the value of a property. indi_send() will send the change to the INDI server. it can send an entire property, or an individual element of the property.
For example: setting a switch:
if (strcmp(iprop->name, "CONNECTION") == 0) {
printf("Found CONNECTION for camera %s\n", iprop->idev->name);
indi_send(iprop, indi_prop_set_switch(iprop, "CONNECT", TRUE));
indi_prop_add_cb(iprop, connect_cb, self);
}setting a number:
indi_prop_set_number(coord_prop, "RA", ra);
indi_prop_set_number(coord_prop, "DEC", dec);
indi_send(coord_prop);
6) Read the value of a property. use the indi_prop_get() functions to fetch element values from a specified property:
double ra = indi_prop_get_number(coord_prop, "RA");
double dec = indi_prop_get_number(coord_prop, "DEC");
7) Working with BLOBs. First make sure to register a callback:
indi_prop_add_cb(blob_prop, camera_capture_cb, self);
Then enable BLOB reception:
indi_dev_enable_blob(ccd_dev, 1);
The callback will be called once the BLOB has been received, decoded and uncompressed (if needed):
void camera_capture_cb(struct indi_prop_t *iprop, void *data)
{
FILE *fh;
char str[80];
static int img_count;
//A BLOB can only have a single element
struct indi_elem_t *ielem = indi_find_first_elem(iprop);
//ielem->value.blob.fmt will normally be '.fits', or '.jpg'
sprintf(str, "test%03d%s", img_count++, ielem->value.blob.fmt);
printf("Writing: %s\n", str);
fh = fopen(str, "w+");
fwrite(ielem->value.blob.data, ielem->value.blob.size, 1, fh);
fclose(fh);
}Undocumented functions
extern struct indi_device_t *indi_find_device(struct indi_t *indi, const char *dev);
extern struct indi_prop_t *indi_find_prop(struct indi_device_t *idev, const char *name);
extern struct indi_elem_t *indi_find_elem(struct indi_prop_t *iprop, const char *name);
extern struct indi_elem_t *indi_find_first_elem(struct indi_prop_t *iprop);
extern const char *indi_get_string_from_state(int state);
extern void indi_prop_add_signal(struct indi_prop_t *iprop, void *object, unsigned long signal);
extern void indi_prop_set_signals(struct indi_prop_t *iprop, int active);
extern void indi_send(struct indi_prop_t *iprop, struct indi_elem_t *ielem );
extern void indi_prop_add_cb(struct indi_prop_t *iprop,
void (* prop_update_cb)(struct indi_prop_t *iprop, void *callback_data),
void *callback_data);
extern void indi_device_add_cb(struct indi_t *indi, const char *devname,
void (* new_prop_cb)(struct indi_prop_t *iprop, void *callback_data),
void *callback_data);
extern int indi_prop_get_switch(struct indi_prop_t *iprop, const char *elemname);
extern struct indi_elem_t *indi_prop_set_switch(struct indi_prop_t *iprop, const char *elemname, int state);
extern double indi_prop_get_number(struct indi_prop_t *iprop, const char *elemname);
extern struct indi_elem_t *indi_prop_set_number(struct indi_prop_t *iprop, const char *elemname, double value);
extern struct indi_elem_t *indi_prop_set_string(struct indi_prop_t *iprop, const char *elemname, const char *value);
extern struct indi_elem_t *indi_dev_set_string(struct indi_device_t *idev, const char *propname, const char *elemname, const char *value);
extern struct indi_elem_t *indi_dev_set_switch(struct indi_device_t *idev, const char *propname, const char *elemname, int state);
extern void indi_dev_enable_blob(struct indi_device_t *idev, int state);