diff --git a/README.md b/README.md
index b2ff8c560566bb5c86bbd9903f9121b4bf706026..13743c85b3869178cbb3d8d66a38d9d084cacfeb 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ These are scripts for interfacing with the TMSS API.
 - `script/run_script_fe.sh` runs the `tmss_fe_test_observation.py` using the `config_fe.yaml`
 - `script/run_script_im.sh` runs the `tmss_im_test_observation.py` using the `config_im.yaml`
 
-Install the LOFAR TMSS client from https://git.astron.nl/ro/lofar_tmss_client
+Install the LOFAR TMSS client from https://git.astron.nl/tmss/lofar_tmss_client
 
 The scripts use a `login.yaml` file which should contain
 
diff --git a/tmss_cal_observation.py b/tmss_cal_observation.py
new file mode 100755
index 0000000000000000000000000000000000000000..3fad5b6f8e523e119a8c60378b94b633809fd7f6
--- /dev/null
+++ b/tmss_cal_observation.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python3
+import os
+import sys
+import yaml
+import json
+import argparse
+from datetime import datetime, timedelta, UTC
+from math import ceil
+
+import astropy.units as u
+from astropy.coordinates import SkyCoord, get_icrs_coordinates
+
+from lofar_tmss_client.tmss_http_rest_client import TMSSsession
+
+from print_dict import print_dict
+
+if __name__ == "__main__":
+    # Read command line arguments
+    parser = argparse.ArgumentParser(description="Schedule station calibration observations in TMSS")
+    parser.add_argument("-s", "--source", help="Source to observe [str, default: Cas A]",
+                        default="Cas A", type=str)
+    parser.add_argument("-a", "--antennafield", help="Antenna field to select [str, default: HBA_DUAL]",
+                        default="HBA_DUAL", type=str)
+    parser.add_argument("-f", "--filter", help="Filter to select [str, default: HBA_110_190]",
+                        default="HBA_110_190", type=str)
+    parser.add_argument("-t", "--tstart", help="Time between start (isot) [str, default: now]",
+                        default=None, type=str)
+    parser.add_argument("-w", "--window", help="Time between window length (d) [float, default: 1]",
+                        default=1.0, type=float)
+    parser.add_argument("-L", "--stationlist", help="Station to use [str, default: CS001, can be multiple, e.g. \"CS001,CS002,CS003\"]",
+                        default="CS001", type=str)
+    parser.add_argument("-i", "--scheduling_set_id", help="Scheduling set ID [int, default: 395]",
+                        default=395, type=int)
+    parser.add_argument("-M", "--description", help="Observation description [str, example \"HBA station calibration\", default: \"HBA station calibration\"]",
+                        default="HBA station calibration", type=str)
+    parser.add_argument("-v", "--verbose", help="Provide detailed output",
+                        action="store_true")
+    parser.add_argument("-F", "--fixed_time", help="Fix observation start time (no dynamic scheduling)",
+                        action="store_true")
+    parser.add_argument("-u", "--upload", help="Upload specification document and create scheduling unit draft",
+                        action="store_true")
+    parser.add_argument("-b", "--blueprint", help="Blueprint uploaded scheduling unit draft",
+                        action="store_true")
+    parser.add_argument("-S", "--subbands", help="Inital subband configuration",
+                        default=[0], nargs='+', type=int)
+    parser.add_argument("-p", "--subband_step", help="Subband step size per integration",
+                        default=1, type=int)
+    parser.add_argument("-T", "--integration_time", help="Integration time per subband captured",
+                        default=1.0, type=float)
+    parser.add_argument("-N", "--num_cycles", help="Number of full subband cycles",
+                        default=1.0, type=float)
+    args = parser.parse_args()
+
+    # Settings
+    run_spec = {"strategy_name": "FE Stokes I - raw",
+                "description": args.description}
+    if args.fixed_time:
+        src_spec = {"name": args.source,
+                    "elev_min_deg": 00,
+                    "lst_min_s": -43200,
+                    "lst_max_s": 43200,
+                    "priority_queue": "A",
+                    "rank": 1.00}
+    else:
+        src_spec = {"name": args.source,
+                    "elev_min_deg": 30,
+                    "lst_min_s": -7200,
+                    "lst_max_s": 7200,
+                    "priority_queue": "A",
+                    "rank": 1.00}
+
+    # Get pointing
+    p = get_icrs_coordinates(args.source)
+    pointing = {"target": args.source,
+                "angle1": p.ra.rad,
+                "angle2": p.dec.rad,
+                "direction_type": "J2000"}
+                
+    # Start time
+    if args.tstart is None:
+        # Round to start of minute
+        tstart = datetime.now(UTC)
+    else:
+        tstart = datetime.strptime(args.tstart, "%Y-%m-%dT%H:%M:%S")
+    tend = tstart + timedelta(days=args.window) 
+    tstart = tstart.strftime("%Y-%m-%dT%H:%M:%S")
+    tend = tend.strftime("%Y-%m-%dT%H:%M:%S")
+        
+    # Station groups for Fly's Eye observations
+    stationlist = [item for item in args.stationlist.split(",")]
+    station_groups = [{"stations": [item],
+                       "max_nr_missing": 1} for item in stationlist]
+
+    # Check antenna field against LOFAR2.0 stations
+    if args.antennafield == "LBA_ALL":
+        if not set(stationlist) <= set(["CS001", "CS032", "RS307"]):
+            print("Can not use LBA_ALL on LOFAR stations. Exiting.")
+            sys.exit()
+
+    # Check if filter is compatible with antenna set
+    if ("LBA" in args.filter and "HBA" in args.antennafield) or ("HBA" in args.filter and "LBA" in args.antennafield):
+        print("Wrong combination of antennafield and filter selection. Exiting.")
+        sys.exit()
+
+    observation_time = int(ceil(args.integration_time * 512 * args.num_cycles / args.subband_step))
+    # Specify observing mode
+    mode =  {"stokes": "I",
+             "quantisation": {
+                 "bits": 8,
+                 "enabled": False,
+                 "scale_max": 5,
+                 "scale_min": -5,
+             },
+             "subbands_per_file": 488,
+             "channels_per_subband": 16,
+             "time_integration_factor": 512
+             }
+        
+    # Read credentials
+    with open("login.yaml", "r") as fp:
+        settings = yaml.full_load(fp)
+
+    # Open session
+    with TMSSsession(host=settings['host'],
+                     port=settings['port'],
+                     username=settings['username'],
+                     password=settings['password']) as client:
+        print("Opened TMSS connection")
+        
+        # Get the latest satellite monitoring template
+        template = client.get_scheduling_unit_observing_strategy_template(run_spec['strategy_name'])
+        print(f"Using strategy template {template['url']}")
+        
+        # Get the specifications document
+        original_spec_doc = client.get_scheduling_unit_observing_strategy_template_specification_with_just_the_parameters(template['name'], template['version'])
+
+        # Copy original specification document
+        spec_doc = original_spec_doc.copy()
+
+        if args.fixed_time:
+            spec_doc['scheduling_constraints_doc']['time']['at'] = f'{tstart}'
+            spec_doc['scheduling_constraints_doc']['scheduler'] = 'fixed_time'
+        else:
+            spec_doc['scheduling_constraints_doc']['time']['between'] = [{"from": tstart, "to": tend}]
+            spec_doc['scheduling_constraints_doc']['scheduler'] = 'dynamic'
+        spec_doc['scheduling_constraints_doc']['sky']['transit_offset']['from'] = src_spec['lst_min_s']
+        spec_doc['scheduling_constraints_doc']['sky']['transit_offset']['to'] = src_spec['lst_max_s']
+
+        spec_doc['tasks']['Observation']['specifications_doc']['duration'] = observation_time
+        spec_doc['tasks']['Observation']['short_description'] = src_spec["name"]
+        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['SAPs'] = [{"subbands": [200],
+                                                                                                   "digital_pointing": pointing}]
+        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['tile_beam'] = pointing
+        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['antenna_set'] = args.antennafield
+        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['filter'] = args.filter
+
+        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['station_groups'] = station_groups
+        spec_doc['tasks']['Observation']['specifications_doc']['beamformer']['pipelines'][0]['station_groups'] = station_groups
+        spec_doc['tasks']['Observation']['specifications_doc']['beamformer']['pipelines'][0]['flys eye']['settings'] = mode
+
+        spec_doc['tasks']['Observation']['specifications_doc']['QA']['XST'] = {"enabled": True,
+                                                                               "integration_interval": args.integration_time,
+                                                                               "subbands": args.subbands,
+                                                                               "subbands_step": args.subband_step}
+
+        # Show spec doc
+        if args.verbose:
+            print_dict(spec_doc, prefix="spec_doc")
+
+        # Skip if not uploaded
+        if not args.upload:
+            print("No scheduling units uploaded to TMSS.")
+            print()
+            sys.exit()
+
+        # Create scheduling unit
+        scheduling_unit_draft = client.create_scheduling_unit_draft_from_strategy_template(template['id'], args.scheduling_set_id, spec_doc, src_spec["name"], run_spec['description'], src_spec['priority_queue'], src_spec['rank'])
+
+        # Patch scheduling unit with keys that are not included in the strategy
+        print(f"Created SU draft {scheduling_unit_draft['id']} for {src_spec['name']} at {scheduling_unit_draft['url']}")
+
+        # Skip if not blueprinted
+        if not args.blueprint:
+            print("No scheduling units blueprinted.")
+            print()
+            sys.exit()
+
+        # Blueprint SU
+        scheduling_unit_blueprint = client.create_scheduling_unit_blueprint_and_tasks_and_subtasks_tree(scheduling_unit_draft['id'])
+        print(f"Created SU blueprint {scheduling_unit_blueprint['id']} for {src_spec['name']} at {scheduling_unit_blueprint['url']}")
+        
diff --git a/tmss_fe_observation.py b/tmss_fe_observation.py
index fa74441fca1fc2aaa4614ca4ae60bbbecc4c483b..18a17ad9d402cd3fe006154dee711ecb723da240 100755
--- a/tmss_fe_observation.py
+++ b/tmss_fe_observation.py
@@ -33,8 +33,8 @@ if __name__ == "__main__":
                         default="CS001", type=str)
     parser.add_argument("-i", "--scheduling_set_id", help="Scheduling set ID [int, default: 305]",
                         default=305, type=int)
