diff --git a/applications/apertif/commissioning/UB_user.conf b/applications/apertif/commissioning/UB_user.conf
new file mode 100644
index 0000000000000000000000000000000000000000..d0ed6ff0af4872ecb10571f9bff05e5d44ea6edf
--- /dev/null
+++ b/applications/apertif/commissioning/UB_user.conf
@@ -0,0 +1,4 @@
+#controller = SignalControl
+IP = "localhost"
+port = 25000
+#instance = 1
diff --git a/applications/apertif/commissioning/main_w_mac_lcurtx_python.py b/applications/apertif/commissioning/main_w_mac_lcurtx_python.py
new file mode 100644
index 0000000000000000000000000000000000000000..0fa242385c1684eee6c229497314682806a4df48
--- /dev/null
+++ b/applications/apertif/commissioning/main_w_mac_lcurtx_python.py
@@ -0,0 +1,256 @@
+#!/usr/bin/env python
+###############################################################################
+#
+# Copyright (C) 2017
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+###############################################################################
+
+# Author:
+# . Daniel van der Schuur
+# . Boudewijn Hut
+# Purpose:
+# . Run UniBoard commands on remote dish LCUs and local correlator LCU to start
+#   data streams
+# Usage: 
+# . python main.py --app <application> --tel <telescopes> --unb <uniboards> --opt <options>
+#        . application = "apertif-ag", "apertif-dev", "arts_sc1" or "arts_sc4"
+#        . telescopes = 2,3,4,..,c,d
+#        . unb = bands = 0,1,2,..15
+#        . options = noflash (optional, debug/development only)
+
+import shell
+import test_case
+import common as cm
+import time
+import numpy as np
+import os
+import sys
+
+from apertif.drivers.uniboard.UniBoards import UniBoards
+from lofar.parameterset import parameterset
+theUniBoards = UniBoards(parameterset("UB_user.conf"))
+
+theUniBoards.version()
+
+
+###############################################################################
+# Test case contains logging/printing functionality
+###############################################################################
+tc = test_case.Testcase('MAIN - ', '')
+
+
+
+
+supportedApps = ['apertif-ag', 'apertif-dev', 'arts_sc1', 'arts_sc4']
+if tc.appStr in supportedApps:
+    app_str = 'Application: ' + tc.appStr
+    tc.append_log(1, app_str)
+else:
+    tc.append_log(1, 'Exit due to unsupported --app , must be one of %s.' % supportedApps)
+    sys.exit()
+
+lcu_str = 'Targetting LCUs: '
+LCUS = []
+for tel in tc.telStrList:
+    if tel == '':
+        continue
+    LCUS.append('lcu-rt' + str(tel))
+    lcu_str = lcu_str + ' lcu-rt' + str(tel) + ','
+tc.append_log(1, lcu_str[:-1])
+
+unb_str = 'Targetting UniBoards: ' + str(tc.unbStr)
+tc.append_log(1, unb_str)
+
+#tc.polStr
+#tc.polNrs
+print 'Polarisation: ' + tc.polStr
+
+opt_str = 'Options: ' + tc.optStr
+tc.append_log(1, opt_str)
+
+if tc.polStr == '0':
+    UNBS_BF = '0:3'
+elif tc.polStr == '1':
+    UNBS_BF = '4:7'
+else:
+    UNBS_BF = '0:7'
+
+print 'UNBS_BF = ' + UNBS_BF
+
+###############################################################################
+# Check if central UniBoard system is ready for action. If not, exit immediately.
+###############################################################################
+if tc.unbStr == '':
+    print 'Omitting call to central_status, since no XC boards are addressed.'
+else:
+    cmd = '. $RADIOHDL/applications/apertif/commissioning/central_status.sh ' + tc.appStr + ' ' + tc.telStr + ' ' + tc.unbStr + ' ' + 'precheck' + ' ' + tc.polStr
+    print 'ccu-corr'+':$ '+cmd
+    output = shell.ssh_cmd('ccu-corr', cmd, tc)
+    if "Error" in output or not "Passed" in output:
+        print "Exiting due to central errors"
+        sys.exit()
+
+###############################################################################
+# Check if dish UniBoard systems are ready for action. If not, exit immediately.
+###############################################################################
+command = '. $RADIOHDL/applications/apertif/commissioning/dish_status.sh ' + tc.appStr + ' ' + 'precheck' + ' ' + tc.polStr
+for lcu in LCUS:
+    print lcu+':$ '+command
+    output = (shell.ssh_cmd(lcu, command, tc))
+    if "Error" in output or not "Passed" in output:
+        print "Exiting due to dish errors"
+        sys.exit()
+
+###############################################################################
+# Run remote dish commands in background
+###############################################################################
+print 'POL, RUN', tc.polStr, tc.runStr
+subcommand = '. $RADIOHDL/applications/apertif/commissioning/dish_commands.sh ' + tc.appStr + ' ' + tc.optStr + ' ' + tc.polStr + ' ' + tc.runStr + ' ' + ','.join(map(str,tc.unbNrs))
+for lcu in LCUS:
+    command = subcommand + ' > ~/'+lcu+'_dish_commands.log '
+    print lcu+':$ '+command
+    shell.ssh_cmd_bkgnd(lcu, command)
+
+###############################################################################
+# Run central commands in foreground
+###############################################################################
+if tc.unbStr == '':
+    pass
+else:
+    subcommand = '. $RADIOHDL/applications/apertif/commissioning/central_commands.sh ' + tc.appStr + ' ' + tc.telStr + ' ' + tc.unbStr + ' ' + tc.optStr + ' ' + tc.polStr
+    command = subcommand + ' | tee ~/central_commands.log '
+    print 'ccu-corr'+':$ '+command
+    shell.ssh_cmd('ccu-corr', command, tc)
+
+###############################################################################
+# Wait until remote dish commands are done
+###############################################################################
+command = 'ps -efd | grep [d]ish_commands.sh'
+for lcu in LCUS:
+    while True:
+        output = (shell.ssh_cmd(lcu, command, tc))
+        if not "dish_commands.sh" in output:
+            print lcu, "ready"
+            break
+        else:
+            time.sleep(1)
+        
+###############################################################################
+# Reset the XAUI cores in the front end Apertif beam former
+###############################################################################
+if tc.unbStr == '':
+    print 'Omitting xaui reset, since no XC boards are addressed.'
+else:
+    cmd = 'python $UPE/peripherals/pi_tr_xaui.py --unb ' + UNBS_BF + ' --fn 0:3 -r 0:2 --reg reset_control_status=3'
+    for lcu in LCUS:
+        print lcu+':$ '+cmd
+        shell.ssh_cmd_bkgnd(lcu, cmd)
+    
+    ###############################################################################
+    # Reset the XAUI cores in all central FPGAs
+    # . Loop through a list of individual UniBoards instead of targeting all 
+    #   UniBoards in one command; in case one of them fails the others will still work.
+    ###############################################################################
+    for unb in tc.unbNrs:
+        cmd = 'python $UPE/peripherals/pi_tr_xaui.py --unb ' + str(unb) + ' --fn 0:3 --bn 0:3 -r 0:2 --reg reset_control_status=3'
+        shell.ssh_cmd('ccu-corr', cmd, tc)
+###############################################################################
+# Enable data path if this is not a re-run
+###############################################################################
+if tc.run == True: 
+
+    if tc.mac == True:
+        print "Starting the Uniboard driver"
+        cmd = 'service UBDriver start'
+        print 'lcu-rtx'+':$ '+cmd
+        output = shell.ssh_cmd('lcu-rtx', cmd, tc)
+
+
+    ###############################################################################
+    # Enable the data path synchonously
+    ###############################################################################
+    BLOCKS_PER_SEC = 781250
+    arm_time = 5 # seconds to arm system
+    curr_time = time.time()
+    curr_time_rounded = round(curr_time)
+    bsn_init_sec = int(np.ceil(curr_time + arm_time)) # seconds after epoch (for next PPS after arm_time)
+    bsn_init = BLOCKS_PER_SEC*(bsn_init_sec)
+    
+
+    cmd = 'python $UPE/peripherals/util_bsn_source.py --unb ' + UNBS_BF + ' --bn 0:3 -n 11 -r %s' %str(bsn_init)
+    for lcu in LCUS:
+        shell.ssh_cmd(lcu, cmd, tc)
+    
+    tc.append_log(1, 'Current time         : ' + str(curr_time))
+    tc.append_log(1, 'Current time rounded : ' + str(curr_time_rounded))
+    tc.append_log(1, 'Scheduled start time : ' + str(bsn_init_sec))
+    tc.append_log(1, 'Scheduled start BSN  : ' + str(bsn_init))
+    
+
+    if tc.mac == True:
+        print "Uniboard driver: Wait for PPS..."
+        cmd = '/opt/apertif/bin/ubctl --address=0::0 --ppswait' # UNB0, BN0
+        print 'lcu-rtx'+':$ '+cmd
+        shell.ssh_cmd('lcu-rtx', cmd, tc)
+
+        #print "Uniboard driver: Wait schedule on PPS=" + str(bsn_init_sec)
+        #cmd = '/opt/apertif/bin/ubctl --address=0::-1 --ppssched=' + str(bsn_init_sec) # UNB0, all BNs
+        #print 'lcu-rtx'+':$ '+cmd
+        #shell.ssh_cmd('lcu-rtx', cmd, tc)
+
+        # Wait until local time is 1.8s before bsn_init_sec
+        #cm.do_until_ge(time.time, bsn_init_sec-1.8, ms_retry=10, s_timeout=20) 
+    else:
+        # Wait until local time is 1.8s before bsn_init_sec
+        cm.do_until_ge(time.time, bsn_init_sec-1.8, ms_retry=10, s_timeout=20) 
+
+        # wait until PPS; should occur in ~0.8s
+        cmd = 'python $UPE/peripherals/util_ppsh.py --unb ' + UNBS_BF[0] + ' --bn 0 -n 4'
+        print 'cmd = %s' % cmd
+        shell.ssh_cmd(LCUS[0], cmd, tc)
+
+        # We are now at ~bsn_init_sec-1. Enable the data path on the next PPS
+        for lcu in LCUS:
+            cmd = ['/usr/bin/ssh', 'ssh', '-x', lcu, 'python', '$UPE/peripherals/util_bsn_source.py', '--unb', UNBS_BF, '--bn', '0:3', '-n', '1']
+            print cmd
+            os.spawnl(os.P_NOWAIT, *cmd)
+
+
+###############################################################################
+# Everything should be up and running - check dish UniBoard system
+###############################################################################
+command = '. $RADIOHDL/applications/apertif/commissioning/dish_status.sh ' + tc.appStr + ' ' + 'postcheck' + ' ' + tc.polStr
+for lcu in LCUS:
+    print lcu+':$ '+command
+    output = (shell.ssh_cmd(lcu, command, tc))
+    if "Error" in output or not "Passed" in output:
+        print "Found post-command dish errors"
+
+###############################################################################
+# Everything should be up and running - check central UniBoard system
+###############################################################################
+if tc.unbStr == '':
+    print 'Omitting call to central_status, since no XC boards are addressed.'
+else:
+    cmd = '. $RADIOHDL/applications/apertif/commissioning/central_status.sh ' + tc.appStr + ' ' + tc.telStr + ' ' + tc.unbStr + ' ' + 'postcheck' + ' ' + tc.polStr
+    print 'ccu-corr'+':$ '+cmd
+    output = shell.ssh_cmd('ccu-corr', cmd, tc)
+    if "Error" in output or not "Passed" in output:
+        print "Found post-command central errors"
+
+