Adding to ACP's Logic

This page describes ways that you can add your own logic to ACP's image acquisition process using scripts and scriptlets. We could not possibly imagine all of the things that our customers might want to do, so we provided these scripting "hooks" to allow additions of almost anything at a given user site. Thus, you need to write your own script code to take advantage of these features. Here's what's covered:

Startup and Shutdown Scripts

If you put a script called ACP-Startup.xxx (xxx=vbs or js) in the same directory as ACP.exe, it will be automatically run when ACP starts up, after any auto actions you may have enabled in ACP preferences.

[historical, see next paragraph] Likewise, a script called ACP-Shutdown.xxx will be run when ACP shuts down before any auto actions you may have enabled in ACP preferences.

The ACP-Shutdown.xxx script isn't what is commonly wanted. Instead, most people are looking for a way to run custom shutdown code at the end of an observing plan. The "standard" actions taken when a #shutdown directive is at the end of an observing plan is often just fine, but sometimes more or different things are needed. There are two ways to do this:

  1. Use the Shutdown custom action as described below. This is OK when you have a limited amount of logic or when you want to use some of the routines in the AcquireSupport library. See the description below, just remember that returning a True will cause the standard shutdown logic to run after the logic in UserActions.
  2. End the observing plan with a #chainscript directive that loads and runs your full-function shutdown script (which can have any name and place on disk). This script will be run in the ACP scripting console, of course, so it will have access to all of ACP's API library.

Script Failure Script

If you put a script called ACP-ScriptFail.xxx (xxx=vbs or js) in the same directory as ACP.exe, it will be automatically run when any other script fails. If the failed script contains a call to Util.ChainScript(), the chained-to script will not be run, instead the ACP-ScriptFail script will be run. You can use this to notify you by email that a problem exists, or whatever. If the ACP-ScriptFail script fails, of course it will not be run again!
noteAborting a script from the ACP console or its web interface is not considered a script error. Thus, the fail script will not run when you abort a script.

Weather Safety Script

If you put a script called ACP-Weather.xxx (xxx=vbs or js) in the same directory as ACP.exe, it will be automatically run when ACP detects that the weather has become unsafe. You can use this to (at a minimum) park your scope and close your dome or roof. If you have turned on "Close and park/home when (or AFTER) scope is parked by script" (Dome tab of Preferences), then all your weather safety script needs to contain is:
Sub Main()
    Telescope.Park
End Sub

This will call the Telescope.Park method, and the auto-home/close logic will take care of your dome. The logic in Telescope.Park tries its very best to assure that your scope is parked before closing the shutter or roof.

noteThe above simple script is included with ACP. Under most circumstances, all you need to do is set the Dome preferences for your dome or roof, and weather alerts will be handled.

noteNote that ACP itself handles stopping any FocusMax or PWI focus in progress at the end of any script.

Custom Actions (expert feature)

Any ACP script that uses the support library AcquireSupport.wsc, including the standard image acquisition script AcquireImages.js, can call out to user-written script snippets (scriptlets). This powerful feature, custom actions, enables ACP to meet virtually any special need(s) without having to modify the standard scripts or the scripting support library (or ACP itself, of course!). Scriptlets are called for all of the following events: To use this feature, you need to insert your custom script actions (scriptlets) into a provided template Windows Script Component (WSC) called UserActions.wsc. This file contains the framework for the WSC, and stubbed-out implementations for each of the above actions. All functions except ScriptEnd() must return a Boolean (true/false) value. Returning False will stop the script with an error message. If you return False, you should log the reason in the console log in your code.
noteTo activate this feature, you must activate UserActions.wsc (see next section). Once registered, you will see "User actions detected" in your run logs, and the functions will be called during each invocation of a script. To deactivate this feature, unregister UserActions.wsc. For more information, look at the UserActions.wsc file itself with Notepad.

Activating UserActions (registering with Windows)

By default ACP does not "see" this component and its member functions. To activate it for ACP it must be registered with the Windows OS. On Windows 7 and later, with User Account Control enabled (the default for those versions of Windows), this is a real pain. You need to have a 32-bit command (CMD) window running in administrator mode. It's different on 32- and 64 bit systems, and with UAC off (common on Observatory control computers) you don't need to mess with administrator mode. So:

64 bit, UAC on:

  1. Find C:\Windows\SysWOW64\cmd.exe
  2. Right-click, select Run as Administrator
  3. ...> CD "\Program Files (x86)\ACP Obs Control" (note quotes)
  4. ...> regsvr32 UserActions.wsc

