Author Topic: A simple INDIClient scripting test  (Read 5126 times)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
A simple INDIClient scripting test
« on: 2016 May 20 04:20:17 »
Hi all,

Here is a simple script to demonstrate the scripting capabilities of the new INDIClient module:

Code: [Select]
/*
 * PixInsight INDIClient module scripting example.
 */

// Name and port of a working INDI server.
#define SERVER_HOST_NAME   "localhost"
#define SERVER_PORT        7624

// Name of the camera device.
#define CCD_DEVICE_NAME    "CCD Simulator"

// Maximum waiting time in seconds.
#define MAX_WAIT_SECONDS   10

function INDITest()
{
   this.__base__ = Object;
   this.__base__();

   this.deviceController = new INDIDeviceController;
   this.deviceController.serverHostName = SERVER_HOST_NAME;
   this.deviceController.serverPort = SERVER_PORT;
   
   this.cameraController = new INDICCDFrame;
   this.cameraController.deviceName = CCD_DEVICE_NAME;

   this.timer = new ElapsedTime;

   this.connectToServer = function()
   {
      // Connect to INDI server
      this.deviceController.serverConnect = true;
      this.executeController();

      // Wait until device names are received from server
      for ( this.restartTimer(); !this.timeout(); )
      {
         msleep( 100 );
         processEvents();
         this.executeController();
         if ( this.indexOfDevice( this.deviceController.devices, CCD_DEVICE_NAME ) >= 0 )
            break;
      }

      // Connect to CCD device
      let propertyKey = "/" + CCD_DEVICE_NAME + "/CONNECTION/CONNECT";
      this.deviceController.newProperties = [[propertyKey, "INDI_SWITCH", "ON"]];
      this.deviceController.serverCommand = "SET";
      this.executeController();
      this.deviceController.serverCommand = "";

      // Wait until device is connected
      this.deviceController.serverCommand = "GET";
      this.deviceController.getCommandParameters = propertyKey;
      for ( this.restartTimer(); !this.timeout(); )
      {
         msleep( 100 );
         processEvents();
         this.executeController();
         if ( this.deviceController.getCommandResult == "ON" )
            break;
      }
      this.deviceController.serverCommand = "";
   };

   this.disconnectFromServer = function()
   {
      this.deviceController.serverConnect = false;
      this.executeController();
   };

   this.acquireImages = function()
   {
      return this.cameraController.executeGlobal();
   };

   // Private helper methods

   this.executeController = function()
   {
      if ( !this.deviceController.executeGlobal() )
         throw new Error( "Failure to execute INDIDeviceController." );
   };

   this.restartTimer = function()
   {
      this.timer.reset();
   };

   this.timeout = function()
   {
      if ( this.timer.value > MAX_WAIT_SECONDS )
         throw new Error( "INDIDeviceController: Timeout reached." );
      return false;
   };

   this.indexOfDevice = function( deviceTable, deviceName )
   {
      for ( let row = 0; row < deviceTable.length; ++row )
         if ( deviceTable[row][0] == deviceName )
            return row;
      return -1;
   };
};

INDITest.prototype = new Object;

//

function main()
{
   let indi = new INDITest;
   indi.connectToServer();
   indi.cameraController.exposureTime = 2.0;
   indi.cameraController.autoStretch = true;
   indi.acquireImages();
   indi.disconnectFromServer();
}

main();

The script is just a bare-bones example to acquire a single two seconds exposure. Change the CCD_DEVICE_NAME macro value to the name of your favorite INDI camera device, and replace SERVER_HOST_NAME and SERVER_PORT as appropriate to see how well it works.

Worth mentioning bits:

- The INDIDeviceController process has a serverConnect Boolean property. If this property is set to true before executing the instance, it will connect to the INDI server specified by the INDIDeviceController.serverHostName and INDIDeviceController.serverPort properties, or remain in the same state if it is already connected. If the INDIDeviceController.serverConnect property is false, the instance will disconnect from the server if necessary.

- INDIDeviceController has a serverCommand property to perform a number of actions on device properties:

if INDIDeviceController.serverCommand == "GET", the instance will acquire the INDI device property element specified by its getCommandParameters property. See script lines 39 to 43 for an example.

if INDIDeviceController.serverCommand == "SET", the instance will attempt to send the new property element values specified by its newProperties property. See lines 46 to 56 for an example.

if INDIDeviceController.serverCommand == "SET_ASYNC", the action is the same as "SET", but the new property element will be sent asynchronously, that is, the instance will return immediately without verifying that the property was sent correctly and accepted by the server.

- Each time an instance of INDIDeviceController is executed with an active server connection, it loads all device names and properties currently seen by the INDI server automatically in INDIDeviceController.devices and INDIDeviceController.properties, respectively. So you can set INDIDeviceController.serverCommand = "" and execute the instance (with serverConnect = true) to acquire all device and property elements.

This is just a warming up example. Much more to come, including a complete documentation of INDIClient's scripting interface.
« Last Edit: 2016 May 20 04:32:11 by Juan Conejero »
Juan Conejero
PixInsight Development Team
http://pixinsight.com/