-    parser.add_argument("-p", "--pointing", help="Override pointing [str, example: \"Zenith,0.0,1.5707963,AZELGEO\", default: None]",
-                        default=None, type=str)
+    parser.add_argument("-p", "--pointings", help="Override pointing (can be multiple) [str, example: \"Zenith,0.0,1.5707963,AZELGEO\", default: None]",
+                        default=None, type=str, action="append")
     parser.add_argument("-m", "--mode", help="Observing mode (I, IQUV or XXYY) [str, default: I]",
                         default="I", type=str)
     parser.add_argument("-D", "--downsamp", help="Downsampling factor for Stokes I observing [int, default: 16]",
@@ -45,6 +45,12 @@ if __name__ == "__main__":
                         default=1, type=int)
     parser.add_argument("-N", "--subbands_per_file", help="Number of subbands per file [int, default: 488 for mode I, 20 for mode XX]",
                         default=None, type=int)
+    parser.add_argument("-M", "--description", help="Observation description [str, example \"Test observation\", default: None, will use source name]",
+                        default=None, type=str)
+    parser.add_argument("-X", "--xst", help="XST settings (subband start, subband step, integration time) [str, example: \"194,0,1.0\", default: None]",
+                        default=None, type=str)
+    parser.add_argument("-v", "--verbose", help="Provide detailed output",
+                        action="store_true")
     parser.add_argument("-u", "--upload", help="Upload specification document and create scheduling unit draft",
                         action="store_true")
     parser.add_argument("-b", "--blueprint", help="Blueprint uploaded scheduling unit draft",
@@ -62,19 +68,40 @@ if __name__ == "__main__":
                 "rank": 1.00}
 
     # Get pointing
-    if args.pointing is None:
+    if args.pointings is None:
         p = get_icrs_coordinates(args.source)
-        pointing = {"target": args.source,
-                    "angle1": p.ra.rad,
-                    "angle2": p.dec.rad,
-                    "direction_type": "J2000"}
+        pointings = [{"target": args.source,
+                      "angle1": p.ra.rad,
+                      "angle2": p.dec.rad,
+                      "direction_type": "J2000"}]
+        tile_pointing = pointings[0]
     else:
-        parts = args.pointing.split(",")
-        pointing = {"target": parts[0],
-                    "angle1": float(parts[1]),
-                    "angle2": float(parts[2]),
-                    "direction_type": parts[3]}
-        src_spec["name"] = parts[0]
+        pointings = []
+        first = True
+        for point in args.pointings:
+            parts = point.split(",")
+            pointing = {"target": parts[0],
+                        "angle1": float(parts[1]),
+                        "angle2": float(parts[2]),
+                        "direction_type": parts[3]}
+            if first:
+                src_spec["name"] = parts[0]
+                tile_pointing = pointing
+                first = False
+            pointings.append(pointing)
+
+    # Get XST settings
+    if args.xst is not None:
+        parts = args.xst.split(",")
+        xst_spec = {"enabled": True,
+                    "subbands": [int(parts[0])],
+                    "subbands_step": int(parts[1]),
+                    "integration_interval": float(parts[2])}
+    else:
+        xst_spec = {"enabled": False,
+                    "subbands": [300],
+                    "subbands_step": 0,
+                    "integration_interval": 1.0}
         
     # Decode subbands
     if "," in args.subband:
@@ -89,7 +116,7 @@ if __name__ == "__main__":
         subband_list = [subband] * nsubband
     else:
         subband_list = [int(args.subband)]
-        
+
     # Start time
     if args.tstart is None:
         # Round to start of minute
@@ -115,6 +142,11 @@ if __name__ == "__main__":
         print("Wrong combination of antennafield and filter selection. Exiting.")
         sys.exit()
 
+    # Check if total number of subbands fits
+    if len(subband_list) * len(pointings) * args.saps > 488:
+        print("Too many subbands per pointing specified. Exiting.")
+        sys.exit()
+        
     # Subbands per file
     if args.subbands_per_file is not None:
         subbands_per_file = args.subbands_per_file
@@ -190,18 +222,25 @@ if __name__ == "__main__":
         spec_doc['scheduling_constraints_doc']['scheduler'] = 'fixed_time'
         spec_doc['scheduling_constraints_doc']['sky']['transit_offset']['from'] = src_spec['lst_min_s']
         spec_doc['scheduling_constraints_doc']['sky']['transit_offset']['to'] = src_spec['lst_max_s']
+        for source_constraint in ['sun', 'moon', 'jupiter']:
+            spec_doc['scheduling_constraints_doc']['sky']['min_distance']['target'][source_constraint] = 0
+            spec_doc['scheduling_constraints_doc']['sky']['min_distance']['calibrator'][source_constraint] = 0            
 
         spec_doc['tasks']['Observation']['specifications_doc']['duration'] = args.length
         spec_doc['tasks']['Observation']['short_description'] = src_spec["name"]
         saps = []