64 bit, UAC off:

  1. Find C:\Windows\SysWOW64\cmd.exe
  2. Double-click it
  3. ...> CD "\Program Files (x86)\ACP Obs Control" (note quotes)
  4. ...> regsvr32 UserActions.wsc

32 bit, UAC on:

  1. Find C:\Windows\System\cmd.exe
  2. Right-click, select Run as Administrator
  3. ...> CD "\Program Files\ACP Obs Control" (note quotes)
  4. ...> regsvr32 UserActions.wsc

32 bit, UAC off:

  1. Find C:\Windows\System\cmd.exe
  2. Double-click it
  3. ...> CD "\Program Files\ACP Obs Control" (note quotes)
  4. ...> regsvr32 UserActions.wsc

If you see a success popup, it's ready to go. If you see a failure popup, there is a mistake in the code or XML.

Accessing the Running Script

From within your custom actions, you can access methods and properties of the running script. To access these items, use the following syntax:
  Util.Script.xxx
Any method, and all variables defined outside the scope of a property or method implementation, in the running script are accessible this way. For example, the standard AcquireImages.js script contains a variable called targetName, which contains the name of the target currently being acquired.
noteDon't modify the value of any script variables unless you know exactly what you're doing.

Accessing the AcquireSupport Library

From within your custom actions, you can use any of the properties and methods of the AcquireSupport library. To access these items, use the following syntax:
  Util.Script.SUP.property-or-method
All of ACP's standard scripts define a global variable SUP which is the handle to the initialized AcquireSupport library. Thus, using the running-script access syntax described in the previous section, you can access AcquireSupport. It is chock full of useful methods, and its properties can be used to learn a lot about the running script. Have a look at AcquireSupport.wsc with a text editor. It is a Windows Script Component, so using PrimalScript will make looking at it easier.
noteDon't modify the value of any of AcquireSupport's properties unless you know exactly what you're doing.

Debugging Custom Actions

The simplest way to debug custom user actions is via MsgBox() statements within your code. Be sure to remove them before going into production, though! Otherwise your observing work will stop if one of them are displayed, requiring you to click OK to proceed.

There are also a couple of additional levels of debugging available. User Actions are contained within a supplied template Windows Script Component (WSC), which is "known" to ACP's standard scripts. Once enabled the functions in UserActions.wsc are automatically called by ACP at the appropriate times during ACP's standard script execution cycles.

For general information on WSCs see Reusable Code, where you will find information about the Error Switch and the Debug Switch. Each of these switches is in the XML framework of UserActions.wsc and may be edited with Notepad, etc. Their function is also explained in this section of ACP help. By using the Error Switch and/or Debug Switch, you can cause UserActions.wsc to pop up an error message if any run-time error occurs. By using the Debug Switch, you can cause UserActions to invoke your script debugger on a Stop (VBS) or debugger (JS) statement, or any run time error.

For information on how to install and use Visual Studio 2006/2008/2010 etc. or the Microsoft Office Script Debugger (recommended) see Debugging.

ACP vs Scheduler

When you are running "live" under ACP (AcquireImages or live observing on the web, same thing) the parameters to TargetStart(), TargetEnd(), AcquireImage() and ImageComplete() will differ. See the comments for each of these functions in template UserActions. YOu can tell if you are running under ACP by testing if you can get the boolean Util.Script.RESUMEPLAN. If it returns a value and doesn't raise an error, then you are running under ACP. With this it is possible to have logic in the UserActions that runs under either ACP or Scheduler, depending.

Slew Start Function

The SlewStart() function is called with parameters that contain the J2000 equatorial coordinates of the slew destination. You could use these, for example, to perform special safety tests before each slew. Returning False will stop the script with an error.

Acquire Image Function

The AcquireImage() function provides a way to completely replace the normal final/data image acquisition process. When called, any pending autofocus will have been completed and the scope will be pointed at the target (via a pointing update as needed). The implementation of AcquireImage is responsible for everything related to acquiring the image including any needed flip (for image duration), filter selection, focus shifs for same, handling of the guider, and acquisition of the image. The function can return True to indicate that it wants the normal image acquisition process to be done by ACP's logic, False to cause the entier run to be terminated, or "ok" to cause ACP to skip its image acquisition logic and proceed to the next image (within a count, repeat or target loop). In other words, this function handles a single image within the flow of ACP image acquisition process. Consider using a $TAG directive to allow the function to decide whether it should handle the current image or defer to ACP's normal logic. When using from Scheduler, you could put a special string into the Description field of the ImageSet or Observation to trigger this.

Image Start Function

