Developer's guide to event callbacks in seestar_alp - smart-underworld/seestar_alp GitHub Wiki
This write-up is intended for developers, to describe how to make use of the newly added functionality in seestar_alp, that allows for actions to be taken in a reaction to events, rather than a timed schedule.
An event callback is a class, based off of the abstract class EventCallback
, defined in device/event_callbacks.py
Child classes implementing this interface must implement 3 things:
- Initialization
- Define what events to take action on
- Define what to do when these events occur.
The intent is to initialize the callback class from the current device state at start time, and all future action should be based off of events, or inspecting the current state of the device object. All efforts should be made to avoid costly calls back out to the scope.
This is meant to be a passive callback system that reacts to the events being reported by the scope. Think of it as a "push" system vs a "pull", or "poll" system.
Callbacks are registered with the system, and initialized in seestar_device.py
in a method named event_callbacks_init
This gets called from start_watch_thread
at device (re)connnect time.
After that point, the callback classes should wait for their eventFired
call to be executed.
We have 2 general categories of callbacks at this time:
-
Specific code-based subclasses to do specific things
These callbacks have access to the internals of the device context, so can make changes to ALP state.
-
User supplied "script" based hooks, that get executed by the system
These scripts get passed some context, like event details, and what device it occurred on, but cannot make changes to the internals of ALP state. These hooks are defined in a top-level directory from seestar_alp, named
user_hooks
More details are in the
callback class types
section below.
In seestar_device.py
, we monitor the open connection to the scope for messages it sends to ALP, in the receive_message_thread_fn
method.
In that method, we handle both jsonrpc
- and Event
message types.
- Any event sent from the SeeStar Eg:
{'Event': 'PiStatus', 'Timestamp': '5804.822674860', 'temp': 43.099998}
- Event wildcard special-case:
event_*
At the time of this writing, there are 2 active callback types, and 1 in development:
This is intended to expand over time, as we identify additional use cases. Several have been proposed, and should be worked on as time allows. The intent of this guide is to make this infrastructure something that any developer could add to.
A callback class to watch battery levels, so we can do a safe shutdown if the battery gets too low
This callback class monitors the state of the battery, and will safely shutdown the scope, if it goes below a certain level. This has the advantage of running through the process to properly park the scope, if imaging below-horizon targets
A callback class to watch the sensor temp, and re-take darks if if changes more than a set value.
When merged, this event will optionally
- pause imaging
- re-take darks
- resume imaging
As mentioned above, UserScriptEvents are initialized from the user_hooks subdir. The system will process files with a .conf
or a .hcon
extension. All others (like .example
) are ignored.
The format for these hooks are in HOCON format - a superset of JSON
An example hook might look like the following:
events: ["PiStatus"]
execute: "./local/run"
When initialized, this hook will be executed when the PiStatus
event is encountered.
It will execute the ./local/run
script, with the following environment variables supplied to it:
DEVNUM=<device number>
DEVICENAME=<device name>
NAME=<event name>
EVENT_DATA=<json representation of event>