BLACS lock monitor plugin

80 views
Skip to first unread message

Rohit Prasad Bhatt

unread,
Jul 13, 2023, 12:51:09 PM7/13/23
to 'Philip Starkey' via The labscript suite
Hi all,
I am trying to use the lock monitor plugin in BLACS [https://github.com/zakv/blacs/tree/lock-monitor/blacs/plugins].

I was able to load a dummy lock monitor in BLACS. Now I would like to use it to do two tasks:
1. The callback_pre_transition_to_buffered() functions checks if the experiment queue is not paused and all BLACS devices are error free.
2. If the queue is paused due to some devices in error state, the plugin restarts all devices which have error and resumes the queue execution.

For this, I started by trying to access the manager_paused variable of BLACS but I do not see how I can access it. I think once this problem is solved then accessing the device names and their error states should be similar.

So how can I access these BLACS attributes and (functions for restarting the devices etc.) from with my plugin?

Regards,
Rohit Prasad Bhatt

Zak V

unread,
Jul 14, 2023, 10:15:19 PM7/14/23
to the labscript suite
Hi Rohit,

Glad to hear that others are interested in lock monitor and good to know you were able to get the dummy lock monitor to work!

Although I made that plugin, it's been a while since I've used labscript so my memory is a bit hazy. But naively I'd think that if the blacs experiment queue is paused then blacs will sit in manual mode and won't reach the point where it executes the pre-transition-to-buffered callbacks. In fact, after a brief glance at the code, it looks like this continue statement is executed if the queue is paused, which causes it to skip past where the pre-transition-to-buffered callbacks happen. That continue statement makes blacs jump back to the top of this while loop a few lines above it. So it looks to me like no callbacks are ever execute while the queue is paused.

I'm not sure of the best way to achieve your goal of automatically restarting errored devices. One possibility might be to modify blacs to add a new place for plugin callbacks before that continue statement. Then you could write a plugin which would have access to the blacs application data via its `self.BLACS` attribute, and that would allow you to access `manager_paused` while blacs is paused in manual mode. Another workaround might be to make a plugin which starts a thread to periodically check for errored devices and restart them, though it would probably be difficult - if not impossible - to do that in a way which robustly works with blacs state machine (since that approach is more-or-less just a way to circumvent the state machine). Maybe some labscript pros will have better suggestions.

Cheers,
Zak

Rohit Prasad Bhatt

unread,
Jul 23, 2023, 8:48:06 AM7/23/23
to 'Philip Starkey' via The labscript suite
Hi Zak,
Yes that is actually a problem that BLACS will sit in manual mode and so the plugin callback won't be executed. So I would like to share our hacky current solution. We run a separate python script which keeps sending some query strings to BLACS. This is possible because BLACS is running a server. Then we modify BLACS code to execute a function once we receive specific strings. This function has the code to check the whether BLACS is paused, restart devices etc. I also put some boilerplate code below in case someone else finds it useful.

 

So we have a script that sends query strings to BLACS. Its code looks like:

****************************

import blacs

blacs.send_query_string(query_string = 'restart_all_devices')

****************************

 

Then in the __init__.py  file of BLACS we define the function send_query_string():

****************************

def send_query_string(host='localhost', port=42517, timeout=5, query_string = 'get_queue_status'):

    return zmq_get(port, host, query_string, timeout)

****************************

 

Next we add/edit some code in the class ExperimentServer(ZMQServer) of the __main__.py  file of BLACS.

****************************

def handler(self, h5_filepath=None):

              if h5_filepath in ['get_queue_status','restart_all_devices']:

                             return self.resolve_external_request(h5_filepath)

              print(h5_filepath)

              message = self.process(h5_filepath)

              logger.info('Request handler: %s ' % message.strip())

              return message

 

@inmain_decorator(wait_for_return=True)

def resolve_external_request(self,query_string):

              if query_string == 'get_queue_status':

                             return app.queue.manager_paused

              if query_string == 'restart_all_devices':

                             app.tablist['intermediate_device'].restart()#Put the name of the device you want to restart

                             return 'restarted'

              return 'Hello'

****************************

             

So we misuse the 'h5_filepath' argument of the handler function to check if it matches any of the predefined query strings. If yes, a function called resolve_external_request() is executed which can perform actions depending on the string received. This function has access to BLACS object app so it can access the queue and devices as the object attributes. Also note that this function needs to be run in the main thread so it has the @inmain_decorator(wait_for_return=True) decorator.

Regards,
Rohit Prasad Bhatt

--
You received this message because you are subscribed to the Google Groups "the labscript suite" group.
To unsubscribe from this group and stop receiving emails from it, send an email to labscriptsuit...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/labscriptsuite/1be0ed0d-19cd-4199-a3dd-61744d71cbffn%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages