@@ -182,7 +182,7 @@ class Device(object):
182
182
property_names = {"device_properties" : ["added_properties" ]}
183
183
)
184
184
def __init__ (self ,name ,parent_device ,connection , call_parents_add_device = True ,
185
- added_properties = {}, ** kwargs ):
185
+ added_properties = {}, gui = None , worker = None , ** kwargs ):
186
186
# Verify that no invalid kwargs were passed and the set properties
187
187
if len (kwargs ) != 0 :
188
188
raise LabscriptError ('Invalid keyword arguments: %s.' % kwargs )
@@ -230,6 +230,33 @@ def __init__(self,name,parent_device,connection, call_parents_add_device=True,
230
230
231
231
# Add self to the compiler's device inventory
232
232
compiler .inventory .append (self )
233
+
234
+ # handle remote workers/gui interface
235
+ if gui is not None or worker is not None :
236
+ # remote GUI and worker
237
+ if gui is not None :
238
+ # if no worker is specified, assume it is the same as the gui
239
+ if worker is None :
240
+ worker = gui
241
+
242
+ # check that worker and gui are appropriately typed
243
+ if not isinstance (gui , _RemoteConnection ):
244
+ raise LabscriptError ('the "gui" argument for %s must be specified as a subclass of _RemoteConnection' % (self .name ))
245
+ else :
246
+ # just remote worker
247
+ gui = compiler ._PrimaryBLACS
248
+
249
+ if not isinstance (worker , _RemoteConnection ):
250
+ raise LabscriptError ('the "worker" argument for %s must be specified as a subclass of _RemoteConnection' % (self .name ))
251
+
252
+ # check that worker is equal to, or a child of, gui
253
+ if worker != gui and worker not in gui .get_all_children ():
254
+ print gui .get_all_children ()
255
+ raise LabscriptError ('The remote worker (%s) for %s must be a child of the specified gui (%s) ' % (worker .name , self .name , gui .name ))
256
+
257
+ # store worker and gui as properties of the connection table
258
+ self .set_property ('gui' , gui .name , 'connection_table_properties' )
259
+ self .set_property ('worker' , worker .name , 'connection_table_properties' )
233
260
234
261
235
262
# Method to set a property for this device.
@@ -248,7 +275,7 @@ def set_property(self, name, value, location=None, overwrite=False):
248
275
if location is None or location not in labscript_utils .properties .VALID_PROPERTY_LOCATIONS :
249
276
raise LabscriptError ('Device %s requests invalid property assignment %s for property %s' % (self .name , location , name ))
250
277
251
- # if this try failes then self."location" may not be instantiated
278
+ # if this try fails then self."location" may not be instantiated
252
279
if not hasattr (self , "_properties" ):
253
280
self ._properties = {}
254
281
@@ -431,29 +458,32 @@ def init_device_group(self, hdf5_file):
431
458
return group
432
459
433
460
434
- class _RemoteBLACSConnection (Device ):
435
- delimeter = '|'
436
-
461
+ class _PrimaryBLACS (Device ):
462
+ pass
463
+
464
+ class _RemoteConnection (Device ):
437
465
@set_passed_properties (
438
466
property_names = {}
439
467
)
440
- def __init__ (self , name , external_address ):
441
- Device .__init__ (self , name , None , None )
442
- # this is the address:port the parent BLACS will connect on
443
- self .BLACS_connection = str (external_address )
444
-
445
- def __call__ (self , port ):
446
- """ This modifies the connection string so that a parent BLACS knows not to instantiate it directly"""
447
- return '%s%s%s' % (self .name , self .delimeter , port )
448
-
449
-
450
- class RemoteWorkerBroker (_RemoteBLACSConnection ):
451
- pass
452
-
453
-
454
- class SecondaryControlSystem (_RemoteBLACSConnection ):
455
- pass
456
-
468
+ def __init__ (self , name , parent = None , connection = None ):
469
+ if parent is None :
470
+ # define a hidden parent of top level remote connections so that
471
+ # "connection" is stored correctly in the connection table
472
+ if compiler ._PrimaryBLACS is None :
473
+ compiler ._PrimaryBLACS = _PrimaryBLACS ('__PrimaryBLACS' , None , None )
474
+ parent = compiler ._PrimaryBLACS
475
+ Device .__init__ (self , name , parent , connection )
476
+
477
+
478
+ class RemoteBLACS (_RemoteConnection ):
479
+ def __init__ (self , name , host , port = 7340 , parent = None ):
480
+ _RemoteConnection .__init__ (self , name , parent , "%s:%s" % (host , port ))
481
+
482
+
483
+ class SecondaryControlSystem (_RemoteConnection ):
484
+ def __init__ (self , name , host , port , parent = None ):
485
+ _RemoteConnection .__init__ (self , name , parent , "%s:%s" % (host , port ))
486
+
457
487
458
488
class IntermediateDevice (Device ):
459
489
@@ -1944,6 +1974,11 @@ def generate_connection_table(hdf5_file):
1944
1974
else :
1945
1975
BLACS_connection = ""
1946
1976
1977
+ #if there is no BLACS connection, make sure there is no "gui" or "worker" entry in the connection table properties
1978
+ if 'worker' in properties or 'gui' in properties :
1979
+ raise LabscriptError ('You cannot specify a remote GUI or worker for a device (%s) that does not have a tab in BLACS' % (device .name ))
1980
+
1981
+
1947
1982
connection_table .append ((device .name , device .__class__ .__name__ ,
1948
1983
device .parent_device .name if device .parent_device else str (None ),
1949
1984
str (device .connection if device .parent_device else str (None )),
@@ -2241,6 +2276,7 @@ def labscript_cleanup():
2241
2276
compiler .trigger_duration = 0
2242
2277
compiler .wait_delay = 0
2243
2278
compiler .time_markers = {}
2279
+ compiler ._PrimaryBLACS = None
2244
2280
2245
2281
class compiler :
2246
2282
# The labscript file being compiled:
@@ -2258,6 +2294,7 @@ class compiler:
2258
2294
trigger_duration = 0
2259
2295
wait_delay = 0
2260
2296
time_markers = {}
2297
+ _PrimaryBLACS = None
2261
2298
2262
2299
# safety measure in case cleanup is called before init
2263
2300
_existing_builtins_dict = _builtins_dict .copy ()
0 commit comments