-        for isap in range(args.saps):
-            sap = {
-                "subbands": subband_list,
-                "digital_pointing": pointing
-            }
-            saps.append(sap)
+        idx = 0
+        for pointing in pointings:
+            for isap in range(args.saps):
+                sap = {
+                    "name": f"SAP{idx:03d}",
+                    "subbands": subband_list,
+                    "digital_pointing": pointing
+                }
+                saps.append(sap)
+                idx += 1
         spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['SAPs'] = saps
-        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['tile_beam'] = pointing
+        spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['tile_beam'] = tile_pointing
         spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['antenna_set'] = args.antennafield
         spec_doc['tasks']['Observation']['specifications_doc']['station_configuration']['filter'] = args.filter
 
@@ -209,9 +248,13 @@ if __name__ == "__main__":
         spec_doc['tasks']['Observation']['specifications_doc']['beamformer']['pipelines'][0]['station_groups'] = station_groups
         spec_doc['tasks']['Observation']['specifications_doc']['beamformer']['pipelines'][0]['flys eye']['settings'] = mode
 
-        # Show spec doc
-        print_dict(spec_doc, prefix="spec_doc")
+        if xst_spec["enabled"]:
+            spec_doc['tasks']['Observation']['specifications_doc']['QA']['XST'] = xst_spec
 
+        # Show spec doc
+        if args.verbose:
+            print_dict(spec_doc, prefix="spec_doc")
+            
         # Skip if not uploaded
         if not args.upload:
             print("No scheduling units uploaded to TMSS.")