The ImageStart() function is called with parameters that allow you to modify the image acquisition. The exposure interval, binning, and sub frame fraction can be altered, resulting in a change from the parameters specified in the plan or script that is doing the image acquisition. Two other parameters which must not be changed specify the filter that is selected and whether or not this is a pointing exposure. You can tell what type of exposure it is by looking at the exposure interval. It is positive for lights, 0 for biases, and negative for darks.

One way to use this feature is to alter the exposure interval to compensate for a filter's transmissivity when doing a pointing exposure. When combined with the Filter Info feature, you could use the selected imaging filter for pointing exposures as well. You could also force pointing exposures to be acquired at binning levels other than the default chosen by ACP.

Image End Function

The ImageEnd() function is special. It is called with a parameter that is the full path/name of the final (closed) image file. With this information, you could apply special post-processing of the image. For example, you could mail the file to a user, or extract science information using a program such as IRAF or the PinPoint engine, etc. Scripts can start shell programs such as IRAF and pass command line parameters to same (see documentation on the WScript.Shell object in the Windows Script 5.6 documentation). Do not rename or move the image file in this action! Use the ImageComplete() function described in the next section.

Image Complete Function

The ImageComplete() function is called with a parameter that is the full path/name of the final (closed) image file, after all post-acquisition processing has been completed. It may have been plate-solved and/or calibrated. This event allows you to (among other things) change the final file path/name of the just-acquired and processed image.

Target Start Function

The TargetStart() function is called with parameters that allow you to examine or modify virtually anything about the upcoming target. You could use this function, for example, to offset from the given coordinates or alter the name. Returning False will stop the script with an error.

Target End Function

The TargetEnd() function is called with parameters that allow you to examine virtually anything about the just-finished target and do some post-acquisition task, then decide whether or not to continue acquisition, and even start a new observing run. Returning False will stop the script with an error.

Shutdown Function

The Shutdown() function is called when an ACP plan uses the #shutdown directive, or when any script calls the Shutdown() method of the AcquireSupport library. This can be used to override or augment the default observatory shutdown logic. If this method returns True, the default logic is skipped, otherwise the default logic is executed after the logic in the custom action. This is not the same as the ACP Shutdown script, which runs when ACP itself is shut down.

Migrating if New Actions are Added

Occasionally, upgrades to ACP will add new user actions. When this happens, you must merge your custom action code into the new template, as the new actions must exist as methods in your UserActions.wsc. The ACP installer always creates a file UserActionsTemplate.wsc which contains the current set of user actions. To migrate, you have two choices. Which one you use depends on your comfort level:

  1. Copy your custom code from your current UserActions.wsc into the same methods in the UserActionsTemplate.wsc, then save UserActionsTemplate.wsc over the top of your UserActions.wsc. This will upgrade your UserActions.wsc.
  2. Look at UserActionsTemplate.wsc and note any newly added methods. Add them to the interface section (XML) of your UserActions.wsc, and add the corresponding template method code to your UserActions.wsc. This will also upgrade your UserActions.wsc.

Example: Saving "prettified" PNG image for each FITS image

This uses the ImageComplete() function to open then apply some simple processing steps to the FITS image (which has already been saved to disk, right?) and then create a PNG image with the same name in the same folder. This is a great addition to ACP when it's being used by young people for whom you are trying to engage for art or science astronomy. They can download and immediately see a pleasing image of the object they just photographed with your observatory. I encourage you to work with JavaScript as it is the world's most widely used language now, so your skills will transfer. Here's how to add this via the UserActions hooks provided with ACP:

  1. Copy the file UserActionsJS-template.wsc to UserActions.wsc
  2. Edit UserActions.wsc with Notepad or your favorite ASCII/ANSI/UTF-8 text editor. Do not use a Unicode editor or Word.
  3. Locate the ImageComplete() function and fill it in with the following code. The best way is to copy from here and paste into the editor at the right place:
    function ImageComplete(ImageFile)
    {
        var D = new ActiveXObject("MaxIm.Document");
        var pfn = ImageFile.replace(/\.fts/, ".png");
        D.OpenFile(ImageFile);
        D.KernelFilter(5, 20);
        D.DDP(0, true, true, 0, 0, 100);
        D.RemoveGradient();
        D.SaveFile(pfn, 7, true, 0, 0);
        D.Close();                       // Important!
        D = null;
        return true;
    }
  4. Save the file in the text editor.
  5. Now activate UserActions.wsc according to the instructions above. Make sure you do it as shown if you have a 64-bit system.

After doing this, every image acquired will result in not only a FITS image but also a nice looking PNG image of the same name in the same folder.