diff --git a/tmss_format_l2json_commands.py b/tmss_format_l2json_commands.py
new file mode 100755
index 0000000000000000000000000000000000000000..478a6b79027720a79abd10a6475c331e4e313604
--- /dev/null
+++ b/tmss_format_l2json_commands.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+import sys
+import json
+import yaml
+import argparse
+
+from datetime import datetime, timedelta, UTC
+
+from lofar_tmss_client.tmss_http_rest_client import TMSSsession
+
+from print_dict import print_dict
+
+if __name__ == "__main__":
+    # Read command line arguments
+    parser = argparse.ArgumentParser(description="List tasks")
+    parser.add_argument("-p", "--project", help="Project to which tasks belong [str, default: COM_LOFAR2]",
+                        default="Calibration", type=str)
+    parser.add_argument("-s", "--tstart", help="Start time (isot) [str, default: now - 1 day]",
+                        default=None, type=str)
+    parser.add_argument("-e", "--tend", help="Start time (isot) [str, default: now]",
+                        default=None, type=str)
+    args = parser.parse_args()
+
+    task_type = "observation"
+    
+    # Start time
+    if args.tstart is None and args.tend is None:
+        tstart = (datetime.now(UTC) + timedelta(days=-1)).strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+        tend = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+    else:
+        tstart = datetime.strptime(args.tstart, "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+        tend = datetime.strptime(args.tend, "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+
+    # Read credentials
+    with open("login.yaml", "r") as fp:
+        settings = yaml.load(fp, Loader=yaml.FullLoader)
+
+    with TMSSsession(host=settings['host'],
+                     port=settings['port'],
+                     username=settings['username'],
+                     password=settings['password']) as client:
+
+        # Format URL
+        url = f"https://tmss.lofar.eu/api/task_blueprint?tags=&created_at_after=&created_at_before=&updated_at_after=&updated_at_before=&name=&description=&scheduled_start_time_after={tstart}&scheduled_start_time_before={tend}&scheduled_stop_time_after=&scheduled_stop_time_before=&actual_process_start_time_after=&actual_process_start_time_before=&actual_process_stop_time_after=&actual_process_stop_time_before=&actual_on_sky_start_time_after=&actual_on_sky_start_time_before=&actual_on_sky_stop_time_after=&actual_on_sky_stop_time_before=&process_start_time_after=&process_start_time_before=&process_stop_time_after=&process_stop_time_before=&on_sky_start_time_after=&on_sky_start_time_before=&on_sky_stop_time_after=&on_sky_stop_time_before=&on_sky_duration=&duration=&specified_on_sky_duration=&obsolete_since=&short_description=&specifications_doc=&specifications_template=&draft=&scheduling_unit_blueprint=&output_pinned=unknown&id=&id_min=&id_max=&scheduling_unit_blueprint_min=&scheduling_unit_blueprint_max=&scheduling_unit_blueprint_name=&scheduling_set_name=&project={args.project}&draft_min=&draft_max=&duration_min=&duration_max=&on_sky_duration_min=&on_sky_duration_max=&relative_start_time_min=&relative_start_time_max=&relative_stop_time_min=&relative_stop_time_max=&subtasks_min=&subtasks_max=&obsolete=&task_type={task_type}"
+
+        # Query results
+        spec_doc = client.do_request_and_get_result_as_json_object(method="GET", full_url=url)
+        
+        # Print results
+        for o in spec_doc["results"]:
+            blueprint_id = o['scheduling_unit_blueprint_id']
+            description = o['short_description']
+            duration = o['specifications_doc']['duration']
+            task_type = o['task_type']
+            obsid = o['subtasks_ids'][0]
+            tstart = o['scheduled_start_time']
+            band = o['specifications_doc']['station_configuration']['filter']
+            antennaset = o['specifications_doc']['station_configuration']['antenna_set']
+            station_groups = o['specifications_doc']['station_configuration']['station_groups']
+            stations = [s for sg in station_groups for s in sg['stations']]
+            #print(f"| {obsid} | {blueprint_id} | {task_type} | {tstart} | {duration:6d} | {antennaset:8s} | {band:11s} | {description} | {stations}")
+
+            # Create station string
+            station_string = ""
+            for station in stations:
+                station_string += f"{station} "
+            station_string = station_string.rstrip()
+            
+            if "LBA" in antennaset:
+                cmd = f"python l2json/quick_impl.py --tstart {tstart} --duration {duration} --output_pattern \"/home/bassa/calibration/{{start}}_L{obsid}_{{station}}{{field}}_{{datatype}}.h5\" --station {station_string} --type XST --field LBA"
+            elif "HBA_DUAL" in antennaset:
+                cmd = f"python l2json/quick_impl.py --tstart {tstart} --duration {duration} --output_pattern \"/home/bassa/calibration/{{start}}_L{obsid}_{{station}}{{field}}_{{datatype}}.h5\" --station {station_string} --type XST --field HBA0 HBA1 HBA"
+            print(cmd)
diff --git a/tmss_list_observations.py b/tmss_list_observations.py
new file mode 100755
index 0000000000000000000000000000000000000000..618a26972b144ce351477853c0d02b38287828f5
--- /dev/null
+++ b/tmss_list_observations.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+import sys
+import json
+import yaml
+import argparse
+
+from datetime import datetime, timedelta, UTC
+
+from lofar_tmss_client.tmss_http_rest_client import TMSSsession
+
+from print_dict import print_dict
+
+if __name__ == "__main__":
+    # Read command line arguments
+    parser = argparse.ArgumentParser(description="List tasks")
+    parser.add_argument("-p", "--project", help="Project to which tasks belong [str, default: COM_LOFAR2]",
+                        default="COM_LOFAR2", type=str)
+    parser.add_argument("-s", "--tstart", help="Start time (isot) [str, default: now - 1 day]",
+                        default=None, type=str)
+    parser.add_argument("-e", "--tend", help="Start time (isot) [str, default: now]",
+                        default=None, type=str)
+    args = parser.parse_args()
+
+    task_type = "observation"
+    
+    # Start time
+    if args.tstart is None and args.tend is None:
+        tstart = (datetime.now(UTC) + timedelta(days=-1)).strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+        tend = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+    else:
+        tstart = datetime.strptime(args.tstart, "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+        tend = datetime.strptime(args.tend, "%Y-%m-%dT%H:%M:%S").strftime("%Y-%m-%dT%H:%M:%S").replace(":", "%3A")
+
+    # Read credentials
+    with open("login.yaml", "r") as fp:
+        settings = yaml.load(fp, Loader=yaml.FullLoader)
+
+    with TMSSsession(host=settings['host'],
+                     port=settings['port'],
+                     username=settings['username'],
+                     password=settings['password']) as client:
+
+        # Format URL
+        url = f"https://tmss.lofar.eu/api/task_blueprint?tags=&created_at_after=&created_at_before=&updated_at_after=&updated_at_before=&name=&description=&scheduled_start_time_after={tstart}&scheduled_start_time_before={tend}&scheduled_stop_time_after=&scheduled_stop_time_before=&actual_process_start_time_after=&actual_process_start_time_before=&actual_process_stop_time_after=&actual_process_stop_time_before=&actual_on_sky_start_time_after=&actual_on_sky_start_time_before=&actual_on_sky_stop_time_after=&actual_on_sky_stop_time_before=&process_start_time_after=&process_start_time_before=&process_stop_time_after=&process_stop_time_before=&on_sky_start_time_after=&on_sky_start_time_before=&on_sky_stop_time_after=&on_sky_stop_time_before=&on_sky_duration=&duration=&specified_on_sky_duration=&obsolete_since=&short_description=&specifications_doc=&specifications_template=&draft=&scheduling_unit_blueprint=&output_pinned=unknown&id=&id_min=&id_max=&scheduling_unit_blueprint_min=&scheduling_unit_blueprint_max=&scheduling_unit_blueprint_name=&scheduling_set_name=&project={args.project}&draft_min=&draft_max=&duration_min=&duration_max=&on_sky_duration_min=&on_sky_duration_max=&relative_start_time_min=&relative_start_time_max=&relative_stop_time_min=&relative_stop_time_max=&subtasks_min=&subtasks_max=&obsolete=&task_type={task_type}"
+
+        # Query results
+        spec_doc = client.do_request_and_get_result_as_json_object(method="GET", full_url=url)
+
+        #print(f"|| OBSID || BP ID || Task || Start || Duration || Antenna Set || Band || Description | Stations |")
+
+        #print_dict(spec_doc, prefix="spec_doc")
+        
+        # Print results
+        for o in spec_doc["results"]:
+#            print(o)
+            blueprint_id = o['scheduling_unit_blueprint_id']
+            description = o['short_description']
+            duration = o['specifications_doc']['duration']
+            task_type = o['task_type']
+            obsid = o['subtasks_ids'][0]
+            tstart = o['scheduled_start_time']
+            band = o['specifications_doc']['station_configuration']['filter']
+            antennaset = o['specifications_doc']['station_configuration']['antenna_set']
+            station_groups = o['specifications_doc']['station_configuration']['station_groups']
+            stations = [s for sg in station_groups for s in sg['stations']]
+            #print(f"| {obsid} | {blueprint_id} | {task_type} | {tstart} | {duration:6d} | {antennaset:8s} | {band:11s} | {description} | {stations}")
+
+            # Create station string
+            station_string = ""
+            for station in stations:
+                station_string += f"{station} "
+            station_string = station_string.rstrip()
+            
+            if "LBA" in antennaset:
+                cmd = f"python l2json/quick_impl.py --tstart {tstart} --duration {duration} --output_pattern \"/home/bassa/calibration/{{start}}_L{obsid}_{{station}}{{field}}_{{datatype}}.h5\" --station {station_string} --type XST --field LBA"
+            elif "HBA_DUAL" in antennaset:
+                cmd = f"python l2json/quick_impl.py --tstart {tstart} --duration {duration} --output_pattern \"/home/bassa/calibration/{{start}}_L{obsid}_{{station}}{{field}}_{{datatype}}.h5\" --station {station_string} --type XST --field HBA0 HBA1 HBA"
+            print(cmd)