diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..2605fb84392a054428d4f4579b752d169ecd2876
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,192 @@
+## MATLAB ##
+# Windows default autosave extension
+*.asv
+
+# OSX / *nix default autosave extension
+*.m~
+
+# Compiled MEX binaries (all platforms)
+*.mex*
+
+# Packaged app and toolbox files
+*.mlappinstall
+*.mltbx
+
+# Generated helpsearch folders
+helpsearch*/
+
+# Simulink code generation folders
+slprj/
+sccprj/
+
+# Matlab code generation folders
+codegen/
+
+# Simulink autosave extension
+*.autosave
+
+# Simulink cache files
+*.slxc
+
+# Octave session info
+octave-workspace
+
+## PYTHON ##
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+Sacher_Lasertechnik/
+
+measurements/
+flexsensorpy/measurements/
+.venv-waffel-untersucher/
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/flexsensor.iml b/.idea/flexsensor.iml
new file mode 100644
index 0000000000000000000000000000000000000000..8a05c6ed5f0c89c2998d9aee8978f53136f7649a
--- /dev/null
+++ b/.idea/flexsensor.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+  <component name="PyDocumentationSettings">
+    <option name="format" value="GOOGLE" />
+    <option name="myDocStringFormat" value="Google" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1030d7352b2f9c4feee0960cd1f81183a0144165
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,14 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredPackages">
+        <value>
+          <list size="1">
+            <item index="0" class="java.lang.String" itemvalue="PySide6" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..105ce2da2d6447d11dfe32bfb846c3d5b199fc99
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..67388a2ac340ca6c17e649492b707758f6f04016
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Black">
+    <option name="sdkName" value="Python 3.11 (pythonProject1)" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11 (pythonProject1)" project-jdk-type="Python SDK" />
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..706538a9e64a579a2518d6b4f085ca54bd24db07
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/flexsensor.iml" filepath="$PROJECT_DIR$/.idea/flexsensor.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6323e499d2e6d7a5807f773ef99ea0cc72c8dc7b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,101 @@
+## Still under construction
+![](https://commons.wikimedia.org/wiki/Category:Under_construction_icons#/media/File:Baustelle-mittel.png)
+
+*This repository is under construction*. It will be restructured after all individual parts are updated. 
+You can find the dependencies in the gitlab parent folder of this repo.
+
+# Flexsensor
+
+
+An automation software for [FormFactor Cascade Summit200](https://www.formfactor.com/product/probe-systems/200-mm-systems/summit200/) Probe Stations.
+*FlexSensor* is a software that allows to automate measurements using the FormFactor Wafer Prober.
+
+*FlexSensor* is a standalone Python application. Its versatility allows for immediate deployment, without prior programming knowledge. Particularly noteworthy are its post-processing capabilities, however, the software's core functionality is the use of the automated measurement routine to acquire the resonant spectra of photonic devices, integrated within a specialized measurement system, as detailed in Section 
+
+# Installation
+Create a virtual environment (highly recommended)
+```python
+python -m venv .venv
+source .venv/Scripts/Activate
+```
+Prior to using the software, these packages need to be installed.
+```
+pip install rich PySide6 pyyaml matplotlib pyqtgraph pandas scipy numpy
+```
+
+# Measuring using Flexsensor
+## Input Structure File
+The measuring process relies on a ```vas```-File that store the positions to the structures. in priciple 
+this file os a list of python dictionary in a predefined format, that allows the easy definiton
+on how to measure the structures. 
+The file allows python-style line comments using the ```#```-sign
+### Comments and Bookmarks
+```python
+# First structure to measure  
+# group="mrr1"
+```
+Sometimes it is useful to have the Klayout-positions bookmarked. Using the Klayout-Coordinates, the
+software creates a readable Bookmark file that can be used in Klayout.
+```python
+# Bookmark this view
+mrr1_bookmark = { 'x_left': 19012, 'x_right' : 20708, 'y_bottom' : 20185, 'y_top': 21866 }
+```
+### Defining a measurement point
+Defining a measurement point requires the input position (`x_in`, `y_in`) and the output 
+position (`x_out`, `y_out`). The keyword `repetitions` allows to define the number of repeated measurements of the same
+structure (e.g., for statistical evaluation, etc.)
+<br> 
+**These positions are relative and measured from a predefined point (See Sec ...) on how
+to select this point which can be chosen arbitrarily.**
+```python
+mrr1_ref = {'y_in' : -2120, 'x_in' : 960, 'y_out' : -2120, 'x_out' : -155, 'repetitions': 2}
+```
+Sometimes it is useful to define a group of measurement points that are equally spaced in x-direction. For this, the 
+`spacing` and `num`-keyword can be used. Using these values, the software will automatically generate a list of 
+`num` structures, equally spaced in x-direction using the `spacing` value. 
+```python
+mrr1     = {'y_in' : -1845, 'x_in' : 960, 'y_out' : -2015, 'x_out' : -155,  'num' : 6, 'spacing' : 100, 'repetitons': 200}
+```
+
+## Setup bevore measuring
+1. Open the correct wafer map. 
+Open the wafer Map under **Velox** -> **WaferMap**. Load the correct wafer file and select or deselect dies you do not 
+want to capture. 
+![](images/docs_img/open_wafer_map.png)
+ **Note**: Make sure that the die and wafer size is correct.
+2. Auto-Align the Wafer
+ For this open the "AutoAlign" Wizard  and find a suitable alignment structure. 
+![](images/docs_img/autoalign_wafer.png)
+3. Place at "your" origin
+The structure file relies on "relative" positions to a point you
+find a suitable structur which is defined as the "die" origin. This is used to  measure the distance to the to/be measured strcutures. Use the same mark in zour Klayout file and on the wafer. 
+![](images/docs_img/origina_at_wafer.JPG)
+If you have not yet created a list for measuring your structure, you can use 
+- the wafer prober find the right coordinates.
+- the KLayout-File for measuring the structures
+5. Set contact height
+Set our fiber to the correct height. Then use the "Set Contact height". Otherwise the measurement routine will fail!
+6. Train the Home Positions
+This step is crucial and needed to train the output positions.
+
+
+# Lincence and usage
+This software is licenced under the [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.de.html). 
+If you use this software for your work or in your papers please cite me the following:
+
+
+
+
+# FAQ&Issues
+This section should cover the issues that may occure during usage or development. 
+## Installation issues and running
+There are some combinations of pyside6 and pyqtgraph that may lead to incompatibility
+issues. Especially `PySide 6.5.0` and `pyqtgraph 0.13.2` installation lead to 
+```python
+TypeError: GraphicsWidgetAnchor.__init__() takes 1 positional argument but 2 were given
+```
+[Solution](https://stackoverflow.com/questions/76005506/pyqtgraphs-graphicswidgetanchor-class-incomplatible-with-pyside6?noredirect=1#comment134055507_76005506):
+Remove your current installed pyqtgraph and install the latest version:
+```python
+pip install git+https://github.com/pyqtgraph/pyqtgraph@master
+```
\ No newline at end of file
diff --git a/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertaintyControlWidget.ui b/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertaintyControlWidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..67df7de70e1f9c87f604ef83675bca77306071db
--- /dev/null
+++ b/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertaintyControlWidget.ui
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Form</class>
+ <widget class="QWidget" name="Form">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>569</width>
+    <height>573</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <layout class="QGridLayout" name="gridLayout_3">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>22</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Quantity Data</string>
+       </property>
+      </widget>
+     </item>
+     <item row="5" column="0">
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QFrame" name="horizontalFrame">
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>22</height>
+        </size>
+       </property>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QLabel" name="label_2">
+          <property name="maximumSize">
+           <size>
+            <width>16777215</width>
+            <height>22</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Type</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="comboBox_2"/>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item row="2" column="0">
+      <widget class="QFrame" name="horizontalFrame_2">
+       <property name="maximumSize">
+        <size>
+         <width>16777215</width>
+         <height>22</height>
+        </size>
+       </property>
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <widget class="QLabel" name="label_3">
+          <property name="maximumSize">
+           <size>
+            <width>16777215</width>
+            <height>22</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Uncertainty Distribution</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="comboBox_3"/>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item row="3" column="0">
+      <layout class="QGridLayout" name="gridLayout_2"/>
+     </item>
+     <item row="4" column="0">
+      <layout class="QGridLayout" name="gridLayout_4">
+       <item row="0" column="0">
+        <widget class="QTabWidget" name="tabWidget">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="currentIndex">
+          <number>1</number>
+         </property>
+         <widget class="QWidget" name="tab">
+          <attribute name="title">
+           <string>Unit</string>
+          </attribute>
+          <layout class="QGridLayout" name="gridLayout_6">
+           <item row="0" column="0">
+            <layout class="QGridLayout" name="gridLayout_5">
+             <item row="0" column="1">
+              <widget class="QLineEdit" name="lineEdit"/>
+             </item>
+             <item row="0" column="0">
+              <widget class="QLabel" name="label_4">
+               <property name="text">
+                <string>Unit</string>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="0">
+              <widget class="QLabel" name="label_5">
+               <property name="text">
+                <string>Definition</string>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="1">
+              <widget class="QLineEdit" name="lineEdit_2"/>
+             </item>
+            </layout>
+           </item>
+          </layout>
+         </widget>
+         <widget class="QWidget" name="tab_2">
+          <attribute name="title">
+           <string>Description</string>
+          </attribute>
+          <layout class="QGridLayout" name="gridLayout_8">
+           <item row="1" column="0">
+            <widget class="QPlainTextEdit" name="plainTextEdit">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertainyControlWidget.py b/src/FlexSensor/BackgroundHandlers/UncertaintyControl/UncertainyControlWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/InitialSetupWizard/InitialSetupWizard.py b/src/FlexSensor/InitialSetupWizard/InitialSetupWizard.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7ae53e34c048b54a25fe902a7093a87342bc401
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/InitialSetupWizard.py
@@ -0,0 +1,40 @@
+import sys
+
+from PySide6.QtWidgets import QWizard, QApplication
+
+import Prober as Prober
+from InitialSetupWizard.pages.FifthPage import FifthWizardPage
+from InitialSetupWizard.pages.ForthPage import ForthWizardPage
+from InitialSetupWizard.pages.ThirdPage import ThirdWizardPage
+from InitialSetupWizard.pages.SecondPage import SecondWizardPage
+from InitialSetupWizard.pages.FirstPage import FirstWizardPage
+from generics.logger import setup_logging
+
+
+class InitialSetupWizard(QWizard):
+
+    def __init__(self, prober: Prober.Controller, parent=None):
+        super().__init__(parent)
+        self.prober = prober
+        self.addPage(FirstWizardPage(self.prober, self))
+        self.addPage(SecondWizardPage(self.prober, self))
+        p3 = ThirdWizardPage(self.prober, self)
+        self.addPage(p3)
+        p4 = ForthWizardPage(self.prober, p3, parent=self)
+        self.addPage(p4)
+        self.addPage(FifthWizardPage(self.prober, p4, self))
+
+        self.setWindowTitle("Wizard Example")
+
+
+if __name__ == "__main__":
+    setup_logging()
+
+    app = QApplication()
+    prober = Prober.Controller()
+    wizard = InitialSetupWizard(prober)
+
+    wizard.show()
+
+    sys.exit(app.exec())
+
diff --git a/src/FlexSensor/InitialSetupWizard/pages/FifthPage.py b/src/FlexSensor/InitialSetupWizard/pages/FifthPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..69a77e60cdb79f970e9786da1b4072fb3e040af3
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/FifthPage.py
@@ -0,0 +1,112 @@
+from PySide6.QtWidgets import QWizard, QGridLayout, QLabel, QPushButton
+
+import Prober as Prober
+from InitialSetupWizard.pages.ForthPage import ForthWizardPage
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class FifthWizardPage(WizardPage):
+    def __init__(self, prober: Prober.Controller, page_input_distance: ForthWizardPage, parent: QWizard = None):
+        super().__init__(prober, parent)
+        self.setMaximumHeight(450)
+        self.setMinimumHeight(450)
+
+        self.setTitle("Train Output Home Position")
+        layout = QGridLayout()
+        self.distance = 0
+        # p_3: ThirdPage = parent.page(2)
+        page_input_distance.input_distance.textChanged.connect(self._on_distance_changed)
+        self.label_intro = QLabel(
+            f"To train the output home Position the Prober will move both probes in the direction given in the previous"
+            f"step. \n"
+            f"First it will move the input probe 500um to the left, then the output probe the given distance "
+            f"d={self.distance}um so it is placed at the input position. \n"
+            f"Afterwards the Home position is set to the current "
+            f"position and both probes are moved back to it's initial position.")
+        self.label_intro.setWordWrap(True)
+        layout.addWidget(self.label_intro, 0, 0, 1, 2)
+
+        self.btn_train = QPushButton('Set Home Position')
+        self.btn_train.clicked.connect(lambda: self.train_warn(self.distance))
+        layout.addWidget(self.btn_train, 1, 0, 1, 2)
+
+        self.setLayout(layout)
+
+    def _on_distance_changed(self, distance):
+        self.distance = int(distance)
+        self.label_intro.setText(
+            f"To train the output home Position the Prober will move both probes in the direction given in the previous"
+            f"step. \n"
+            f"First it will move the input probe 500um to the left, then the output probe the given distance "
+            f"d={self.distance}um so it is placed at the input position. \n"
+            f"Afterwards the Home position is set to the current "
+            f"position and both probes are moved back to it's initial position.")
+
+    # NO pressed
+
+    def train_warn(self, distance, safe_move_distance=500):
+        # Bevor continuning display a warning as a dialog box to the user
+        if self.display_mbox_warning(
+                text=f"The output optical probes are about to move {distance} towards the input probe. The"
+                     f" input probe will be moved away {safe_move_distance}."
+                     f"Make sure that no obstacles are in the way and the distance is safe to move.",
+                title="Optical probe are about to move"
+        ):
+            self.train(distance, safe_move_distance)
+        else:
+            self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
+            return
+
+    def train(self, distance, safe_move_distance):
+        # First read out both positions
+        x_in, y_in, z_in, _, _, _ = self.prober.opt_if.set_optical_probe_home(probe=Prober.Probe.INPUT)
+        x_out, y_out, z_out, _, _, _ = self.prober.opt_if.set_optical_probe_home(probe=Prober.Probe.OUTPUT)
+        pos = Prober.ProbePosition(input=(x_in, y_in, z_in), output=(x_out, y_out, z_out))
+        print(pos)
+        # Now move the input probe away from the position
+
+        # INPUT -safe_move_distance #===================================================================================
+        self.logger.info(f"Moving input probe {-safe_move_distance}um.")
+        self.prober.opt_if.move_optical_probe(Prober.Probe.INPUT, -safe_move_distance, '0', 'R')
+        self.logger.info(f"Moved input probe {-safe_move_distance}um.")
+        # ==============================================================================================================
+
+        # OUTPUT -distance =============================================================================================
+        self.logger.info(f"Moving output probe {-distance}um.")
+        if self.display_mbox_warning(
+                text=f"The  optical output probe is about to move {-distance}um towards the input probe. "
+                     f"Make sure that the output probe has been moved!",
+                title="Optical output probe are about to move",
+        ):
+            self.prober.opt_if.move_optical_probe(Prober.Probe.OUTPUT, -distance, '0', 'R')
+            self.logger.info(f"Moved output probe {-distance}um.")
+        else:
+            self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
+            return
+        # ==============================================================================================================
+
+        # ==============================================================================================================
+        self.prober.opt_if.set_optical_probe_home(Prober.Probe.OUTPUT)
+        self.logger.info(f"Set optical output home to current position")
+        # ==============================================================================================================
+
+        # OUTPUT distance ==============================================================================================
+        self.logger.info(f"Moving output probe {distance}um back to initial position ")
+        self.prober.opt_if.move_optical_probe(Prober.Probe.OUTPUT, distance, '0', 'R')
+        # ==============================================================================================================
+
+        # INPUT safe_move_distance =====================================================================================
+        self.logger.info(f"Moving input probe {safe_move_distance}um back to initial position.")
+        if self.display_mbox_warning(
+                text=f"The optical input probe is about to move {safe_move_distance}um towards the output probe. "
+                     f"Make sure that the output probe position has been reset!",
+                title="Optical output probe are about to move"
+        ):
+            self.prober.opt_if.move_optical_probe(Prober.Probe.INPUT, safe_move_distance, '0', 'R')
+            self.logger.info(f"Moved input probe {safe_move_distance}.")
+        else:
+            self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
+            return
+        # ==============================================================================================================
+        self.display_mbox_ok(text="The home position has been set successfully!",
+                             title="Home position set")
diff --git a/src/FlexSensor/InitialSetupWizard/pages/FirstPage.py b/src/FlexSensor/InitialSetupWizard/pages/FirstPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad7b2688bfe6ac7f06141d46b38e804a810e433d
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/FirstPage.py
@@ -0,0 +1,33 @@
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QWizard, QVBoxLayout, QLabel
+
+import Prober as Prober
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class FirstWizardPage(WizardPage):
+    def __init__(self, prober: Prober.Controller, parent=None):
+        super().__init__(prober, parent)
+
+        self.setPixmap(QWizard.WizardPixmap.WatermarkPixmap, QPixmap())
+
+        layout = QVBoxLayout()
+
+        self.setTitle("Train Output Home Position")
+
+        label = QLabel("This wizard will guide you trough the calibration step. \n"
+                       "During the process the Prober (Chuck, etc.) and the Optical Interface (Hexapods, etc.) will "
+                       "move! The wizard won't start the movement automatically and each step "
+                       "must be verified by the user and started manually.\n"
+                       "\n"
+                       "To prevent damage, the setup process are designed to check each steps. Thus,"
+                       "checking the individual steps is required to continue the calibration.\n\n "
+                       "Click 'Next' to start the wizard.")
+        label.setWordWrap(True)
+        label.setAlignment(Qt.AlignLeft)
+
+        # Add an image to the QWizardPage
+        layout.addWidget(label)
+
+        self.setLayout(layout)
diff --git a/src/FlexSensor/InitialSetupWizard/pages/ForthPage.py b/src/FlexSensor/InitialSetupWizard/pages/ForthPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..c6fe8a47352728f4617669cc3b64de4000a02c01
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/ForthPage.py
@@ -0,0 +1,74 @@
+from PySide6.QtWidgets import QGridLayout, QPushButton, QLabel, QLineEdit, QCheckBox
+
+import Prober as Prober
+from InitialSetupWizard.pages.ThirdPage import ThirdWizardPage
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class ForthWizardPage(WizardPage):
+    def __init__(self, prober: Prober.Controller, third_page: ThirdWizardPage, parent=None):
+        super().__init__(prober, parent)
+        self.third_page = third_page
+        self.setTitle("Positioning of the Probes")
+        layout = QGridLayout()
+
+        task_set_chuck_home_position, _ = self.add_task(
+            "1.  Move to the calibration structure",
+            "Click on the next button 'Move to calibration structure' to move the chuck back to the calibration structure.\n"
+            "Warning: The probes will be moved 250um away from the selected position to ease the next step.",
+            "task_move_back_to_cal_structure*")
+        layout.addWidget(task_set_chuck_home_position, 1, 0, 1, 4)
+
+        # ==============================================================================================================
+        # layout.addWidget(self.add_graphics(path=f'{self.imgf}/1_placed_at_origin_cut.JPG'), 10, 0, 1, 4)
+        self.btn_move_back_to_cal_structure = QPushButton('Move to calibration structure')
+        layout.addWidget(self.btn_move_back_to_cal_structure, 2, 0, 1, 4)
+        self.btn_move_back_to_cal_structure.clicked.connect(lambda: self.move_back_to_cal_structure(probe_movement=250))
+
+        task_measure_distance, _ = self.add_task(
+            "2.  Measure the distance between the input and the output.",
+            "For calibrating the position of the input probe to the output probe, "
+            "the difference of the input and the output must be determined. If the "
+            "distance is not known, Velox's Measurement Tool can be used. \n"
+            "Note: If using layout values make sure to include a distance which "
+            "corresponds to the position of input and the output probes",
+            "measure_distance*")
+        layout.addWidget(task_measure_distance, 3, 0, 1, 4)
+
+        graphics1 = self.add_graphics(f'{self.imgf}/Step4_2.png')
+        layout.addWidget(graphics1, 4, 0, 1, 4)
+
+        self.task_enter_distance, self.cb_distance_enterd = self.add_task(
+            "3.  Enter the (measured) distance between input and output.",
+            "Enter the measured distance below and press 'Apply' to move the chuck half the given distance",
+            "task_measure_distance*")
+        layout.addWidget(self.task_enter_distance, 5, 0, 1, 4)
+        self.cb_distance_enterd.setCheckable(False)
+
+        lbl_distance = QLabel("Distance (d)")
+        self.input_distance = QLineEdit()
+
+        # self.btn_apply = QPushButton('Move chuck')
+        layout.addWidget(lbl_distance, 6, 0, 1, 1)
+        layout.addWidget(self.input_distance, 6, 1, 1, 1)
+        self.btn_measurement_done = QPushButton("Apply")
+        layout.addWidget(self.btn_measurement_done, 6, 2, 1, 2)
+        self.btn_measurement_done.clicked.connect(lambda: self.move_probes_back(probe_movement=250))
+        self.registerField('distance*', self.input_distance)
+
+        self.setLayout(layout)
+
+
+
+    def move_back_to_cal_structure(self, probe_movement=250):
+        self.move_chuck_x_y(-int(self.third_page.input_movement_x.text()), -int(self.third_page.lbl_movement_y.text()) )
+        self.move_input_probes_x_y(-probe_movement, 0)
+        self.move_output_probes_x_y(probe_movement, 0)
+
+    def move_probes_back(self, probe_movement=250):
+        self.move_input_probes_x_y(probe_movement, 0)
+        self.move_output_probes_x_y(-probe_movement, 0)
+        self.cb_distance_enterd: QCheckBox
+        self.cb_distance_enterd.setCheckable(True)
+        self.cb_distance_enterd.setChecked(True)
+        self.completeChanged.emit()
\ No newline at end of file
diff --git a/src/FlexSensor/InitialSetupWizard/pages/SecondPage.py b/src/FlexSensor/InitialSetupWizard/pages/SecondPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..e65cd134badd553202ef305f81cc5211378acced
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/SecondPage.py
@@ -0,0 +1,50 @@
+from PySide6.QtWidgets import QVBoxLayout, QLabel, QPushButton
+
+import Prober as Prober
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class SecondWizardPage(WizardPage):
+
+    def __init__(self, prober: Prober.Controller, parent=None):
+        super().__init__(prober, parent)
+        self.setTitle("Initial Setup")
+        self.setSubTitle("In this step, the home position will be set.")
+
+        layout = QVBoxLayout()
+        labeli = QLabel("The structure file relies on 'relative' positions to a 'zero' point. Usually such a suitable"
+                        "structure can be chosen as the 'die' origin. From this 'zero' position, "
+                        "every coordinates (x, y) is used to measure the distance to"
+                        "the to/be measured structures.")
+        labeli.setWordWrap(True)
+        layout.addWidget(labeli)
+
+        label1 = QLabel("Use the same 'mark' in the Klayout file and on the wafer. Usually the die's edge is a good"
+                        "point.\n")
+        layout.addWidget(label1)
+
+        # ==============================================================================================================
+        task_move_chuck, _ = self.add_task(
+            "1.  Manually move chuck to the calibration structure",
+            "Manually move the Chuck to the calibration structure using the the Velox Chuck Control. "
+            "Then move the Probes using the FFI Photonic Interface to place it exaclty above the grating couplers.",
+            "task_move_chuck*")
+        layout.addWidget(task_move_chuck)
+        layout.addWidget(self.add_graphics(path=f'{self.imgf}/Step2_1.png'))
+
+        # ==============================================================================================================
+        task_area_scan, self.cb_area_scan = self.add_task(
+            "2.  Perform an 'Area Scan'",
+            "If the Probes are moved, perform an 'Area Scan' to find the best position of the probes."
+            "The program may freez during the area scan.",
+            "task_area_scan*")
+        self.cb_area_scan.setCheckable(True)
+        layout.addWidget(task_area_scan)
+        self.btn_area_scan = QPushButton('Perform Area Scan (Input/Output)')
+        self.txt_coupled_power = QLabel('In: N/A, Out:N/A - Not performed.')
+        layout.addWidget(self.btn_area_scan)
+        layout.addWidget(self.txt_coupled_power)
+        self.btn_area_scan.clicked.connect(lambda: self.area_scan(self.txt_coupled_power, self.cb_area_scan))
+
+        self.setLayout(layout)
+
diff --git a/src/FlexSensor/InitialSetupWizard/pages/ThirdPage.py b/src/FlexSensor/InitialSetupWizard/pages/ThirdPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..52982499b43fc5f72998ba6e7200994eb4f0dbce
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/ThirdPage.py
@@ -0,0 +1,76 @@
+from PySide6.QtWidgets import QGridLayout, QLabel, QLineEdit, QPushButton, QLineEdit
+
+import Prober as Prober
+from InitialSetupWizard.pages.WizardPage import WizardPage
+
+
+class ThirdWizardPage(WizardPage):
+    def __init__(self, prober: Prober.Controller, parent=None):
+        super().__init__(prober, parent)
+
+        self.setTitle("Selecting the reference structure.")
+        layout = QGridLayout()
+        # ==============================================================================================================
+        task_moved_to_ref_structure, _ = self.add_task(
+            "1. Place the Scope over the Input Probe.",
+            "Try to match the center point using the scope's cross. It is useful to set the scope home position to the"
+            "current position.", "task_moved_scope*")
+
+        layout.addWidget(task_moved_to_ref_structure, 0, 0, 1, 4)
+        graphics1 = self.add_graphics(f'{self.imgf}/Step2_1.png')
+        layout.addWidget(graphics1, 1, 0, 1, 4)
+
+        # ==============================================================================================================
+        task_move_to_home, _ = self.add_task(
+            "2.  Move back to the zero position",
+            "Move back to the 'zero' point. This point is your arbitrarily chosen reference point and must be the same "
+            "in your layout file and the prober. Usually a mark or the die's corner is used, however not mandatory.\n"
+            "Input the X and y distance from the calibration structure to the 'zero' point. Make sure to have the "
+            "signs correct.",
+            "task_set_chuck_home_position*")
+        layout.addWidget(task_move_to_home, 2, 0, 1, 4)
+        # Input the X and y distance from the calibration structure to the Home Position
+        graphics1 = self.add_graphics(f'{self.imgf}/Step2_2.png', max_width=400)
+        layout.addWidget(graphics1, 3, 0, 1, 4)
+        self.lbl_movement_x = QLabel("X Movement: ")
+        self.input_movement_x = QLineEdit("-950")
+
+        layout.addWidget(self.lbl_movement_x, 4, 0)
+        layout.addWidget(self.input_movement_x, 4, 1)
+
+        self.input_movement_y = QLabel("Y Movement: ")
+        self.lbl_movement_y = QLineEdit("2120")
+        layout.addWidget(self.input_movement_y, 4, 2)
+        layout.addWidget(self.lbl_movement_y, 4, 3)
+
+        self.btn_move_to_home = QPushButton('Move chuck')
+        layout.addWidget(self.btn_move_to_home, 5, 0, 1, 4)
+        self.btn_move_to_home.clicked.connect(
+            lambda: self.move_chuck_x_y(int(self.input_movement_x.text()), int(self.lbl_movement_y.text())))
+
+        # ==============================================================================================================
+        task_set_chuck_home_position, _ = self.add_task(
+            "3.  Set Chuck Home position",
+            "Use the 'Set to Current Position' to the left to reset the prober's coordinates to (0,0,Z)",
+            "task_set_chuck_home_position*")
+        layout.addWidget(task_set_chuck_home_position, 6, 0, 1, 4)
+        # layout.addWidget(self.add_graphics(path=f'{self.imgf}/1_placed_at_origin_cut.JPG'), 7, 0, 1, 4)
+        self.btn_move_to_home = QPushButton('Set chuck Home')
+        layout.addWidget(self.btn_move_to_home, 7, 0, 1, 4)
+        self.btn_move_to_home.clicked.connect(lambda: self.prober.set_chuck_home())
+
+        self.setLayout(layout)
+
+    # def get_distance(self) -> float:
+    #     value = self.input_distance.text()
+    #     try:
+    #         distance = int(value)
+    #     except Exception as e:
+    #         self.logger.error(f"Can't convert {value} to int!")
+    #         raise e
+    #     return distance
+    #
+    # def move_chuck(self):
+    #     distance = self.get_distance()
+    #     distance_half = int(distance / 2)
+    #     self.move_chuck_x_y(x=-distance_half, y=0)
diff --git a/src/FlexSensor/InitialSetupWizard/pages/WizardPage.py b/src/FlexSensor/InitialSetupWizard/pages/WizardPage.py
new file mode 100644
index 0000000000000000000000000000000000000000..46e10f4d14401a3e1ff9ffeed9ef3d73169663df
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/WizardPage.py
@@ -0,0 +1,146 @@
+import logging
+import pathlib
+
+import numpy as np
+from PySide6 import QtGui
+from PySide6.QtCore import QSize, Qt
+from PySide6.QtGui import QPixmap
+from PySide6.QtWidgets import QWizardPage, QLabel, QWidget, QCheckBox, QVBoxLayout, QMessageBox, QSizePolicy
+
+import Prober as Prober
+from pathes import image_root
+
+
+class WizardPage(QWizardPage):
+    def __init__(self, prober: Prober.Controller, parent=None):
+        super().__init__(parent)
+        self.parent = parent
+        self.prober = prober
+        self.logger = logging.getLogger('Wizard')
+
+        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+        #self.parent.setMinimumWidth(780)
+        self.parent.setMaximumHeight(900)
+        self.parent.setMinimumHeight(900)
+
+        self.imgf = f"{image_root}/wizard_img"
+
+        # Stores all included graphics for later accessing via the resize Event
+        self.graphics = []
+
+    # ==================================================================================================================
+    # For adding UI Elements
+    # ==================================================================================================================
+    def add_graphics(self, path, max_width=None):
+        print(f"Added {path}")
+        graphics = QLabel(self)
+        pixmap = QPixmap(str(pathlib.PurePosixPath(path)))
+        self._resize_graphics_on_resize_event(graphics, pixmap, max_width=max_width)
+        self.graphics.append({"graphics": graphics, "pixmap": pixmap})
+        return graphics
+
+    def add_task(self, title, description, task_desc) -> (QWidget, QCheckBox):
+        widget = QWidget()
+        layout = QVBoxLayout()
+        widget.setLayout(layout)
+
+        task = QCheckBox(title)
+        task.setStyleSheet(
+            "QCheckBox:unchecked{ color: red; }QCheckBox:checked{ color: black; }")
+        label = QLabel(description)
+        label.setWordWrap(True)
+        layout.addWidget(task)
+        layout.addWidget(label)
+        self.registerField(task_desc, task)
+        return widget, task
+
+    # ==================================================================================================================
+    # Message Boxes
+    # ==================================================================================================================
+    def display_mbox_warning(self, text, title):
+        self.logger.warning(text)
+        warning_dialog = QMessageBox()
+        warning_dialog.setText(text)
+        warning_dialog.setIcon(QMessageBox.Warning)
+        warning_dialog.setWindowTitle(title)
+        warning_dialog.show()
+        warning_dialog.setStandardButtons(QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Abort)
+        btn_ok = warning_dialog.button(QMessageBox.StandardButton.Ok)
+        btn_abort = warning_dialog.button(QMessageBox.StandardButton.Abort)
+        warning_dialog.exec()
+        if warning_dialog.clickedButton() == btn_ok:
+            return True
+        elif warning_dialog.clickedButton() == btn_abort:
+            return False
+
+    def display_mbox_error(self, text, title):
+        self.logger.error(text)
+        warning_dialog = QMessageBox()
+        warning_dialog.setText(text)
+        warning_dialog.setIcon(QMessageBox.Critical)
+        warning_dialog.setWindowTitle(title)
+        warning_dialog.show()
+        warning_dialog.exec()
+
+    def display_mbox_ok(self, text, title):
+        self.logger.error(text)
+        warning_dialog = QMessageBox()
+        warning_dialog.setText(text)
+        warning_dialog.setIcon(QMessageBox.Information)
+        warning_dialog.setWindowTitle(title)
+        warning_dialog.show()
+        warning_dialog.exec()
+
+    # ==================================================================================================================
+    # Prober Controls
+    # ==================================================================================================================
+    def move_chuck_x_y(self, x, y):
+        if self.display_mbox_warning(f"The chuck is about to move relatively {x} in x-direction und {y} y-direction. "
+                                     f"Continue?",
+                                     "Move chuck"):
+            self.prober.move_chuck(x_value=x, y_value=y, pos_ref="R")
+            # Enable the next button when the user has entered a non-empty
+            # string.
+            # self.cb_distance_enterd.setCheckable(True)
+            # self.cb_distance_enterd.setChecked(True)
+            self.completeChanged.emit()
+        else:
+            self.display_mbox_error(text="The movement has been aborted by the user.", title="Movement Aborted.")
+            return
+
+    def area_scan(self, txt_coupled_power: QLabel, checkbox: QCheckBox, threshold: float = -70):
+        x_1, x_2, y_1, y_2, input_power, output_power = self.prober.opt_if.area_scan(True, True)
+        if input_power > threshold and output_power > threshold:
+            checkbox.setCheckable(True)
+            checkbox.setChecked(True)
+            # self.distance_task.setCheckable(False)
+            txt_coupled_power.setText(f'In: {input_power}, Out: {output_power} - Passed/Threshold < -70dB.')
+            self.completeChanged.emit()
+        else:
+            txt_coupled_power.setText(f'In: {input_power}, Out: {output_power} - Not passed/Threshold < -70dB.')
+
+    def move_input_probes_x_y(self, x: float, y: float):
+        self.prober.opt_if.move_optical_probe(0, x, y, pos_ref='R')
+
+    def move_output_probes_x_y(self, x: float, y: float):
+        self.prober.opt_if.move_optical_probe(1, x, y, pos_ref='R')
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def _resize_graphics_on_resize_event(self, graphics, pixmap, max_width=None):
+
+        aspect_ratio = pixmap.height() / pixmap.width()
+        if max_width is None:
+            max_width = int(self.parent.width()*0.95)
+        max_height = np.floor(aspect_ratio * max_width)
+        # print(f"{aspect_ratio}: {max_width}x{max_height} - {max_height / max_width}")
+
+        graphics.setPixmap(pixmap.scaled(QSize(max_width, max_height),
+                                         Qt.AspectRatioMode.KeepAspectRatio,
+                                         Qt.SmoothTransformation))
+
+    def resizeEvent(self, event: QtGui.QResizeEvent) -> None:
+        # print(self.graphics)
+        for ele in self.graphics:
+            self._resize_graphics_on_resize_event(ele['graphics'], ele['pixmap'])
diff --git a/src/FlexSensor/InitialSetupWizard/pages/tmp.txt b/src/FlexSensor/InitialSetupWizard/pages/tmp.txt
new file mode 100644
index 0000000000000000000000000000000000000000..24c71afe88dd6af291a554f0974f24ced2974318
--- /dev/null
+++ b/src/FlexSensor/InitialSetupWizard/pages/tmp.txt
@@ -0,0 +1,25 @@
+task_move_chuck, _ = self.add_task(
+    "1.  Move chuck to the 'mark'",
+    "Use the same 'mark' in the Klayout file and on the wafer. Usually the die's edge is "
+    "a good point. Move your chuck, thus the yellow cross precisely matches "
+    "the selected mark.", "task_move_chuck*")
+layout.addWidget(task_move_chuck)
+
+
+
+
+
+
+task_set_chuck_home_position, _ = self.add_task(
+    "2.  Set Chuck Home position",
+    "Use the 'Set to Current Position' to the left to reset the "
+    "prober's coordinates to (0,0,Z)",
+    "task_set_chuck_home_position*")
+layout.addWidget(task_set_chuck_home_position)
+layout.addWidget(self.add_graphics(path=f'{self.imgf}/1_placed_at_origin_cut.JPG'))
+
+
+
+label2 = QLabel("The Prober's coordinates are now at zero.")
+label2.setWordWrap(True)
+layout.addWidget(label2)
\ No newline at end of file
diff --git a/src/FlexSensor/MainWindow/__init__.py b/src/FlexSensor/MainWindow/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/controller/MainThreadController.py b/src/FlexSensor/MainWindow/controller/MainThreadController.py
new file mode 100644
index 0000000000000000000000000000000000000000..47a94951948b33be77f76d7a86bf3829c8b509b7
--- /dev/null
+++ b/src/FlexSensor/MainWindow/controller/MainThreadController.py
@@ -0,0 +1,99 @@
+import logging
+
+from PySide6.QtCore import QThread
+
+import ConfigHandler as Config
+import Laser as Laser
+import AD2CaptDevice as AD2Dev
+import Prober as Prober
+import MeasurementEvaluationTool
+
+from MainWindow.model.MainThreadModel import MainThreadModel
+from MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
+from Prober.controller.ProberController import ProberController
+
+
+class MainThreadController(object):
+    def __init__(self, model: MainThreadModel):
+        self.logger = logging.getLogger("MainThread")
+        self._model = model
+
+        # self.model._laser_controller.connect_device(self._vaut_config.laser_config.get_port())
+
+        mypath = (
+            r'F:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement')
+
+        # Device init: Connect signals and slots
+        self._device_initialization()
+
+        # Load the measurement routine
+        self.model.measurement_routine = self._load_measurement_routine()
+
+        # Thread for the measurement routine
+        self.measurement_thread = QThread()
+
+        # Create the working folders
+        self._create_working_folders()
+
+    @property
+    def model(self) -> MainThreadModel:
+        return self._model
+
+    def start_measurement_routine(self):
+        # 1. Create all working folders
+        self._create_working_folders()
+        self._move_measurement_routine_thread(self.model.measurement_routine)
+        self.measurement_thread.start()
+        self.logger.info("Started worker thread for running the measurement routine.")
+
+        if self.measurement_thread.isRunning():
+            self.logger.debug("Thread is running.")
+
+    def _create_working_folders(self):
+        """Creates all working folders to store the measurement data.
+        """
+        self.model.vaut_config.setup_folders()
+
+    def _move_measurement_routine_thread(self, measurement_routine):
+        measurement_routine.moveToThread(self.measurement_thread)
+        self.measurement_thread.started.connect(measurement_routine.run)
+        self.logger.debug("Moved worker/measurement routine to thread and connected the signals.")
+
+
+    def _load_measurement_routine(self) -> MeasurementRoutine:
+        """
+            Loads the measurement routine and initializes it.
+
+            Returns:
+                MeasurementRoutine: The measurement routine.
+
+            Raises:
+                Exception: If some or all devices have not been initialized.
+        """
+        if not self.device_are_init:
+            raise Exception("Some or all devices have not been initialized. First call `_device_initialization()`!")
+
+        measurement_routine = MeasurementRoutine(
+            self.model.laser_controller,
+            self.model.ad2_controller,
+            self.model.prober_controller,
+            self.model.vaut_config)
+        self.logger.debug("Initialized MeasurementRoutine.")
+        return measurement_routine
+
+    def _device_initialization(self):
+        """
+            Initializes all devices and connects the signals and slots.
+        """
+        self.model.ad2_controller.connect_device(0)
+        # # Connect the required signals and slots
+        # self.model.laser_model.signals.laser_ready_for_sweep_changed.connect(
+        #     self.model.ad2_controller.start_capture_flag)
+        #
+        # self.model.ad2_model.signals.device_ready_changed.connect(
+        #     self.model.laser_controller.start_wavelength_sweep)
+        #
+        # self.model.laser_model.signals.wavelength_sweep_running_changed.connect(
+        #     self.model.ad2_controller.set_ad2_acq_status)
+
+        self.device_are_init = True
diff --git a/src/FlexSensor/MainWindow/controller/__init__.py b/src/FlexSensor/MainWindow/controller/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/model/MainThreadModel.py b/src/FlexSensor/MainWindow/model/MainThreadModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c4a7c9aace1588fe6bd8d7dac3de035088606df
--- /dev/null
+++ b/src/FlexSensor/MainWindow/model/MainThreadModel.py
@@ -0,0 +1,170 @@
+from PySide6.QtCore import QObject, Signal
+
+import Laser as Laser
+import AD2CaptDevice as AD2Dev
+import Prober as Prober
+import MeasurementEvaluationTool as met
+import ConfigHandler as Config
+from MeasurementRoutines.MeasurementRoutine import MeasurementRoutine
+
+
+class MainThreadSignals(QObject):
+    # Signals for the main thread
+    vaut_config_changed = Signal(Config.VAutomatorConfig)
+    laser_changed = Signal(Laser.Model, Laser.Controller, Laser.ControlWindow)
+    ad2_changed = Signal(AD2Dev.Model, AD2Dev.Controller, AD2Dev.ControlWindow)
+    prober_changed = Signal(Prober.Model, Prober.Controller, Prober.ControlWindow)
+
+    measurement_routine_changed = Signal(MeasurementRoutine)
+
+class MainThreadModel(QObject):
+
+    def __init__(self, vaut_config: Config.VAutomatorConfig):
+        super().__init__()
+
+        self.signals = MainThreadSignals()
+
+        self._vaut_config: Config.VAutomatorConfig = vaut_config
+
+        self._measurement_routine: MeasurementRoutine = None
+
+
+
+        self._ad2_model: AD2Dev.Model = AD2Dev.Model(self.vaut_config.ad2_device_config)
+        self._ad2_controller: AD2Dev.Controller = AD2Dev.Controller(
+            self._ad2_model)
+        self._ad2_window: AD2Dev.ControlWindow = AD2Dev.ControlWindow(
+            self._ad2_model, self._ad2_controller)
+
+        # Devices
+        self._laser_model: Laser.Model = Laser.Model(self.vaut_config.laser_config)
+        self._laser_controller: Laser.Controller = Laser.Controller(self._laser_model, self._ad2_controller)
+
+        self._laser_window: Laser.ControlWindow = Laser.ControlWindow(
+            self._laser_model,
+            self._laser_controller)
+
+        self._prober_model: Prober.Model = Prober.Model()
+        self._prober_controller: Prober.Controller = Prober.Controller(
+            self._prober_model,
+            self.vaut_config)
+        self._prober_window: Prober.ControlWindow = Prober.ControlWindow(
+            self._prober_model,
+            self._prober_controller)
+
+        # Widgets
+        self.mea_eval_tool_model: met.Model  = met.Model()
+        self.mea_eval_tool_controller: met.Controller = met.Controller(
+            self.mea_eval_tool_model)
+        self.mea_eval_tool_window: met.View = met.View(
+            self.mea_eval_tool_model,
+            self.mea_eval_tool_controller)
+
+    # Implement all getter and setter methods for the model here
+    @property
+    def vaut_config(self) -> Config.VAutomatorConfig:
+        return self._vaut_config
+
+    @vaut_config.setter
+    def vaut_config(self, value: Config.VAutomatorConfig):
+        self._vaut_config = value
+        self.signals.vaut_config_changed.emit(self.vaut_config)
+
+    @property
+    def laser_model(self) -> Laser.Model:
+        return self._laser_model
+
+    @laser_model.setter
+    def laser_model(self, value: Laser.Model):
+        self._laser_model = value
+        self.signals.laser_changed.emit(self.laser_model, self.laser_controller, self.laser_window)
+
+
+    @property
+    def laser_controller(self) -> Laser.Controller:
+        return self._laser_controller
+
+    @laser_controller.setter
+    def laser_controller(self, value: Laser.Controller):
+        self._laser_controller = value
+        self.signals.laser_changed.emit(self.laser_model, self.laser_controller, self.laser_window)
+
+    @property
+    def laser_window(self) -> Laser.ControlWindow:
+        return self._laser_window
+
+    @laser_window.setter
+    def laser_window(self, value: Laser.ControlWindow):
+        self._laser_window = value
+        self.signals.laser_changed.emit(self.laser_model, self.laser_controller, self.laser_window)
+
+
+    @property
+    def ad2_model(self) -> AD2Dev.Model:
+        return self._ad2_model
+
+    @ad2_model.setter
+    def ad2_model(self, value: AD2Dev.Model):
+        self._ad2_model = value
+        self.signals.ad2_changed.emit(self.ad2_model, self.ad2_controller, self.ad2_window)
+
+    @property
+    def ad2_controller(self) -> AD2Dev.Controller:
+        return self._ad2_controller
+
+    @ad2_controller.setter
+    def ad2_controller(self, value: AD2Dev.Controller):
+        self._ad2_controller = value
+        self.signals.ad2_changed.emit(self.ad2_model, self.ad2_controller, self.ad2_window)
+
+    @property
+    def ad2_window(self) -> AD2Dev.ControlWindow:
+        return self._ad2_window
+
+    @ad2_window.setter
+    def ad2_window(self, value: AD2Dev.ControlWindow):
+        self._ad2_window = value
+        self.signals.ad2_changed.emit(self.ad2_model, self.ad2_controller, self.ad2_window)
+
+    @property
+    def prober_model(self) -> Prober.Model:
+        return self._prober_model
+
+    @prober_model.setter
+    def prober_model(self, value: Prober.Model):
+        self._prober_model = value
+        self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
+
+    @property
+    def prober_controller(self) -> Prober.Controller:
+        return self._prober_controller
+
+    @prober_controller.setter
+    def prober_controller(self, value: Prober.Controller):
+        self._prober_controller = value
+        self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
+
+    @property
+    def prober_window(self) -> Prober.ControlWindow:
+        return self._prober_window
+
+    @prober_window.setter
+    def prober_window(self, value: Prober.ControlWindow):
+        self._prober_window = value
+        self.signals.prober_changed.emit(self.prober_model, self.prober_controller, self.prober_window)
+
+
+    @property
+    def measurement_routine(self) -> MeasurementRoutine:
+        return self._measurement_routine
+
+    @measurement_routine.setter
+    def measurement_routine(self, value: MeasurementRoutine):
+        self._measurement_routine = value
+        self.signals.measurement_routine_changed.emit(self.measurement_routine)
+
+
+
+
+
+
diff --git a/src/FlexSensor/MainWindow/model/__init__.py b/src/FlexSensor/MainWindow/model/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/resources/MainView.ui b/src/FlexSensor/MainWindow/resources/MainView.ui
new file mode 100644
index 0000000000000000000000000000000000000000..3cb89cb8e02edb91db7c753b193dfc886fd4d7a0
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/MainView.ui
@@ -0,0 +1,2608 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <author>Wanderson M. Pimenta</author>
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1085</width>
+    <height>753</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>940</width>
+    <height>560</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <property name="toolTipDuration">
+   <number>-9</number>
+  </property>
+  <property name="styleSheet">
+   <string notr="true"/>
+  </property>
+  <widget class="QWidget" name="styleSheet">
+   <property name="maximumSize">
+    <size>
+     <width>16777214</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <property name="toolTipDuration">
+    <number>0</number>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">/* /////////////////////////////////////////////////////////////////////////////////////////////////
+
+SET APP STYLESHEET - FULL STYLES HERE
+DARK THEME - DRACULA COLOR BASED
+
+///////////////////////////////////////////////////////////////////////////////////////////////// */
+
+QWidget{
+	color: rgb(221, 221, 221);
+	font: 10pt &quot;Segoe UI&quot;;
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Tooltip */
+QToolTip {
+	color: #ffffff;
+	background-color: rgba(33, 37, 43, 180);
+	border: 1px solid rgb(44, 49, 58);
+	background-image: none;
+	background-position: left center;
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 2px solid rgb(255, 121, 198);
+	text-align: left;
+	padding-left: 8px;
+	margin: 0px;
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Bg App */
+#bgApp {	
+	background-color: rgb(40, 44, 52);
+	border: 1px solid rgb(44, 49, 58);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Left Menu */
+#leftMenuBg {	
+	background-color: rgb(33, 37, 43);
+}
+#topLogo {
+	background-color: rgb(33, 37, 43);
+	border-image: url(:/images/images/images/FlexSensorIcon.png) 10 0 0 0 strech strech;
+	background-position: centered;
+	background-repeat: no-repeat;
+}
+#titleLeftApp { font: 63 12pt &quot;Segoe UI Semibold&quot;; }
+#titleLeftDescription { font: 8pt &quot;Segoe UI&quot;; color: rgb(189, 147, 249); }
+
+/* MENUS */
+
+
+
+#topMenu .QPushButton {	
+	background-position: left center;
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 22px solid transparent;
+	background-color: transparent;
+	text-align: left;
+	padding-left: 44px;
+}
+#topMenu .QPushButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#topMenu .QPushButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+#bottomMenu .QPushButton {	
+	background-position: left center;
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 20px solid transparent;
+	background-color:transparent;
+	text-align: left;
+	padding-left: 44px;
+}
+#bottomMenu .QPushButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#bottomMenu .QPushButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+#leftMenuFrame{
+	border-top: 3px solid rgb(44, 49, 58);
+}
+
+/* Toggle Button */
+#toggleButton {
+	background-position: left center;
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 20px solid transparent;
+	background-color: rgb(37, 41, 48);
+	text-align: left;
+	padding-left: 44px;
+	color: rgb(113, 126, 149);
+}
+#toggleButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#toggleButton:pressed {
+	background-color: rgb(189, 147, 249);
+}
+
+/* Title Menu */
+/*#titleRightInfo { padding-left: 10px; }*/
+
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Extra Tab */
+#extraLeftBox {	
+	background-color: rgb(44, 49, 58);
+}
+#extraTopBg{	
+	background-color: rgb(189, 147, 249)
+}
+
+/* Icon */
+#extraIcon {
+	background-position: center;
+	background-repeat: no-repeat;
+	background-image: url(:/icons/images/icons/icon_settings.png);
+}
+
+/* Label */
+#extraLabel { color: rgb(255, 255, 255); }
+
+/* Btn Close */
+#extraCloseColumnBtn { background-color: rgba(255, 255, 255, 0); border: none;  border-radius: 5px; }
+#extraCloseColumnBtn:hover { background-color: rgb(196, 161, 249); border-style: solid; border-radius: 4px; }
+#extraCloseColumnBtn:pressed { background-color: rgb(180, 141, 238); border-style: solid; border-radius: 4px; }
+
+/* Extra Content */
+#extraContent{
+	border-top: 3px solid rgb(40, 44, 52);
+}
+
+/* Extra Top Menus */
+#extraTopMenu .QPushButton {
+	/*background-position: left center;*/
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 22px solid transparent;
+	background-color:transparent;
+	text-align: left;
+	padding-left: 44px;
+}
+#extraTopMenu .QPushButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#extraTopMenu .QPushButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+
+
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Content App */
+#contentTopBg{	
+	background-color: rgb(33, 37, 43);
+}
+#contentBottom{
+	border-top: 3px solid rgb(44, 49, 58);
+}
+
+/* Top Buttons */
+#rightButtons .QPushButton { background-color: rgba(255, 255, 255, 0); border: none;  border-radius: 5px; }
+#rightButtons .QPushButton:hover { background-color: rgb(44, 49, 57); border-style: solid; border-radius: 4px; }
+#rightButtons .QPushButton:pressed { background-color: rgb(23, 26, 30); border-style: solid; border-radius: 4px; }
+
+/* Theme Settings */
+#extraRightBox { background-color: rgb(44, 49, 58); }
+#themeSettingsTopDetail { background-color: rgb(189, 147, 249); }
+
+/* Bottom Bar */
+#bottomBar { background-color: rgb(44, 49, 58); }
+#bottomBar QLabel { font-size: 11px; color: rgb(113, 126, 149); padding-left: 10px; padding-right: 10px; padding-bottom: 2px; }
+
+/* CONTENT SETTINGS */
+/* MENUS */
+#contentSettings .QPushButton {	
+	background-position: left center;
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 22px solid transparent;
+	background-color:transparent;
+	text-align: left;
+	padding-left: 44px;
+}
+#contentSettings .QPushButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#contentSettings .QPushButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+QTableWidget */
+QTableWidget {	
+	background-color: transparent;
+	padding: 10px;
+	border-radius: 5px;
+	gridline-color: rgb(44, 49, 58);
+	border-bottom: 1px solid rgb(44, 49, 60);
+}
+QTableWidget::item{
+	border-color: rgb(44, 49, 60);
+	padding-left: 5px;
+	padding-right: 5px;
+	gridline-color: rgb(44, 49, 60);
+}
+QTableWidget::item:selected{
+	background-color: rgb(189, 147, 249);
+}
+QHeaderView::section{
+	background-color: rgb(33, 37, 43);
+	max-width: 30px;
+	border: 1px solid rgb(44, 49, 58);
+	border-style: none;
+    border-bottom: 1px solid rgb(44, 49, 60);
+    border-right: 1px solid rgb(44, 49, 60);
+}
+QTableWidget::horizontalHeader {	
+	background-color: rgb(33, 37, 43);
+}
+QHeaderView::section:horizontal
+{
+    border: 1px solid rgb(33, 37, 43);
+	background-color: rgb(33, 37, 43);
+	padding: 3px;
+	border-top-left-radius: 7px;
+    border-top-right-radius: 7px;
+}
+QHeaderView::section:vertical
+{
+    border: 1px solid rgb(44, 49, 60);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+LineEdit */
+QLineEdit {
+	background-color: rgb(33, 37, 43);
+	border-radius: 5px;
+	border: 2px solid rgb(33, 37, 43);
+	padding-left: 10px;
+	selection-color: rgb(255, 255, 255);
+	selection-background-color: rgb(255, 121, 198);
+}
+QLineEdit:hover {
+	border: 2px solid rgb(64, 71, 88);
+}
+QLineEdit:focus {
+	border: 2px solid rgb(91, 101, 124);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+PlainTextEdit */
+QPlainTextEdit {
+	background-color: rgb(27, 29, 35);
+	border-radius: 5px;
+	padding: 10px;
+	selection-color: rgb(255, 255, 255);
+	selection-background-color: rgb(255, 121, 198);
+}
+QPlainTextEdit  QScrollBar:vertical {
+    width: 8px;
+ }
+QPlainTextEdit  QScrollBar:horizontal {
+    height: 8px;
+ }
+QPlainTextEdit:hover {
+	border: 2px solid rgb(64, 71, 88);
+}
+QPlainTextEdit:focus {
+	border: 2px solid rgb(91, 101, 124);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+ScrollBars */
+QScrollBar:horizontal {
+    border: none;
+    background: rgb(52, 59, 72);
+    height: 8px;
+    margin: 0px 21px 0 21px;
+	border-radius: 0px;
+}
+QScrollBar::handle:horizontal {
+    background: rgb(189, 147, 249);
+    min-width: 25px;
+	border-radius: 4px
+}
+QScrollBar::add-line:horizontal {
+    border: none;
+    background: rgb(55, 63, 77);
+    width: 20px;
+	border-top-right-radius: 4px;
+    border-bottom-right-radius: 4px;
+    subcontrol-position: right;
+    subcontrol-origin: margin;
+}
+QScrollBar::sub-line:horizontal {
+    border: none;
+    background: rgb(55, 63, 77);
+    width: 20px;
+	border-top-left-radius: 4px;
+    border-bottom-left-radius: 4px;
+    subcontrol-position: left;
+    subcontrol-origin: margin;
+}
+QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal
+{
+     background: none;
+}
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
+{
+     background: none;
+}
+ QScrollBar:vertical {
+	border: none;
+    background: rgb(52, 59, 72);
+    width: 8px;
+    margin: 21px 0 21px 0;
+	border-radius: 0px;
+ }
+ QScrollBar::handle:vertical {	
+	background: rgb(189, 147, 249);
+    min-height: 25px;
+	border-radius: 4px
+ }
+ QScrollBar::add-line:vertical {
+     border: none;
+    background: rgb(55, 63, 77);
+     height: 20px;
+	border-bottom-left-radius: 4px;
+    border-bottom-right-radius: 4px;
+     subcontrol-position: bottom;
+     subcontrol-origin: margin;
+ }
+ QScrollBar::sub-line:vertical {
+	border: none;
+    background: rgb(55, 63, 77);
+     height: 20px;
+	border-top-left-radius: 4px;
+    border-top-right-radius: 4px;
+     subcontrol-position: top;
+     subcontrol-origin: margin;
+ }
+ QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
+     background: none;
+ }
+
+ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
+     background: none;
+ }
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+CheckBox */
+QCheckBox::indicator {
+    border: 3px solid rgb(52, 59, 72);
+	width: 15px;
+	height: 15px;
+	border-radius: 10px;
+    background: rgb(44, 49, 60);
+}
+QCheckBox::indicator:hover {
+    border: 3px solid rgb(58, 66, 81);
+}
+QCheckBox::indicator:checked {
+    background: 3px solid rgb(52, 59, 72);
+	border: 3px solid rgb(52, 59, 72);	
+	background-image: url(:/icons/images/icons/cil-check-alt.png);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+RadioButton */
+QRadioButton::indicator {
+    border: 3px solid rgb(52, 59, 72);
+	width: 15px;
+	height: 15px;
+	border-radius: 10px;
+    background: rgb(44, 49, 60);
+}
+QRadioButton::indicator:hover {
+    border: 3px solid rgb(58, 66, 81);
+}
+QRadioButton::indicator:checked {
+    background: 3px solid rgb(94, 106, 130);
+	border: 3px solid rgb(52, 59, 72);	
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+ComboBox */
+QComboBox{
+	background-color: rgb(27, 29, 35);
+	border-radius: 5px;
+	border: 2px solid rgb(33, 37, 43);
+	padding: 5px;
+	padding-left: 10px;
+}
+QComboBox:hover{
+	border: 2px solid rgb(64, 71, 88);
+}
+QComboBox::drop-down {
+	subcontrol-origin: padding;
+	subcontrol-position: top right;
+	width: 25px; 
+	border-left-width: 3px;
+	border-left-color: rgba(39, 44, 54, 150);
+	border-left-style: solid;
+	border-top-right-radius: 3px;
+	border-bottom-right-radius: 3px;	
+	background-image: url(:/icons/images/icons/cil-arrow-bottom.png);
+	background-position: center;
+	background-repeat: no-reperat;
+ }
+QComboBox QAbstractItemView {
+	color: rgb(255, 121, 198);	
+	background-color: rgb(33, 37, 43);
+	padding: 10px;
+	selection-background-color: rgb(39, 44, 54);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Sliders */
+QSlider::groove:horizontal {
+    border-radius: 5px;
+    height: 10px;
+	margin: 0px;
+	background-color: rgb(52, 59, 72);
+}
+QSlider::groove:horizontal:hover {
+	background-color: rgb(55, 62, 76);
+}
+QSlider::handle:horizontal {
+    background-color: rgb(189, 147, 249);
+    border: none;
+    height: 10px;
+    width: 10px;
+    margin: 0px;
+	border-radius: 5px;
+}
+QSlider::handle:horizontal:hover {
+    background-color: rgb(195, 155, 255);
+}
+QSlider::handle:horizontal:pressed {
+    background-color: rgb(255, 121, 198);
+}
+
+QSlider::groove:vertical {
+    border-radius: 5px;
+    width: 10px;
+    margin: 0px;
+	background-color: rgb(52, 59, 72);
+}
+QSlider::groove:vertical:hover {
+	background-color: rgb(55, 62, 76);
+}
+QSlider::handle:vertical {
+    background-color: rgb(189, 147, 249);
+	border: none;
+    height: 10px;
+    width: 10px;
+    margin: 0px;
+	border-radius: 5px;
+}
+QSlider::handle:vertical:hover {
+    background-color: rgb(195, 155, 255);
+}
+QSlider::handle:vertical:pressed {
+    background-color: rgb(255, 121, 198);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+CommandLinkButton */
+QCommandLinkButton {	
+	color: rgb(255, 121, 198);
+	border-radius: 5px;
+	padding: 5px;
+	color: rgb(255, 170, 255);
+}
+QCommandLinkButton:hover {	
+	color: rgb(255, 170, 255);
+	background-color: rgb(44, 49, 60);
+}
+QCommandLinkButton:pressed {	
+	color: rgb(189, 147, 249);
+	background-color: rgb(52, 58, 71);
+}
+
+/* /////////////////////////////////////////////////////////////////////////////////////////////////
+Button */
+#pagesContainer QPushButton {
+	border: 2px solid rgb(52, 59, 72);
+	border-radius: 5px;	
+	background-color: rgb(52, 59, 72);
+}
+#pagesContainer QPushButton:hover {
+	background-color: rgb(57, 65, 80);
+	border: 2px solid rgb(61, 70, 86);
+}
+#pagesContainer QPushButton:pressed {	
+	background-color: rgb(35, 40, 49);
+	border: 2px solid rgb(43, 50, 61);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+QToolButton { 
+border-image: url(:/img/btn_mid_0.png);
+text-align: center;
+}
+QToolButton::menu-indicator { image: none; }
+
+
+#menuBar .QPushButton {	
+     background-position: left center;
+     background-repeat: no-repeat;
+	 border: none;
+	 /*border-left: 22px solid transparent;*/
+	 /*text-align: center;*/
+	padding-right: 10px;
+}
+#menuBar .QPushButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#menuBar .QPushButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+
+#menuBar .QToolButton {
+     background-position: left center;
+     background-repeat: no-repeat;
+	 border: none;
+	 /*border-left: 22px solid transparent;*/
+	 /*text-align: center;*/
+	padding-right: 10px;
+}
+#menuBar .QToolButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#menuBar .QToolButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+
+
+#extraMenuBar .QToolButton {
+     background-position: left center;
+     background-repeat: no-repeat;
+	 border: none;
+	 /*border-left: 22px solid transparent;*/
+	 /*text-align: center;*/
+	padding-right: 10px;
+}
+#extraMenuBar .QToolButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#extraMenuBar .QToolButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+
+
+#extraMenuBar .QPushButton {
+   /*background-position: left center;*/
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 22px solid transparent;
+	text-align: center;
+	/*padding-left: 44px;*/
+}
+#extraMenuBar .QPushButton:hover {
+	background-color: rgb(40, 44, 52);
+}
+#extraMenuBar .QPushButton:pressed {	
+	background-color: rgb(189, 147, 249);
+	color: rgb(255, 255, 255);
+}
+
+
+
+
+/* QMenu ------------------------------------------------------------------
+
+examples: https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qmenu
+
+--------------------------------------------------------------------------- */
+QMenu {
+    background-color: rgb(40, 44, 52);
+    margin: 2px; /* some spacing around the menu */
+}
+
+QMenu::item {
+    padding: 2px 25px 2px 20px;
+    border: 1px solid transparent; /* reserve space for selection border */
+}
+
+QMenu::item:selected {
+    border-color: darkblue;
+    background: rgba(100, 100, 100, 150);
+}
+
+QMenu::icon:checked { /* appearance of a 'checked' icon */
+    background: gray;
+    border: 1px inset gray;
+    position: absolute;
+    top: 1px;
+    right: 1px;
+    bottom: 1px;
+    left: 1px;
+}
+
+QMenu::separator {
+    height: 2px;
+    background: lightblue;
+    margin-left: 10px;
+    margin-right: 5px;
+}
+
+QMenu::indicator {
+    width: 13px;
+    height: 13px;
+}
+
+/*
+
+QMenu::indicator:non-exclusive:unchecked {
+    image: url(:/images/checkbox_unchecked.png);
+}
+
+QMenu::indicator:non-exclusive:unchecked:selected {
+    image: url(:/images/checkbox_unchecked_hover.png);
+}
+
+QMenu::indicator:non-exclusive:checked {
+    image: url(:/images/checkbox_checked.png);
+}
+
+QMenu::indicator:non-exclusive:checked:selected {
+    image: url(:/images/checkbox_checked_hover.png);
+}
+
+
+QMenu::indicator:exclusive:unchecked {
+    image: url(:/images/radiobutton_unchecked.png);
+}
+
+QMenu::indicator:exclusive:unchecked:selected {
+    image: url(:/images/radiobutton_unchecked_hover.png);
+}
+
+QMenu::indicator:exclusive:checked {
+    image: url(:/images/radiobutton_checked.png);
+}
+
+QMenu::indicator:exclusive:checked:selected {
+    image: url(:/images/radiobutton_checked_hover.png);
+}*/
+
+QTabWidget::pane {
+  border: 1px solid lightgray;
+  top:-1px; 
+  background:  rgb(40, 44, 52); 
+} 
+
+QTabBar::tab {
+  background: rgb(40, 44, 52);; 
+  border: 1px solid lightgray; 
+  padding: 2px;
+	padding-left: 10px;
+	padding-right: 10px;
+} 
+
+QTabBar::tab:selected { 
+  background:  rgb(189, 147, 249);
+  margin-bottom: -1px; 
+}</string>
+   </property>
+   <layout class="QVBoxLayout" name="appMargins">
+    <property name="spacing">
+     <number>0</number>
+    </property>
+    <property name="leftMargin">
+     <number>10</number>
+    </property>
+    <property name="topMargin">
+     <number>10</number>
+    </property>
+    <property name="rightMargin">
+     <number>10</number>
+    </property>
+    <property name="bottomMargin">
+     <number>10</number>
+    </property>
+    <item>
+     <widget class="QFrame" name="bgApp">
+      <property name="toolTipDuration">
+       <number>0</number>
+      </property>
+      <property name="styleSheet">
+       <string notr="true"/>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::NoFrame</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Plain</enum>
+      </property>
+      <layout class="QHBoxLayout" name="appLayout">
+       <property name="spacing">
+        <number>0</number>
+       </property>
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QFrame" name="leftMenuBg">
+         <property name="minimumSize">
+          <size>
+           <width>60</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>60</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::NoFrame</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Raised</enum>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_3">
+          <property name="spacing">
+           <number>0</number>
+          </property>
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QFrame" name="topLogoInfo">
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>50</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>16777215</width>
+              <height>50</height>
+             </size>
+            </property>
+            <property name="frameShape">
+             <enum>QFrame::NoFrame</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <widget class="QLabel" name="titleLeftApp">
+             <property name="geometry">
+              <rect>
+               <x>60</x>
+               <y>3</y>
+               <width>160</width>
+               <height>20</height>
+              </rect>
+             </property>
+             <property name="font">
+              <font>
+               <pointsize>12</pointsize>
+               <italic>false</italic>
+               <bold>false</bold>
+              </font>
+             </property>
+             <property name="text">
+              <string>PyDracula</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+             </property>
+            </widget>
+            <widget class="QFrame" name="topLogo">
+             <property name="geometry">
+              <rect>
+               <x>10</x>
+               <y>10</y>
+               <width>32</width>
+               <height>32</height>
+              </rect>
+             </property>
+             <property name="minimumSize">
+              <size>
+               <width>32</width>
+               <height>32</height>
+              </size>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>32</width>
+               <height>32</height>
+              </size>
+             </property>
+             <property name="frameShape">
+              <enum>QFrame::NoFrame</enum>
+             </property>
+             <property name="frameShadow">
+              <enum>QFrame::Raised</enum>
+             </property>
+            </widget>
+            <widget class="QLabel" name="titleLeftDescription">
+             <property name="geometry">
+              <rect>
+               <x>60</x>
+               <y>22</y>
+               <width>160</width>
+               <height>16</height>
+              </rect>
+             </property>
+             <property name="maximumSize">
+              <size>
+               <width>16777215</width>
+               <height>16</height>
+              </size>
+             </property>
+             <property name="font">
+              <font>
+               <pointsize>8</pointsize>
+               <italic>false</italic>
+               <bold>false</bold>
+              </font>
+             </property>
+             <property name="text">
+              <string>Modern GUI / Flat Style</string>
+             </property>
+             <property name="alignment">
+              <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+             </property>
+            </widget>
+           </widget>
+          </item>
+          <item>
+           <widget class="QFrame" name="leftMenuFrame">
+            <property name="enabled">
+             <bool>true</bool>
+            </property>
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>0</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>16777215</width>
+              <height>16777215</height>
+             </size>
+            </property>
+            <property name="toolTipDuration">
+             <number>0</number>
+            </property>
+            <property name="layoutDirection">
+             <enum>Qt::LeftToRight</enum>
+            </property>
+            <property name="frameShape">
+             <enum>QFrame::NoFrame</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <layout class="QVBoxLayout" name="verticalMenuLayout">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <widget class="QFrame" name="toggleBox">
+               <property name="maximumSize">
+                <size>
+                 <width>16777215</width>
+                 <height>45</height>
+                </size>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QVBoxLayout" name="verticalLayout_4">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QPushButton" name="toggleButton">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/icon_menu.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Hide</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item>
+              <widget class="QFrame" name="topMenu">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>10</height>
+                </size>
+               </property>
+               <property name="layoutDirection">
+                <enum>Qt::LeftToRight</enum>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QVBoxLayout" name="verticalLayout_8">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QPushButton" name="btn_start_measuring_routine">
+                  <property name="minimumSize">
+                   <size>
+                    <width>60</width>
+                    <height>60</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>16660</width>
+                    <height>60</height>
+                   </size>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">QPushButton {	
+	background-position: left center;
+    background-repeat: no-repeat;
+	border: none;
+	border-left: 22px solid transparent;
+	background-color: rgb(36, 209, 21);
+	text-align: left;
+	padding-left: 44px;
+    background-image: url(:/icons/images/icons/cil-media-play.png);
+}
+
+QPushButton:hover {
+	background-color: rgb(26, 153, 16);
+}
+
+QPushButton:pressed {	
+	background-color: rgb(20, 120, 12);
+	color: rgb(255, 255, 255);
+}
+
+
+</string>
+                  </property>
+                  <property name="text">
+                   <string>PushButton</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_home">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>16777215</width>
+                    <height>16777215</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-home.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Home</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_adc_control">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-signal-cellular-3.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>ADC Control</string>
+                  </property>
+                  <property name="iconSize">
+                   <size>
+                    <width>16</width>
+                    <height>16</height>
+                   </size>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_laser_control">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-lightbulb.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Laser Control</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_probe_control">
+                  <property name="enabled">
+                   <bool>true</bool>
+                  </property>
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-action-redo.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Probe Control</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_measured_data">
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-description.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Measured Data</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_exit">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>60</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-x.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Exit</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item>
+              <widget class="QFrame" name="bottomMenu">
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QVBoxLayout" name="verticalLayout_9">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QPushButton" name="toggleLeftBox">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/icon_settings.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Left Box</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QFrame" name="extraLeftBox">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>0</width>
+           <height>16777215</height>
+          </size>
+         </property>
+         <property name="frameShape">
+          <enum>QFrame::NoFrame</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Raised</enum>
+         </property>
+         <property name="lineWidth">
+          <number>0</number>
+         </property>
+         <layout class="QVBoxLayout" name="extraColumLayout">
+          <property name="spacing">
+           <number>0</number>
+          </property>
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QFrame" name="extraTopBg">
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>50</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>16777215</width>
+              <height>50</height>
+             </size>
+            </property>
+            <property name="frameShape">
+             <enum>QFrame::NoFrame</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <layout class="QVBoxLayout" name="verticalLayout_5">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <layout class="QGridLayout" name="extraTopLayout">
+               <property name="leftMargin">
+                <number>10</number>
+               </property>
+               <property name="rightMargin">
+                <number>10</number>
+               </property>
+               <property name="horizontalSpacing">
+                <number>10</number>
+               </property>
+               <property name="verticalSpacing">
+                <number>0</number>
+               </property>
+               <item row="0" column="0">
+                <widget class="QFrame" name="extraIcon">
+                 <property name="minimumSize">
+                  <size>
+                   <width>20</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>20</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="frameShape">
+                  <enum>QFrame::NoFrame</enum>
+                 </property>
+                 <property name="frameShadow">
+                  <enum>QFrame::Raised</enum>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="1">
+                <widget class="QLabel" name="extraLabel">
+                 <property name="minimumSize">
+                  <size>
+                   <width>150</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="text">
+                  <string>Left Box</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2">
+                <widget class="QPushButton" name="extraCloseColumnBtn">
+                 <property name="minimumSize">
+                  <size>
+                   <width>28</width>
+                   <height>28</height>
+                  </size>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>28</width>
+                   <height>28</height>
+                  </size>
+                 </property>
+                 <property name="cursor">
+                  <cursorShape>PointingHandCursor</cursorShape>
+                 </property>
+                 <property name="toolTip">
+                  <string>Close left box</string>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                 <property name="icon">
+                  <iconset resource="../../resources.qrc">
+                   <normaloff>:/icons/images/icons/icon_close.png</normaloff>:/icons/images/icons/icon_close.png</iconset>
+                 </property>
+                 <property name="iconSize">
+                  <size>
+                   <width>20</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="QFrame" name="extraContent">
+            <property name="frameShape">
+             <enum>QFrame::NoFrame</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <layout class="QVBoxLayout" name="verticalLayout_12">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item alignment="Qt::AlignTop">
+              <widget class="QFrame" name="extraTopMenu">
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QVBoxLayout" name="verticalLayout_11">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QPushButton" name="btn_share">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-share-boxed.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Share</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_adjustments">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-equalizer.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>Adjustments</string>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="btn_more">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>45</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="layoutDirection">
+                   <enum>Qt::LeftToRight</enum>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background-image: url(:/icons/images/icons/cil-layers.png);</string>
+                  </property>
+                  <property name="text">
+                   <string>More</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item>
+              <widget class="QFrame" name="extraCenter">
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QVBoxLayout" name="verticalLayout_10">
+                <item>
+                 <widget class="QTextEdit" name="textEdit">
+                  <property name="minimumSize">
+                   <size>
+                    <width>222</width>
+                    <height>0</height>
+                   </size>
+                  </property>
+                  <property name="styleSheet">
+                   <string notr="true">background: transparent;</string>
+                  </property>
+                  <property name="frameShape">
+                   <enum>QFrame::NoFrame</enum>
+                  </property>
+                  <property name="readOnly">
+                   <bool>true</bool>
+                  </property>
+                  <property name="html">
+                   <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; color:#ff79c6;&quot;&gt;PyDracula&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#ffffff;&quot;&gt;An interface created using Python and PySide (support for PyQt), and with colors based on the Dracula theme created by Zeno Rocha.&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#ffffff;&quot;&gt;MIT License&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#bd93f9;&quot;&gt;Created by: Wanderson M. Pimenta&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; color:#ff79c6;&quot;&gt;Convert UI&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt; color:#ffffff;&quot;&gt;pyside6-uic main.ui &amp;gt; ui_main.py&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600; color:#ff79c6;&quot;&gt;Convert QRC&lt;/span&gt;&lt;/p&gt;
+&lt;p align=&quot;center&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:9pt; color:#ffffff;&quot;&gt;pyside6-rcc resources.qrc -o resources_rc.py&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item>
+              <widget class="QFrame" name="extraBottom">
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QFrame" name="contentBox">
+         <property name="frameShape">
+          <enum>QFrame::NoFrame</enum>
+         </property>
+         <property name="frameShadow">
+          <enum>QFrame::Raised</enum>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_2">
+          <property name="spacing">
+           <number>0</number>
+          </property>
+          <property name="leftMargin">
+           <number>0</number>
+          </property>
+          <property name="topMargin">
+           <number>0</number>
+          </property>
+          <property name="rightMargin">
+           <number>0</number>
+          </property>
+          <property name="bottomMargin">
+           <number>0</number>
+          </property>
+          <item>
+           <widget class="QFrame" name="contentTopBg">
+            <property name="minimumSize">
+             <size>
+              <width>0</width>
+              <height>50</height>
+             </size>
+            </property>
+            <property name="maximumSize">
+             <size>
+              <width>16777215</width>
+              <height>50</height>
+             </size>
+            </property>
+            <property name="frameShape">
+             <enum>QFrame::NoFrame</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <layout class="QHBoxLayout" name="horizontalLayout">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>10</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <widget class="QFrame" name="leftBox">
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+               <property name="focusPolicy">
+                <enum>Qt::NoFocus</enum>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QHBoxLayout" name="horizontalLayout_3">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QFrame" name="verticalFrame">
+                  <layout class="QFormLayout" name="formLayout">
+                   <property name="horizontalSpacing">
+                    <number>0</number>
+                   </property>
+                   <property name="leftMargin">
+                    <number>0</number>
+                   </property>
+                   <property name="topMargin">
+                    <number>0</number>
+                   </property>
+                   <property name="rightMargin">
+                    <number>0</number>
+                   </property>
+                   <property name="bottomMargin">
+                    <number>0</number>
+                   </property>
+                   <item row="1" column="0">
+                    <widget class="QFrame" name="menuBar">
+                     <property name="sizePolicy">
+                      <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+                       <horstretch>0</horstretch>
+                       <verstretch>0</verstretch>
+                      </sizepolicy>
+                     </property>
+                     <property name="minimumSize">
+                      <size>
+                       <width>0</width>
+                       <height>0</height>
+                      </size>
+                     </property>
+                     <property name="focusPolicy">
+                      <enum>Qt::NoFocus</enum>
+                     </property>
+                     <property name="frameShadow">
+                      <enum>QFrame::Raised</enum>
+                     </property>
+                     <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0,0">
+                      <property name="spacing">
+                       <number>0</number>
+                      </property>
+                      <property name="sizeConstraint">
+                       <enum>QLayout::SetDefaultConstraint</enum>
+                      </property>
+                      <property name="leftMargin">
+                       <number>0</number>
+                      </property>
+                      <property name="topMargin">
+                       <number>0</number>
+                      </property>
+                      <property name="rightMargin">
+                       <number>0</number>
+                      </property>
+                      <property name="bottomMargin">
+                       <number>0</number>
+                      </property>
+                      <item>
+                       <widget class="QToolButton" name="menu_file">
+                        <property name="enabled">
+                         <bool>true</bool>
+                        </property>
+                        <property name="sizePolicy">
+                         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+                          <horstretch>0</horstretch>
+                          <verstretch>0</verstretch>
+                         </sizepolicy>
+                        </property>
+                        <property name="minimumSize">
+                         <size>
+                          <width>0</width>
+                          <height>16</height>
+                         </size>
+                        </property>
+                        <property name="maximumSize">
+                         <size>
+                          <width>16777215</width>
+                          <height>16777215</height>
+                         </size>
+                        </property>
+                        <property name="font">
+                         <font>
+                          <pointsize>10</pointsize>
+                          <italic>false</italic>
+                          <bold>false</bold>
+                          <kerning>true</kerning>
+                         </font>
+                        </property>
+                        <property name="mouseTracking">
+                         <bool>true</bool>
+                        </property>
+                        <property name="layoutDirection">
+                         <enum>Qt::LeftToRight</enum>
+                        </property>
+                        <property name="autoFillBackground">
+                         <bool>false</bool>
+                        </property>
+                        <property name="styleSheet">
+                         <string notr="true"/>
+                        </property>
+                        <property name="text">
+                         <string>File</string>
+                        </property>
+                        <property name="checkable">
+                         <bool>false</bool>
+                        </property>
+                        <property name="popupMode">
+                         <enum>QToolButton::InstantPopup</enum>
+                        </property>
+                        <property name="toolButtonStyle">
+                         <enum>Qt::ToolButtonTextOnly</enum>
+                        </property>
+                        <property name="autoRaise">
+                         <bool>true</bool>
+                        </property>
+                       </widget>
+                      </item>
+                      <item>
+                       <widget class="QToolButton" name="menu_edit">
+                        <property name="text">
+                         <string>Edit</string>
+                        </property>
+                       </widget>
+                      </item>
+                      <item>
+                       <widget class="QToolButton" name="menu_run">
+                        <property name="minimumSize">
+                         <size>
+                          <width>0</width>
+                          <height>0</height>
+                         </size>
+                        </property>
+                        <property name="styleSheet">
+                         <string notr="true"/>
+                        </property>
+                        <property name="text">
+                         <string>Run</string>
+                        </property>
+                        <property name="popupMode">
+                         <enum>QToolButton::InstantPopup</enum>
+                        </property>
+                        <property name="toolButtonStyle">
+                         <enum>Qt::ToolButtonTextOnly</enum>
+                        </property>
+                        <property name="autoRaise">
+                         <bool>true</bool>
+                        </property>
+                       </widget>
+                      </item>
+                     </layout>
+                    </widget>
+                   </item>
+                   <item row="0" column="0">
+                    <widget class="QLabel" name="titleRight">
+                     <property name="sizePolicy">
+                      <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
+                       <horstretch>0</horstretch>
+                       <verstretch>0</verstretch>
+                      </sizepolicy>
+                     </property>
+                     <property name="maximumSize">
+                      <size>
+                       <width>16777215</width>
+                       <height>45</height>
+                      </size>
+                     </property>
+                     <property name="font">
+                      <font>
+                       <pointsize>10</pointsize>
+                       <italic>false</italic>
+                       <bold>false</bold>
+                      </font>
+                     </property>
+                     <property name="text">
+                      <string>FlexSensor 6</string>
+                     </property>
+                     <property name="alignment">
+                      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+                     </property>
+                    </widget>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item alignment="Qt::AlignRight">
+              <widget class="QFrame" name="rightButtons">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>28</height>
+                </size>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QHBoxLayout" name="horizontalLayout_2">
+                <property name="spacing">
+                 <number>5</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QPushButton" name="settingsTopBtn">
+                  <property name="minimumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="toolTip">
+                   <string>Settings</string>
+                  </property>
+                  <property name="text">
+                   <string/>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="../../resources.qrc">
+                    <normaloff>:/icons/images/icons/icon_settings.png</normaloff>:/icons/images/icons/icon_settings.png</iconset>
+                  </property>
+                  <property name="iconSize">
+                   <size>
+                    <width>20</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="minimizeAppBtn">
+                  <property name="minimumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="toolTip">
+                   <string>Minimize</string>
+                  </property>
+                  <property name="text">
+                   <string/>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="../../resources.qrc">
+                    <normaloff>:/icons/images/icons/icon_minimize.png</normaloff>:/icons/images/icons/icon_minimize.png</iconset>
+                  </property>
+                  <property name="iconSize">
+                   <size>
+                    <width>20</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="maximizeRestoreAppBtn">
+                  <property name="minimumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>10</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                    <stylestrategy>PreferDefault</stylestrategy>
+                   </font>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="toolTip">
+                   <string>Maximize</string>
+                  </property>
+                  <property name="text">
+                   <string/>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="../../resources.qrc">
+                    <normaloff>:/icons/images/icons/icon_maximize.png</normaloff>:/icons/images/icons/icon_maximize.png</iconset>
+                  </property>
+                  <property name="iconSize">
+                   <size>
+                    <width>20</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QPushButton" name="closeAppBtn">
+                  <property name="minimumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>28</width>
+                    <height>28</height>
+                   </size>
+                  </property>
+                  <property name="cursor">
+                   <cursorShape>PointingHandCursor</cursorShape>
+                  </property>
+                  <property name="toolTip">
+                   <string>Close</string>
+                  </property>
+                  <property name="text">
+                   <string/>
+                  </property>
+                  <property name="icon">
+                   <iconset resource="../../resources.qrc">
+                    <normaloff>:/icons/images/icons/icon_close.png</normaloff>:/icons/images/icons/icon_close.png</iconset>
+                  </property>
+                  <property name="iconSize">
+                   <size>
+                    <width>20</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="QFrame" name="contentBottom">
+            <property name="frameShape">
+             <enum>QFrame::NoFrame</enum>
+            </property>
+            <property name="frameShadow">
+             <enum>QFrame::Raised</enum>
+            </property>
+            <layout class="QVBoxLayout" name="verticalLayout_6">
+             <property name="spacing">
+              <number>0</number>
+             </property>
+             <property name="leftMargin">
+              <number>0</number>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <property name="rightMargin">
+              <number>0</number>
+             </property>
+             <property name="bottomMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <widget class="QFrame" name="content">
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QHBoxLayout" name="horizontalLayout_4">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QFrame" name="pagesContainer">
+                  <property name="styleSheet">
+                   <string notr="true"/>
+                  </property>
+                  <property name="frameShape">
+                   <enum>QFrame::NoFrame</enum>
+                  </property>
+                  <property name="frameShadow">
+                   <enum>QFrame::Raised</enum>
+                  </property>
+                  <layout class="QGridLayout" name="gridLayout_5">
+                   <property name="leftMargin">
+                    <number>10</number>
+                   </property>
+                   <property name="topMargin">
+                    <number>10</number>
+                   </property>
+                   <property name="rightMargin">
+                    <number>10</number>
+                   </property>
+                   <property name="bottomMargin">
+                    <number>10</number>
+                   </property>
+                   <item row="0" column="0">
+                    <widget class="QStackedWidget" name="stackedWidget">
+                     <property name="styleSheet">
+                      <string notr="true">background: transparent;</string>
+                     </property>
+                     <property name="currentIndex">
+                      <number>4</number>
+                     </property>
+                     <widget class="QWidget" name="home">
+                      <property name="styleSheet">
+                       <string notr="true"/>
+                      </property>
+                      <layout class="QGridLayout" name="gridLayout_7">
+                       <item row="0" column="0">
+                        <layout class="QGridLayout" name="home_layout"/>
+                       </item>
+                      </layout>
+                     </widget>
+                     <widget class="QWidget" name="prober_control">
+                      <layout class="QVBoxLayout" name="verticalLayout_20">
+                       <item>
+                        <layout class="QGridLayout" name="prober_control_layout">
+                         <property name="leftMargin">
+                          <number>1</number>
+                         </property>
+                         <property name="topMargin">
+                          <number>2</number>
+                         </property>
+                         <property name="rightMargin">
+                          <number>3</number>
+                         </property>
+                        </layout>
+                       </item>
+                      </layout>
+                     </widget>
+                     <widget class="QWidget" name="adc_control">
+                      <layout class="QGridLayout" name="gridLayout_6">
+                       <item row="0" column="0">
+                        <layout class="QGridLayout" name="adc_control_layout"/>
+                       </item>
+                      </layout>
+                     </widget>
+                     <widget class="QWidget" name="laser_control">
+                      <layout class="QGridLayout" name="gridLayout_4">
+                       <item row="0" column="0">
+                        <layout class="QGridLayout" name="laser_control_layout"/>
+                       </item>
+                      </layout>
+                     </widget>
+                     <widget class="QWidget" name="measured_data">
+                      <layout class="QGridLayout" name="gridLayout_2">
+                       <item row="0" column="0">
+                        <layout class="QGridLayout" name="measured_data_layout"/>
+                       </item>
+                      </layout>
+                     </widget>
+                    </widget>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QFrame" name="extraRightBox">
+                  <property name="minimumSize">
+                   <size>
+                    <width>0</width>
+                    <height>0</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>0</width>
+                    <height>16777215</height>
+                   </size>
+                  </property>
+                  <property name="frameShape">
+                   <enum>QFrame::NoFrame</enum>
+                  </property>
+                  <property name="frameShadow">
+                   <enum>QFrame::Raised</enum>
+                  </property>
+                  <layout class="QVBoxLayout" name="verticalLayout_7">
+                   <property name="spacing">
+                    <number>0</number>
+                   </property>
+                   <property name="leftMargin">
+                    <number>0</number>
+                   </property>
+                   <property name="topMargin">
+                    <number>0</number>
+                   </property>
+                   <property name="rightMargin">
+                    <number>0</number>
+                   </property>
+                   <property name="bottomMargin">
+                    <number>0</number>
+                   </property>
+                   <item>
+                    <widget class="QFrame" name="themeSettingsTopDetail">
+                     <property name="maximumSize">
+                      <size>
+                       <width>16777215</width>
+                       <height>3</height>
+                      </size>
+                     </property>
+                     <property name="frameShape">
+                      <enum>QFrame::NoFrame</enum>
+                     </property>
+                     <property name="frameShadow">
+                      <enum>QFrame::Raised</enum>
+                     </property>
+                    </widget>
+                   </item>
+                   <item>
+                    <widget class="QFrame" name="contentSettings">
+                     <property name="frameShape">
+                      <enum>QFrame::NoFrame</enum>
+                     </property>
+                     <property name="frameShadow">
+                      <enum>QFrame::Raised</enum>
+                     </property>
+                     <layout class="QVBoxLayout" name="verticalLayout_13">
+                      <property name="spacing">
+                       <number>0</number>
+                      </property>
+                      <property name="leftMargin">
+                       <number>0</number>
+                      </property>
+                      <property name="topMargin">
+                       <number>0</number>
+                      </property>
+                      <property name="rightMargin">
+                       <number>0</number>
+                      </property>
+                      <property name="bottomMargin">
+                       <number>0</number>
+                      </property>
+                      <item>
+                       <widget class="QTextEdit" name="txt_logs"/>
+                      </item>
+                      <item alignment="Qt::AlignTop">
+                       <widget class="QFrame" name="topMenus">
+                        <property name="frameShape">
+                         <enum>QFrame::NoFrame</enum>
+                        </property>
+                        <property name="frameShadow">
+                         <enum>QFrame::Raised</enum>
+                        </property>
+                        <layout class="QVBoxLayout" name="verticalLayout_14">
+                         <property name="spacing">
+                          <number>0</number>
+                         </property>
+                         <property name="leftMargin">
+                          <number>0</number>
+                         </property>
+                         <property name="topMargin">
+                          <number>0</number>
+                         </property>
+                         <property name="rightMargin">
+                          <number>0</number>
+                         </property>
+                         <property name="bottomMargin">
+                          <number>0</number>
+                         </property>
+                         <item>
+                          <widget class="QPushButton" name="btn_print">
+                           <property name="sizePolicy">
+                            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+                             <horstretch>0</horstretch>
+                             <verstretch>0</verstretch>
+                            </sizepolicy>
+                           </property>
+                           <property name="minimumSize">
+                            <size>
+                             <width>0</width>
+                             <height>45</height>
+                            </size>
+                           </property>
+                           <property name="font">
+                            <font>
+                             <pointsize>10</pointsize>
+                             <italic>false</italic>
+                             <bold>false</bold>
+                            </font>
+                           </property>
+                           <property name="cursor">
+                            <cursorShape>PointingHandCursor</cursorShape>
+                           </property>
+                           <property name="layoutDirection">
+                            <enum>Qt::LeftToRight</enum>
+                           </property>
+                           <property name="styleSheet">
+                            <string notr="true">background-image: url(:/icons/images/icons/cil-print.png);</string>
+                           </property>
+                           <property name="text">
+                            <string>Print</string>
+                           </property>
+                          </widget>
+                         </item>
+                        </layout>
+                       </widget>
+                      </item>
+                     </layout>
+                    </widget>
+                   </item>
+                  </layout>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+             <item>
+              <widget class="QFrame" name="bottomBar">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>22</height>
+                </size>
+               </property>
+               <property name="maximumSize">
+                <size>
+                 <width>16777215</width>
+                 <height>22</height>
+                </size>
+               </property>
+               <property name="frameShape">
+                <enum>QFrame::NoFrame</enum>
+               </property>
+               <property name="frameShadow">
+                <enum>QFrame::Raised</enum>
+               </property>
+               <layout class="QHBoxLayout" name="horizontalLayout_5">
+                <property name="spacing">
+                 <number>0</number>
+                </property>
+                <property name="leftMargin">
+                 <number>0</number>
+                </property>
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <property name="rightMargin">
+                 <number>0</number>
+                </property>
+                <property name="bottomMargin">
+                 <number>0</number>
+                </property>
+                <item>
+                 <widget class="QLabel" name="creditsLabel">
+                  <property name="maximumSize">
+                   <size>
+                    <width>16777215</width>
+                    <height>16</height>
+                   </size>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <pointsize>-1</pointsize>
+                    <italic>false</italic>
+                    <bold>false</bold>
+                   </font>
+                  </property>
+                  <property name="text">
+                   <string>Flexsensor 6</string>
+                  </property>
+                  <property name="alignment">
+                   <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QLabel" name="version">
+                  <property name="text">
+                   <string>v1.0.3</string>
+                  </property>
+                  <property name="alignment">
+                   <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                  </property>
+                 </widget>
+                </item>
+                <item>
+                 <widget class="QFrame" name="frame_size_grip">
+                  <property name="minimumSize">
+                   <size>
+                    <width>20</width>
+                    <height>0</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>20</width>
+                    <height>16777215</height>
+                   </size>
+                  </property>
+                  <property name="frameShape">
+                   <enum>QFrame::NoFrame</enum>
+                  </property>
+                  <property name="frameShadow">
+                   <enum>QFrame::Raised</enum>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources>
+  <include location="../../resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/FlexSensor/MainWindow/resources/convert.sh b/src/FlexSensor/MainWindow/resources/convert.sh
new file mode 100644
index 0000000000000000000000000000000000000000..eb75364500a9ddc5fb07ab9e2990bc1c2251cb18
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/convert.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Convert .ui files to .py files
+for ui in *.ui; do
+    pyside6-uic $ui > ../view/${ui%.*}.py
+done
+ pyside6-rcc ../../resources.qrc -o ../../resources_rc.py
diff --git a/src/FlexSensor/MainWindow/resources/ui_palette.xml b/src/FlexSensor/MainWindow/resources/ui_palette.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8fafb2b667af4fd7f647bd0e9d84a005270aab0
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/ui_palette.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<palette>
+ <active/>
+ <inactive/>
+ <disabled/>
+</palette>
diff --git a/src/FlexSensor/MainWindow/resources/ui_palette_QFrame.xml b/src/FlexSensor/MainWindow/resources/ui_palette_QFrame.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8fafb2b667af4fd7f647bd0e9d84a005270aab0
--- /dev/null
+++ b/src/FlexSensor/MainWindow/resources/ui_palette_QFrame.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<palette>
+ <active/>
+ <inactive/>
+ <disabled/>
+</palette>
diff --git a/src/FlexSensor/MainWindow/view/BaseWindow.py b/src/FlexSensor/MainWindow/view/BaseWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae6ca6e885ac46bf3737ce528c4428ce196ace1a
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/BaseWindow.py
@@ -0,0 +1,282 @@
+from PySide6.QtCore import QPropertyAnimation, QEasingCurve, QParallelAnimationGroup
+from PySide6.QtGui import QColor, Qt, QIcon
+from PySide6.QtWidgets import QMainWindow, QGraphicsDropShadowEffect, QSizeGrip, QPushButton
+
+import __version__
+from ConfigHandler.controller.AppSettings import Settings
+from MainWindow.view.MainView import Ui_MainWindow
+from MainWindow.view.widgets.custom_grips import CustomGrip
+
+
+class BaseWindow(QMainWindow):
+
+    def __init__(self, ui_main_window: Ui_MainWindow):
+        super().__init__()
+        self.GLOBAL_STATE = False
+        self.GLOBAL_TITLE_BAR = True
+
+        self._ui = ui_main_window
+        self._ui.setupUi(self)
+        Settings.ENABLE_CUSTOM_TITLE_BAR = True
+
+        # APP NAME
+        # ///////////////////////////////////////////////////////////////
+        title = "FlexSensor 6 - A SiPh automation tool"
+        description = f"Flexsensor  {__version__.__version__}"
+        # APPLY TEXTS
+        self.setWindowTitle(title)
+        self._ui.titleRight.setText(description)
+
+        if not Settings.ENABLE_CUSTOM_TITLE_BAR:
+            self._ui.appMargins.setContentsMargins(0, 0, 0, 0)
+            self._ui.minimizeAppBtn.hide()
+            self._ui.maximizeRestoreAppBtn.hide()
+            self._ui.closeAppBtn.hide()
+            self._ui.frame_size_grip.hide()
+
+        # DROP SHADOW
+        self.shadow = QGraphicsDropShadowEffect(self)
+        self.shadow.setBlurRadius(17)
+        self.shadow.setXOffset(0)
+        self.shadow.setYOffset(0)
+        self.shadow.setColor(QColor(0, 0, 0, 150))
+        self._ui.bgApp.setGraphicsEffect(self.shadow)
+
+        # RESIZE WINDOW
+        self.sizegrip = QSizeGrip(self._ui.frame_size_grip)
+        self.sizegrip.setStyleSheet("width: 20px; height: 20px; margin 0px; padding: 0px;")
+        # self.setStyleSheet("background-color: rgb(0, 0, 0);")
+
+        # MINIMIZE
+        self._ui.minimizeAppBtn.clicked.connect(lambda: self.showMinimized())
+
+        # MAXIMIZE/RESTORE
+        self._ui.maximizeRestoreAppBtn.clicked.connect(lambda: self.maximize_restore())
+
+        # CLOSE APPLICATION
+        self._ui.closeAppBtn.clicked.connect(lambda: self.close())
+
+        self.setWindowFlags(Qt.FramelessWindowHint)
+        self.setAttribute(Qt.WA_TranslucentBackground)
+
+        self.left_grip = CustomGrip(self, Qt.LeftEdge, True)
+        self.right_grip = CustomGrip(self, Qt.RightEdge, True)
+        self.top_grip = CustomGrip(self, Qt.TopEdge, True)
+        self.bottom_grip = CustomGrip(self, Qt.BottomEdge, True)
+        self.maximize_restore()
+        # self._ui.titleRightInfo.mouseMoveEvent = self.moveWindow
+
+    # def moveWindow(self, event):
+
+    def openCloseRightBox(self):
+        self.toggleRightBox(True)
+
+    def openCloseLeftBox(self):
+        self.toggleLeftBox(True)
+
+    def toggleLeftBox(self, enable):
+        if enable:
+            # GET WIDTH
+            width = self._ui.extraLeftBox.width()
+            widthRightBox = self._ui.extraRightBox.width()
+            maxExtend = Settings.LEFT_BOX_WIDTH
+            color = Settings.BTN_LEFT_BOX_COLOR
+            standard = 0
+
+            # GET BTN STYLE
+            style = self._ui.toggleLeftBox.styleSheet()
+
+            # SET MAX WIDTH
+            if width == 0:
+                widthExtended = maxExtend
+                # SELECT BTN
+                self._ui.toggleLeftBox.setStyleSheet(style + color)
+                if widthRightBox != 0:
+                    style = self._ui.settingsTopBtn.styleSheet()
+                    self._ui.settingsTopBtn.setStyleSheet(style.replace(Settings.BTN_RIGHT_BOX_COLOR, ''))
+            else:
+                widthExtended = standard
+                # RESET BTN
+                self._ui.toggleLeftBox.setStyleSheet(style.replace(color, ''))
+
+        self.start_box_animation(width, widthRightBox, "left")
+
+    # UI initialization
+    # TOGGLE RIGHT BOX
+    #     # ///////////////////////////////////////////////////////////////
+    def toggleRightBox(self, enable):
+        if enable:
+            # GET WIDTH
+            width = self._ui.extraRightBox.width()
+            widthLeftBox = self._ui.extraLeftBox.width()
+            maxExtend = Settings.RIGHT_BOX_WIDTH
+            color = Settings.BTN_RIGHT_BOX_COLOR
+            standard = 0
+
+            # GET BTN STYLE
+            style = self._ui.settingsTopBtn.styleSheet()
+
+            # SET MAX WIDTH
+            if width == 0:
+                widthExtended = maxExtend
+                # SELECT BTN
+                self._ui.settingsTopBtn.setStyleSheet(style + color)
+                if widthLeftBox != 0:
+                    style = self._ui.toggleLeftBox.styleSheet()
+                    self._ui.toggleLeftBox.setStyleSheet(style.replace(Settings.BTN_LEFT_BOX_COLOR, ''))
+            else:
+                widthExtended = standard
+                # RESET BTN
+                self._ui.settingsTopBtn.setStyleSheet(style.replace(color, ''))
+
+            self.start_box_animation(widthLeftBox, width, "right")
+
+    # TOGGLE MENU
+    # ///////////////////////////////////////////////////////////////
+    def toggleMenu(self, enable):
+        if enable:
+            # GET WIDTH
+            width = self._ui.leftMenuBg.width()
+            maxExtend = Settings.MENU_WIDTH
+            standard = 60
+
+            # SET MAX WIDTH
+            if width == 60:
+                widthExtended = maxExtend
+            else:
+                widthExtended = standard
+
+            # ANIMATION
+            self.animation = QPropertyAnimation(self._ui.leftMenuBg, b"minimumWidth")
+            self.animation.setDuration(Settings.TIME_ANIMATION)
+            self.animation.setStartValue(width)
+            self.animation.setEndValue(widthExtended)
+            self.animation.setEasingCurve(QEasingCurve.InOutQuart)
+            self.animation.start()
+
+    def start_box_animation(self, left_box_width, right_box_width, direction):
+        right_width = 0
+        left_width = 0
+
+        # Check values
+        if left_box_width == 0 and direction == "left":
+            left_width = 240
+        else:
+            left_width = 0
+        # Check values
+        if right_box_width == 0 and direction == "right":
+            right_width = 240
+        else:
+            right_width = 0
+
+            # ANIMATION LEFT BOX
+        self.left_box = QPropertyAnimation(self._ui.extraLeftBox, b"minimumWidth")
+        self.left_box.setDuration(Settings.TIME_ANIMATION)
+        self.left_box.setStartValue(left_box_width)
+        self.left_box.setEndValue(left_width)
+        self.left_box.setEasingCurve(QEasingCurve.InOutQuart)
+
+        # ANIMATION RIGHT BOX
+        self.right_box = QPropertyAnimation(self._ui.extraRightBox, b"minimumWidth")
+        self.right_box.setDuration(Settings.TIME_ANIMATION)
+        self.right_box.setStartValue(right_box_width)
+        self.right_box.setEndValue(right_width)
+        self.right_box.setEasingCurve(QEasingCurve.InOutQuart)
+
+        # GROUP ANIMATION
+        self.group = QParallelAnimationGroup()
+        self.group.addAnimation(self.left_box)
+        self.group.addAnimation(self.right_box)
+        self.group.start()
+
+    def selectMenu(self, getStyle):
+        select = getStyle + Settings.MENU_SELECTED_STYLESHEET
+        return select
+
+    def deselectMenu(self, getStyle):
+        deselect = getStyle.replace(Settings.MENU_SELECTED_STYLESHEET, "")
+        return deselect
+
+    # START SELECTION
+    def selectStandardMenu(self, widget):
+        for w in self._ui.topMenu.findChildren(QPushButton):
+            if w.objectName() == widget:
+                w.setStyleSheet(self.selectMenu(w.styleSheet()))
+
+    # RESET SELECTION
+    def resetStyle(self, widget):
+        for w in self._ui.topMenu.findChildren(QPushButton):
+            if w.objectName() != widget:
+                w.setStyleSheet(self.deselectMenu(w.styleSheet()))
+
+    def resize_grips(self):
+        if Settings.ENABLE_CUSTOM_TITLE_BAR:
+            self.left_grip.setGeometry(0, 10, 10, self.height())
+            self.right_grip.setGeometry(self.width() - 10, 10, 10, self.height())
+            self.top_grip.setGeometry(0, 0, self.width(), 10)
+            self.bottom_grip.setGeometry(0, self.height() - 10, self.width(), 10)
+
+    def resizeEvent(self, event):
+        # Update Size Grips
+        self.resize_grips()
+
+    # MOUSE CLICK EVENTS
+    # ///////////////////////////////////////////////////////////////
+    def mousePressEvent(self, event):
+        # SET DRAG POS WINDOW
+        self.dragPos = event.globalPos()
+
+        # PRINT MOUSE EVENTS
+        #if event.buttons() == Qt.LeftButton:
+        #    print(f'Mouse click: LEFT CLICK {self.dragPos}')
+        #if event.buttons() == Qt.RightButton:
+        #    print('Mouse click: RIGHT CLICK')
+
+    def mouseMoveEvent(self, event) -> None:
+        # IF MAXIMIZED CHANGE TO NORMAL
+
+        if self.returStatus():
+            self.maximize_restore()
+        # MOVE WINDOW
+        if event.buttons() == Qt.LeftButton:
+            self.move(self.pos() + event.globalPos() - self.dragPos)
+            print(f"Mouse move: {event.pos()} - {self.pos()}")
+            self.dragPos = event.globalPos()
+            # event.accept()
+            # self.update()
+
+    def maximize_restore(self):
+        status = self.GLOBAL_STATE
+        if status == False:
+            self.showMaximized()
+            GLOBAL_STATE = True
+            self._ui.appMargins.setContentsMargins(0, 0, 0, 0)
+            self._ui.maximizeRestoreAppBtn.setToolTip("Restore")
+            self._ui.maximizeRestoreAppBtn.setIcon(QIcon(u":/icons/images/icons/icon_restore.png"))
+            self._ui.frame_size_grip.hide()
+            self.left_grip.hide()
+            self.right_grip.hide()
+            self.top_grip.hide()
+            self.bottom_grip.hide()
+        else:
+            GLOBAL_STATE = False
+            self.showNormal()
+            self.resize(self.width() + 1, self.height() + 1)
+            self._ui.appMargins.setContentsMargins(10, 10, 10, 10)
+            self._ui.maximizeRestoreAppBtn.setToolTip("Maximize")
+            self._ui.maximizeRestoreAppBtn.setIcon(QIcon(u":/icons/images/icons/icon_maximize.png"))
+            self._ui.frame_size_grip.show()
+            self.left_grip.show()
+            self.right_grip.show()
+            self.top_grip.show()
+            self.bottom_grip.show()
+
+    # RETURN STATUS
+    # ///////////////////////////////////////////////////////////////
+    def returStatus(self):
+        return self.GLOBAL_STATE
+
+    # SET STATUS
+    # ///////////////////////////////////////////////////////////////
+    def setStatus(self, status):
+        self.GLOBAL_STATE = status
diff --git a/src/FlexSensor/MainWindow/view/MainThreadView.py b/src/FlexSensor/MainWindow/view/MainThreadView.py
new file mode 100644
index 0000000000000000000000000000000000000000..8a852bd475396d4f41c11fdb31f0671aea227472
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/MainThreadView.py
@@ -0,0 +1,396 @@
+import logging
+import sys
+import traceback
+
+from PySide6.QtWidgets import (
+    QMessageBox, QGridLayout, QGroupBox, QStatusBar, QPushButton, QTabWidget, QToolButton, QDockWidget, )
+from PySide6.QtCore import QThread
+
+from PySide6.QtGui import QIcon, QAction
+
+import pyqtgraph as pg
+from pyqtgraph.dockarea import *
+
+import __version__
+from ConfigHandler.controller.VASInputFileParser import VASInputFileParser
+from MainWindow.view.BaseWindow import BaseWindow
+from MainWindow.view.widgets.HomeStatusWidget import HomeStatusWidget
+from MainWindow.view.widgets.ScopeWidget import ScopeWidget
+
+from MainWindow.view.MainView import Ui_MainWindow
+
+from MainWindow.controller.MainThreadController import MainThreadController
+from MainWindow.model.MainThreadModel import MainThreadModel
+from MainWindow.view.StepThroughView import StepThroughView
+from InitialSetupWizard.InitialSetupWizard import InitialSetupWizard
+from MainWindow.view.widgets.WidgetSettingsFilesFolders import (WidgetSettingsOutFilesFolders,
+                                                                WidgetLaserSettings, WidgetSettingsInFilesFolders,
+                                                                WidgetAD2Settings)
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementEvaluationTool.view.widgets.MenuBarDefinition import MenuBarDefinition
+from constants.qs_style_sheets import CSSPlayPushButton
+
+#
+from pathes import image_root
+import ConfigHandler as Config
+
+
+class MainWindow(BaseWindow):
+
+    def __init__(self, model: MainThreadModel, controller: MainThreadController):
+        super().__init__(Ui_MainWindow())
+        self.logger = logging.getLogger("MainThread (UI)")
+
+        self._model: MainThreadModel = model
+        self._controller: MainThreadController = controller
+
+        # Signals for finished acquisition
+        self.model.measurement_routine.signals.routine_iteration_finished.connect(
+            self.on_routine_iteration_finished)
+
+        self._ui.settingsTopBtn.clicked.connect(self.openCloseRightBox)
+        self._ui.toggleButton.clicked.connect(lambda: self.toggleMenu(True))
+        self._ui.btn_start_measuring_routine.clicked.connect(self._on_btn_run_clicked)
+
+        self.init_UI()
+
+        # SET HOME PAGE AND SELECT MENU
+        # ///////////////////////////////////////////////////////////////
+        self._ui.stackedWidget.setCurrentWidget(self._ui.home)
+        self._ui.btn_home.setStyleSheet(self.selectMenu(self._ui.btn_home.styleSheet()))
+
+    @property
+    def model(self) -> MainThreadModel:
+        return self._model
+
+    @property
+    def controller(self) -> MainThreadController:
+        return self._controller
+
+    # ==================================================================================================================
+    # UI initialization methods
+    # ==================================================================================================================
+    def init_UI(self):
+        self.logger.debug("Initializing UI of MainWindow.")
+        self.grid_layout_main = QGridLayout()
+        self.init_UI_status_bar()
+        self.menu_bar = MenuBarDefinition(self)
+
+        # Add the prober control
+        self._ui.prober_control_layout.addWidget(self.model.prober_window)
+        self._ui.btn_probe_control.clicked.connect(self._on_btn_prober_control_clicked)
+
+        # Add the ADC control
+        dock_ad2 = QDockWidget("AD2 Control", self)
+        dock_ad2.setWidget(self.model.ad2_window)
+        self._ui.adc_control_layout.addWidget(dock_ad2, 0,0)
+        self._ui.btn_adc_control.clicked.connect(self._on_btn_adc_control_clicked)
+
+        dock_laser = QDockWidget("Laser Control", self)
+        dock_laser.setWidget(self.model.laser_window)
+        self._ui.adc_control_layout.addWidget(dock_laser,0,1)
+        self._ui.btn_laser_control.clicked.connect(self._on_btn_laser_control_clicked)
+
+        # add the measurement evaluation tool
+        self._ui.measured_data_layout.addWidget(self.model.mea_eval_tool_window)
+        self._ui.btn_measured_data.clicked.connect(self._on_btn_measurement_evaluation_clicked)
+
+
+        self._ui.home_layout.addWidget(HomeStatusWidget(self), 0, 0, 1, 2)
+        self._ui.home_layout.addWidget(self.init_UI_measurement_settings(), 1, 0)
+        self._ui.home_layout.addWidget(ScopeWidget(self), 1, 1)
+        # self._ui.grid_layout_main.addWidget(self.init_UI_device_control(), 1, 1, 2, 1)
+
+        self._ui.home_layout.addWidget(self.init_UI_buttons(), 2, 0, 1, 2)
+        self._ui.btn_home.clicked.connect(self._on_btn_home_clicked)
+
+        # self.setGeometry(100, 100, 1250, 150)
+        self.setWindowTitle(f'FlexSensor Automator {__version__.__version__}')
+        self.setWindowIcon(QIcon('../images/FlexSensorIcon.png'))
+
+        # self.init_menu_run()
+
+        # widget = QWidget()
+        # widget.setLayout(layout)
+        # self.setCentralWidget(widget)
+        self._ui.closeAppBtn.clicked.connect(lambda: exit())
+
+
+    # def closeEvent(self, *args, **kwargs):
+    #     # self.prober_worker.stop()
+    #     # self.threadpool.waitForDone()
+    #     self.thread.quit()
+    #     self.logger.warning(f"Exiting {args}")
+    #     sys.exit(1)
+
+    def init_UI_status_bar(self):
+        # global status_bar
+
+        self.status_bar = QStatusBar()
+        self.setStatusBar(self.status_bar)
+
+    def init_UI_measurement_settings(self):
+        tabwidget = QTabWidget()
+        self.configView = Config.View(self.model.vaut_config)
+        tab_input = tabwidget.addTab(WidgetSettingsInFilesFolders(self.model.vaut_config), "Input")
+        tab_folders = tabwidget.addTab(WidgetSettingsOutFilesFolders(self.model.vaut_config), "Folder Settings")
+        tab_ad2 = tabwidget.addTab(WidgetAD2Settings(self.model.vaut_config), "AD2 Settings")
+        tab_laser = tabwidget.addTab(WidgetLaserSettings(self.model.vaut_config), "Laser Settings")
+        tab_yaml = tabwidget.addTab(self.configView, "YAML Config")
+        tabwidget.currentChanged.connect(
+            lambda idx: self.configView.repopulate(self.model.vaut_config) if idx == tab_yaml else print("fg")
+        )
+        return tabwidget
+
+    # def init_UI_device_control(self):
+    #     tabwidget = QTabWidget()
+    #     # tab_scope = tabwidget.addTab(self.init_scope_meter(), "Scope")
+    #     # tab_laser = tabwidget.addTab(self._controller.laser_window, "Laser Control")
+    #     # tab_ad2dev = tabwidget.addTab(self._controller.ad2_window, "AD2 Control")
+    #     # tab_prober = tabwidget.addTab(self._controller.prober_window, "Prober Control")
+    #
+    #     return tabwidget
+
+    def init_scope_meter(self):
+        area = DockArea()
+
+        d1 = Dock("Analog Discovery 2")
+        d2 = Dock("Filtered")
+        area.addDock(d1, 'bottom')
+        area.addDock(d2, 'bottom', d1)
+
+        self.scope_original = pg.PlotWidget(title="AD2 Acquisition")
+        # self.scope_original.plot(np.random.normal(size=100)*1e12)
+        self.scope_original.plotItem.showGrid(x=True, y=True, alpha=1)
+        d1.addWidget(self.scope_original)
+
+        self.scope_filtered = pg.PlotWidget(title="Filtered Data")
+        # self.scope_filtered.plot(np.random.normal(size=100))
+        self.scope_filtered.plotItem.showGrid(x=True, y=True, alpha=1)
+        d2.addWidget(self.scope_filtered)
+
+        # self.scope = pg.PlotWidget()
+        # self.scope.plot([1, 2])
+
+        return area
+
+    def init_UI_buttons(self):
+        grid_group_box = QGroupBox()
+        layout = QGridLayout()
+
+        self.btn_run = QPushButton(parent=self, text="Run")
+        self.btn_run.clicked.connect(self._on_btn_run_clicked)
+        layout.addWidget(self.btn_run, 0, 0)
+
+        self.btn_stop = QPushButton(parent=self, text="Stop")
+        # self.btn_stop.clicked.connect(self.on_btn_stop_clicked)
+        layout.addWidget(self.btn_stop, 0, 1)
+
+        self.btn_exit = QPushButton(parent=self, text="Exit")
+        # self.btn_exit.clicked.connect(self.on_btn_exit_clicked)
+        layout.addWidget(self.btn_exit, 0, 2)
+
+        grid_group_box.setLayout(layout)
+
+        return grid_group_box
+
+    # def init_menu_file(self):
+    #     exit_action = QAction(QIcon('exit.png'), '&Exit     ', self)
+    #     exit_action.setShortcut('Ctrl+Q')
+    #     exit_action.setStatusTip('Exit application')
+    #     exit_action.triggered.connect(self.close)
+    #     self._ui.menu_file.addAction(exit_action)
+    #
+    # def init_menu_edit(self):
+    #     pass
+    #
+    # def init_menu_run(self):
+    #     # self.menu_run = self.menubar.addMenu("Run")
+    #     self.open_step_trough = QAction('Open &Step Through Window', self)
+    #     self.open_step_trough.setShortcut('Ctrl+W')
+    #     self.open_step_trough.setStatusTip('Open Step Through Window')
+    #     self.open_step_trough.triggered.connect(self.on_open_step_through)
+    #     self._ui.menu_run.addAction(self.open_step_trough)
+    #
+    #     self.open_train_home_wizard = QAction('&Initial Setup Wizard', self)
+    #     self.open_train_home_wizard.setShortcut('Ctrl+I')
+    #     self.open_train_home_wizard.setStatusTip('Open Initial Setup Wizard')
+    #     self.open_train_home_wizard.setIcon(QIcon(f"{image_root}/icons/setup_wizard.png"))
+    #     self.open_train_home_wizard.triggered.connect(self.on_open_initial_setup_wizard)
+    #     self._ui.menu_run.addAction(self.open_train_home_wizard)
+    #
+    #
+    # def init_UI_menu_bar(self):
+    #     # self.menubar = self.menuBar()
+    #     self.init_menu_file()
+    #     self.init_menu_edit()
+    #     self.init_menu_run()
+    #     # help_menu = menubar.addMenu("Help")
+    #     # help_menu.addAction("About", self.on_about_clicked)
+
+    # ==================================================================================================================
+    # Signal handlers
+    # ==================================================================================================================
+    def _on_open_step_through(self):
+        file_parser = VASInputFileParser()
+        grouped_structures, _ = file_parser.read_file(
+            input_file=self.model.vaut_config.wafer_config.get_structure_file().absolute
+        )
+        self.step_through_view = StepThroughView(grouped_structures)
+        self.step_through_view.show()
+
+    def _on_open_initial_setup_wizard(self):
+        self.wizard = InitialSetupWizard(self.model.prober_controller)
+        self.wizard.show()
+
+    def _on_btn_laser_control_clicked(self):
+        self.resetStyle(self.sender().objectName())
+        self._ui.stackedWidget.setCurrentWidget(self._ui.laser_control)
+        self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+    def _on_btn_adc_control_clicked(self):
+        self.resetStyle(self.sender().objectName())
+        self._ui.stackedWidget.setCurrentWidget(self._ui.adc_control)
+        self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+    def _on_btn_prober_control_clicked(self):
+        self.resetStyle(self.sender().objectName())
+        self._ui.stackedWidget.setCurrentWidget(self._ui.prober_control)
+        self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+    def _on_btn_home_clicked(self):
+        self.resetStyle(self.sender().objectName())
+        self._ui.stackedWidget.setCurrentWidget(self._ui.home)
+        self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+    def _on_btn_measurement_evaluation_clicked(self):
+        self.resetStyle(self.sender().objectName())
+        self._ui.stackedWidget.setCurrentWidget(self._ui.measured_data)
+        self.sender().setStyleSheet(self.selectMenu(self.sender().styleSheet()))
+
+    def _on_btn_run_clicked(self):
+        self._ui.btn_start_measuring_routine.setStyleSheet(CSSPlayPushButton.style_pause())
+        self._controller.start_measurement_routine()
+
+    # ------------------------------------------------------------------------------------------------------------------
+    # not used (yet)
+    def on_wafer_version_changed(self, value):
+        pass
+        # # Set the object property
+        # self.vaut_config.set_wafer_version(value)
+        # # Update all textfields
+        # self.on_tb_log_file_text_changed(self.tb_log_file.text())
+        # self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+        # self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+        # self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+        # self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+        # self.tb_working_directory.setText(self.vaut_config.output_directory.rel)
+
+    def on_wafer_nr_changed(self, value):
+        pass
+        # # Set the object property
+        # self.vaut_config.set_wafer_nr(value)
+        # # Update all textfields
+        # self.on_tb_log_file_text_changed(self.tb_log_file.text())
+        # self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+        # self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+        # self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+        # self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+        # self.tb_working_directory.setText(self.vaut_config.output_directory.rel)
+
+    def on_routine_iteration_finished(self, cur_measured_signal: SingleMeasuredData = None):
+        pass
+        # if not isinstance(cur_measured_signal, SingleMeasuredData):
+        #     self.logger.error(
+        #         f"Prober did not return any valid measured signal: measured_signal was {type(cur_measured_signal)}")
+        #     self.on_error_emitted((ValueError,
+        #                            f"Prober did not return any valid measured signal: measured_signal was {type(cur_measured_signal)}",
+        #                            traceback.format_exc()))
+        #     # raise ValueError(f"Prober did not return any valid measured signal: measured_signal was {type(measured_signal)}")
+
+        # self.logger.info(
+        #     f"Acquisition finished for structure {cur_measured_signal.wafer_properties.structure_name} (die: {cur_measured_signal.wafer_properties.die_number}).")
+        # try:
+        #     if len(cur_measured_signal._filtered_amplitude['amplitude']) > 0:
+        #         self.scope_original.clear()
+        #         self.scope_original.plot(cur_measured_signal.measured_data['measurements'], pen=pg.mkPen(width=1))
+        #     else:
+        #         self.logger.warning("Nothing to plot!")
+        # except Exception as e:
+        #     self.logger.error(f"Error plotting scope: {e}")
+        #     self.on_error_emitted((type(e), f"Error plotting scope: {e}", traceback.format_exc()))
+
+    def on_error(self, error_message):
+        self.logger.error(error_message)
+        self.status_bar.showMessage(error_message)
+        self.status_bar.setStyleSheet("color: red")
+
+    def on_writeout_emitted(self, msg_type, message):
+
+        if msg_type == "debug":
+            self.status_bar.setStyleSheet('border: 0; color:  blue;')
+        elif msg_type == "warning":
+            self.status_bar.setStyleSheet('border: 0; color:  orange;')
+        elif msg_type == "error":
+            self.status_bar.setStyleSheet('border: 0; color:  red;')
+        elif msg_type == "fatal":
+            self.status_bar.setStyleSheet('border: 0; color:  red;')
+        else:
+            self.status_bar.setStyleSheet('border: 0; color:  black;')
+        self.status_bar.showMessage(message)
+
+    def on_report_info_emitted(self, version_info):
+        self.lbl_die_no.setText("<b>" + str(version_info["die_no"]) + "</b>")
+        self.lbl_structure.setText("<b>" + str(version_info["structure"]) + "</b>")
+        self.lbl_die_col.setText("<b>" + str(version_info["chuck_col"]) + "</b>")
+        self.lbl_die_row.setText("<b>" + str(version_info["chuck_row"]) + "</b>")
+
+    def on_report_progress(self, progress):
+        self.progress.setValue(progress)
+
+    def on_structure_select(self):
+        pass
+        # self.test_win.show()
+
+    def on_error_emitted(self, value):
+        title, text, details = value
+        try:
+            self.error_dialog: QMessageBox
+            # self.error_dialog.close()
+        except Exception as e:
+            print(f"Can't close error_dialog: {e}")
+        # Show a error dialog
+        self.error_dialog = QMessageBox()
+        self.error_dialog.setText(str(text))
+        # set detailed text
+        self.error_dialog.setDetailedText(str(details))
+        self.error_dialog.setIcon(QMessageBox.Critical)
+        self.error_dialog.setWindowTitle(f"Measurmenent Routine Error: {title}")
+        self.error_dialog.exec_()
+
+    def on_warning_emitted(self, value):
+        try:
+            self.warning_dialog: QMessageBox
+            self.warning_dialog.close()
+        except Exception as e:
+            print(f"Can't close warning_dialog: {e}")
+
+        # Show a warning dialog
+        self.warning_dialog = QMessageBox()
+        self.warning_dialog.setText(str(value[1]))
+        # set detailed text
+        self.warning_dialog.setDetailedText(str(value[2]))
+        self.warning_dialog.setIcon(QMessageBox.Warning)
+        self.warning_dialog.setWindowTitle(f"Prober Task Warning: {value[0]}")
+        self.warning_dialog.exec_()
+
+    def closeEvent(self, event):
+        # do stuff
+        self.model.ad2_controller.stop_process()
+        self.model.laser_controller.stop_process()
+        event.accept() # let the window close
+
+
+    def __del__(self):
+        self.logger.info("Exiting")
+        quit()
\ No newline at end of file
diff --git a/src/FlexSensor/MainWindow/view/MainView.py b/src/FlexSensor/MainWindow/view/MainView.py
new file mode 100644
index 0000000000000000000000000000000000000000..e875299a596dcae7c9d3d00b7770fc0234450d2d
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/MainView.py
@@ -0,0 +1,1587 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'MainViewWUffIj.ui'
+##
+## Created by: Qt User Interface Compiler version 6.2.3
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+    QMetaObject, QObject, QPoint, QRect,
+    QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+    QFont, QFontDatabase, QGradient, QIcon,
+    QImage, QKeySequence, QLinearGradient, QPainter,
+    QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QFormLayout, QFrame, QGridLayout,
+    QHBoxLayout, QLabel, QLayout, QMainWindow,
+    QPushButton, QSizePolicy, QStackedWidget, QTextEdit,
+    QToolButton, QVBoxLayout, QWidget)
+import resources_rc
+
+class Ui_MainWindow(object):
+    def setupUi(self, MainWindow):
+        if not MainWindow.objectName():
+            MainWindow.setObjectName(u"MainWindow")
+        MainWindow.resize(1085, 753)
+        MainWindow.setMinimumSize(QSize(940, 560))
+        MainWindow.setToolTipDuration(-9)
+        self.styleSheet = QWidget(MainWindow)
+        self.styleSheet.setObjectName(u"styleSheet")
+        self.styleSheet.setMaximumSize(QSize(16777214, 16777215))
+        self.styleSheet.setToolTipDuration(0)
+        self.styleSheet.setStyleSheet(u"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"\n"
+"SET APP STYLESHEET - FULL STYLES HERE\n"
+"DARK THEME - DRACULA COLOR BASED\n"
+"\n"
+"///////////////////////////////////////////////////////////////////////////////////////////////// */\n"
+"\n"
+"QWidget{\n"
+"	color: rgb(221, 221, 221);\n"
+"	font: 10pt \"Segoe UI\";\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Tooltip */\n"
+"QToolTip {\n"
+"	color: #ffffff;\n"
+"	background-color: rgba(33, 37, 43, 180);\n"
+"	border: 1px solid rgb(44, 49, 58);\n"
+"	background-image: none;\n"
+"	background-position: left center;\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 2px solid rgb(255, 121, 198);\n"
+"	text-align: left;\n"
+"	padding-left: 8px;\n"
+"	margin: 0px;\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Bg App */\n"
+"#bgApp {	\n"
+"	background"
+                        "-color: rgb(40, 44, 52);\n"
+"	border: 1px solid rgb(44, 49, 58);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Left Menu */\n"
+"#leftMenuBg {	\n"
+"	background-color: rgb(33, 37, 43);\n"
+"}\n"
+"#topLogo {\n"
+"	background-color: rgb(33, 37, 43);\n"
+"	border-image: url(:/images/images/images/FlexSensorIcon.png) 10 0 0 0 strech strech;\n"
+"	background-position: centered;\n"
+"	background-repeat: no-repeat;\n"
+"}\n"
+"#titleLeftApp { font: 63 12pt \"Segoe UI Semibold\"; }\n"
+"#titleLeftDescription { font: 8pt \"Segoe UI\"; color: rgb(189, 147, 249); }\n"
+"\n"
+"/* MENUS */\n"
+"\n"
+"\n"
+"\n"
+"#topMenu .QPushButton {	\n"
+"	background-position: left center;\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 22px solid transparent;\n"
+"	background-color: transparent;\n"
+"	text-align: left;\n"
+"	padding-left: 44px;\n"
+"}\n"
+"#topMenu .QPushButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#topMenu .QPushButton:p"
+                        "ressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"#bottomMenu .QPushButton {	\n"
+"	background-position: left center;\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 20px solid transparent;\n"
+"	background-color:transparent;\n"
+"	text-align: left;\n"
+"	padding-left: 44px;\n"
+"}\n"
+"#bottomMenu .QPushButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#bottomMenu .QPushButton:pressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"#leftMenuFrame{\n"
+"	border-top: 3px solid rgb(44, 49, 58);\n"
+"}\n"
+"\n"
+"/* Toggle Button */\n"
+"#toggleButton {\n"
+"	background-position: left center;\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 20px solid transparent;\n"
+"	background-color: rgb(37, 41, 48);\n"
+"	text-align: left;\n"
+"	padding-left: 44px;\n"
+"	color: rgb(113, 126, 149);\n"
+"}\n"
+"#toggleButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#toggleButto"
+                        "n:pressed {\n"
+"	background-color: rgb(189, 147, 249);\n"
+"}\n"
+"\n"
+"/* Title Menu */\n"
+"/*#titleRightInfo { padding-left: 10px; }*/\n"
+"\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Extra Tab */\n"
+"#extraLeftBox {	\n"
+"	background-color: rgb(44, 49, 58);\n"
+"}\n"
+"#extraTopBg{	\n"
+"	background-color: rgb(189, 147, 249)\n"
+"}\n"
+"\n"
+"/* Icon */\n"
+"#extraIcon {\n"
+"	background-position: center;\n"
+"	background-repeat: no-repeat;\n"
+"	background-image: url(:/icons/images/icons/icon_settings.png);\n"
+"}\n"
+"\n"
+"/* Label */\n"
+"#extraLabel { color: rgb(255, 255, 255); }\n"
+"\n"
+"/* Btn Close */\n"
+"#extraCloseColumnBtn { background-color: rgba(255, 255, 255, 0); border: none;  border-radius: 5px; }\n"
+"#extraCloseColumnBtn:hover { background-color: rgb(196, 161, 249); border-style: solid; border-radius: 4px; }\n"
+"#extraCloseColumnBtn:pressed { background-color: rgb(180, 141, 238); border-style: solid; border-radius: 4px; }\n"
+"\n"
+"/* Extr"
+                        "a Content */\n"
+"#extraContent{\n"
+"	border-top: 3px solid rgb(40, 44, 52);\n"
+"}\n"
+"\n"
+"/* Extra Top Menus */\n"
+"#extraTopMenu .QPushButton {\n"
+"	/*background-position: left center;*/\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 22px solid transparent;\n"
+"	background-color:transparent;\n"
+"	text-align: left;\n"
+"	padding-left: 44px;\n"
+"}\n"
+"#extraTopMenu .QPushButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#extraTopMenu .QPushButton:pressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Content App */\n"
+"#contentTopBg{	\n"
+"	background-color: rgb(33, 37, 43);\n"
+"}\n"
+"#contentBottom{\n"
+"	border-top: 3px solid rgb(44, 49, 58);\n"
+"}\n"
+"\n"
+"/* Top Buttons */\n"
+"#rightButtons .QPushButton { background-color: rgba(255, 255, 255, 0); border: none;  border-radius: 5px; }\n"
+"#rightButtons .QPushBu"
+                        "tton:hover { background-color: rgb(44, 49, 57); border-style: solid; border-radius: 4px; }\n"
+"#rightButtons .QPushButton:pressed { background-color: rgb(23, 26, 30); border-style: solid; border-radius: 4px; }\n"
+"\n"
+"/* Theme Settings */\n"
+"#extraRightBox { background-color: rgb(44, 49, 58); }\n"
+"#themeSettingsTopDetail { background-color: rgb(189, 147, 249); }\n"
+"\n"
+"/* Bottom Bar */\n"
+"#bottomBar { background-color: rgb(44, 49, 58); }\n"
+"#bottomBar QLabel { font-size: 11px; color: rgb(113, 126, 149); padding-left: 10px; padding-right: 10px; padding-bottom: 2px; }\n"
+"\n"
+"/* CONTENT SETTINGS */\n"
+"/* MENUS */\n"
+"#contentSettings .QPushButton {	\n"
+"	background-position: left center;\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 22px solid transparent;\n"
+"	background-color:transparent;\n"
+"	text-align: left;\n"
+"	padding-left: 44px;\n"
+"}\n"
+"#contentSettings .QPushButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#contentSettings .QPushButton:pressed {	\n"
+""
+                        "	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"QTableWidget */\n"
+"QTableWidget {	\n"
+"	background-color: transparent;\n"
+"	padding: 10px;\n"
+"	border-radius: 5px;\n"
+"	gridline-color: rgb(44, 49, 58);\n"
+"	border-bottom: 1px solid rgb(44, 49, 60);\n"
+"}\n"
+"QTableWidget::item{\n"
+"	border-color: rgb(44, 49, 60);\n"
+"	padding-left: 5px;\n"
+"	padding-right: 5px;\n"
+"	gridline-color: rgb(44, 49, 60);\n"
+"}\n"
+"QTableWidget::item:selected{\n"
+"	background-color: rgb(189, 147, 249);\n"
+"}\n"
+"QHeaderView::section{\n"
+"	background-color: rgb(33, 37, 43);\n"
+"	max-width: 30px;\n"
+"	border: 1px solid rgb(44, 49, 58);\n"
+"	border-style: none;\n"
+"    border-bottom: 1px solid rgb(44, 49, 60);\n"
+"    border-right: 1px solid rgb(44, 49, 60);\n"
+"}\n"
+"QTableWidget::horizontalHeader {	\n"
+"	background-color: rgb(33, 37, 43);\n"
+"}\n"
+"QHeaderView::section:horizontal\n"
+"{\n"
+"   "
+                        " border: 1px solid rgb(33, 37, 43);\n"
+"	background-color: rgb(33, 37, 43);\n"
+"	padding: 3px;\n"
+"	border-top-left-radius: 7px;\n"
+"    border-top-right-radius: 7px;\n"
+"}\n"
+"QHeaderView::section:vertical\n"
+"{\n"
+"    border: 1px solid rgb(44, 49, 60);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"LineEdit */\n"
+"QLineEdit {\n"
+"	background-color: rgb(33, 37, 43);\n"
+"	border-radius: 5px;\n"
+"	border: 2px solid rgb(33, 37, 43);\n"
+"	padding-left: 10px;\n"
+"	selection-color: rgb(255, 255, 255);\n"
+"	selection-background-color: rgb(255, 121, 198);\n"
+"}\n"
+"QLineEdit:hover {\n"
+"	border: 2px solid rgb(64, 71, 88);\n"
+"}\n"
+"QLineEdit:focus {\n"
+"	border: 2px solid rgb(91, 101, 124);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"PlainTextEdit */\n"
+"QPlainTextEdit {\n"
+"	background-color: rgb(27, 29, 35);\n"
+"	border-radius: 5px;\n"
+"	padding: 10px;\n"
+"	selection-"
+                        "color: rgb(255, 255, 255);\n"
+"	selection-background-color: rgb(255, 121, 198);\n"
+"}\n"
+"QPlainTextEdit  QScrollBar:vertical {\n"
+"    width: 8px;\n"
+" }\n"
+"QPlainTextEdit  QScrollBar:horizontal {\n"
+"    height: 8px;\n"
+" }\n"
+"QPlainTextEdit:hover {\n"
+"	border: 2px solid rgb(64, 71, 88);\n"
+"}\n"
+"QPlainTextEdit:focus {\n"
+"	border: 2px solid rgb(91, 101, 124);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"ScrollBars */\n"
+"QScrollBar:horizontal {\n"
+"    border: none;\n"
+"    background: rgb(52, 59, 72);\n"
+"    height: 8px;\n"
+"    margin: 0px 21px 0 21px;\n"
+"	border-radius: 0px;\n"
+"}\n"
+"QScrollBar::handle:horizontal {\n"
+"    background: rgb(189, 147, 249);\n"
+"    min-width: 25px;\n"
+"	border-radius: 4px\n"
+"}\n"
+"QScrollBar::add-line:horizontal {\n"
+"    border: none;\n"
+"    background: rgb(55, 63, 77);\n"
+"    width: 20px;\n"
+"	border-top-right-radius: 4px;\n"
+"    border-bottom-right-radius: 4px;\n"
+"    subcontrol-positi"
+                        "on: right;\n"
+"    subcontrol-origin: margin;\n"
+"}\n"
+"QScrollBar::sub-line:horizontal {\n"
+"    border: none;\n"
+"    background: rgb(55, 63, 77);\n"
+"    width: 20px;\n"
+"	border-top-left-radius: 4px;\n"
+"    border-bottom-left-radius: 4px;\n"
+"    subcontrol-position: left;\n"
+"    subcontrol-origin: margin;\n"
+"}\n"
+"QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal\n"
+"{\n"
+"     background: none;\n"
+"}\n"
+"QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal\n"
+"{\n"
+"     background: none;\n"
+"}\n"
+" QScrollBar:vertical {\n"
+"	border: none;\n"
+"    background: rgb(52, 59, 72);\n"
+"    width: 8px;\n"
+"    margin: 21px 0 21px 0;\n"
+"	border-radius: 0px;\n"
+" }\n"
+" QScrollBar::handle:vertical {	\n"
+"	background: rgb(189, 147, 249);\n"
+"    min-height: 25px;\n"
+"	border-radius: 4px\n"
+" }\n"
+" QScrollBar::add-line:vertical {\n"
+"     border: none;\n"
+"    background: rgb(55, 63, 77);\n"
+"     height: 20px;\n"
+"	border-bottom-left-radius: 4px;\n"
+"    border-bottom-right-radius"
+                        ": 4px;\n"
+"     subcontrol-position: bottom;\n"
+"     subcontrol-origin: margin;\n"
+" }\n"
+" QScrollBar::sub-line:vertical {\n"
+"	border: none;\n"
+"    background: rgb(55, 63, 77);\n"
+"     height: 20px;\n"
+"	border-top-left-radius: 4px;\n"
+"    border-top-right-radius: 4px;\n"
+"     subcontrol-position: top;\n"
+"     subcontrol-origin: margin;\n"
+" }\n"
+" QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {\n"
+"     background: none;\n"
+" }\n"
+"\n"
+" QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {\n"
+"     background: none;\n"
+" }\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"CheckBox */\n"
+"QCheckBox::indicator {\n"
+"    border: 3px solid rgb(52, 59, 72);\n"
+"	width: 15px;\n"
+"	height: 15px;\n"
+"	border-radius: 10px;\n"
+"    background: rgb(44, 49, 60);\n"
+"}\n"
+"QCheckBox::indicator:hover {\n"
+"    border: 3px solid rgb(58, 66, 81);\n"
+"}\n"
+"QCheckBox::indicator:checked {\n"
+"    background: 3px solid rgb(52, 59,"
+                        " 72);\n"
+"	border: 3px solid rgb(52, 59, 72);	\n"
+"	background-image: url(:/icons/images/icons/cil-check-alt.png);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"RadioButton */\n"
+"QRadioButton::indicator {\n"
+"    border: 3px solid rgb(52, 59, 72);\n"
+"	width: 15px;\n"
+"	height: 15px;\n"
+"	border-radius: 10px;\n"
+"    background: rgb(44, 49, 60);\n"
+"}\n"
+"QRadioButton::indicator:hover {\n"
+"    border: 3px solid rgb(58, 66, 81);\n"
+"}\n"
+"QRadioButton::indicator:checked {\n"
+"    background: 3px solid rgb(94, 106, 130);\n"
+"	border: 3px solid rgb(52, 59, 72);	\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"ComboBox */\n"
+"QComboBox{\n"
+"	background-color: rgb(27, 29, 35);\n"
+"	border-radius: 5px;\n"
+"	border: 2px solid rgb(33, 37, 43);\n"
+"	padding: 5px;\n"
+"	padding-left: 10px;\n"
+"}\n"
+"QComboBox:hover{\n"
+"	border: 2px solid rgb(64, 71, 88);\n"
+"}\n"
+"QComboBox:"
+                        ":drop-down {\n"
+"	subcontrol-origin: padding;\n"
+"	subcontrol-position: top right;\n"
+"	width: 25px; \n"
+"	border-left-width: 3px;\n"
+"	border-left-color: rgba(39, 44, 54, 150);\n"
+"	border-left-style: solid;\n"
+"	border-top-right-radius: 3px;\n"
+"	border-bottom-right-radius: 3px;	\n"
+"	background-image: url(:/icons/images/icons/cil-arrow-bottom.png);\n"
+"	background-position: center;\n"
+"	background-repeat: no-reperat;\n"
+" }\n"
+"QComboBox QAbstractItemView {\n"
+"	color: rgb(255, 121, 198);	\n"
+"	background-color: rgb(33, 37, 43);\n"
+"	padding: 10px;\n"
+"	selection-background-color: rgb(39, 44, 54);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Sliders */\n"
+"QSlider::groove:horizontal {\n"
+"    border-radius: 5px;\n"
+"    height: 10px;\n"
+"	margin: 0px;\n"
+"	background-color: rgb(52, 59, 72);\n"
+"}\n"
+"QSlider::groove:horizontal:hover {\n"
+"	background-color: rgb(55, 62, 76);\n"
+"}\n"
+"QSlider::handle:horizontal {\n"
+"    background-co"
+                        "lor: rgb(189, 147, 249);\n"
+"    border: none;\n"
+"    height: 10px;\n"
+"    width: 10px;\n"
+"    margin: 0px;\n"
+"	border-radius: 5px;\n"
+"}\n"
+"QSlider::handle:horizontal:hover {\n"
+"    background-color: rgb(195, 155, 255);\n"
+"}\n"
+"QSlider::handle:horizontal:pressed {\n"
+"    background-color: rgb(255, 121, 198);\n"
+"}\n"
+"\n"
+"QSlider::groove:vertical {\n"
+"    border-radius: 5px;\n"
+"    width: 10px;\n"
+"    margin: 0px;\n"
+"	background-color: rgb(52, 59, 72);\n"
+"}\n"
+"QSlider::groove:vertical:hover {\n"
+"	background-color: rgb(55, 62, 76);\n"
+"}\n"
+"QSlider::handle:vertical {\n"
+"    background-color: rgb(189, 147, 249);\n"
+"	border: none;\n"
+"    height: 10px;\n"
+"    width: 10px;\n"
+"    margin: 0px;\n"
+"	border-radius: 5px;\n"
+"}\n"
+"QSlider::handle:vertical:hover {\n"
+"    background-color: rgb(195, 155, 255);\n"
+"}\n"
+"QSlider::handle:vertical:pressed {\n"
+"    background-color: rgb(255, 121, 198);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////"
+                        "////////////////\n"
+"CommandLinkButton */\n"
+"QCommandLinkButton {	\n"
+"	color: rgb(255, 121, 198);\n"
+"	border-radius: 5px;\n"
+"	padding: 5px;\n"
+"	color: rgb(255, 170, 255);\n"
+"}\n"
+"QCommandLinkButton:hover {	\n"
+"	color: rgb(255, 170, 255);\n"
+"	background-color: rgb(44, 49, 60);\n"
+"}\n"
+"QCommandLinkButton:pressed {	\n"
+"	color: rgb(189, 147, 249);\n"
+"	background-color: rgb(52, 58, 71);\n"
+"}\n"
+"\n"
+"/* /////////////////////////////////////////////////////////////////////////////////////////////////\n"
+"Button */\n"
+"#pagesContainer QPushButton {\n"
+"	border: 2px solid rgb(52, 59, 72);\n"
+"	border-radius: 5px;	\n"
+"	background-color: rgb(52, 59, 72);\n"
+"}\n"
+"#pagesContainer QPushButton:hover {\n"
+"	background-color: rgb(57, 65, 80);\n"
+"	border: 2px solid rgb(61, 70, 86);\n"
+"}\n"
+"#pagesContainer QPushButton:pressed {	\n"
+"	background-color: rgb(35, 40, 49);\n"
+"	border: 2px solid rgb(43, 50, 61);\n"
+"}\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"QToolButton { \n"
+"border-image:"
+                        " url(:/img/btn_mid_0.png);\n"
+"text-align: center;\n"
+"}\n"
+"QToolButton::menu-indicator { image: none; }\n"
+"\n"
+"\n"
+"#menuBar .QPushButton {	\n"
+"     background-position: left center;\n"
+"     background-repeat: no-repeat;\n"
+"	 border: none;\n"
+"	 /*border-left: 22px solid transparent;*/\n"
+"	 /*text-align: center;*/\n"
+"	padding-right: 10px;\n"
+"}\n"
+"#menuBar .QPushButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#menuBar .QPushButton:pressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"#menuBar .QToolButton {\n"
+"     background-position: left center;\n"
+"     background-repeat: no-repeat;\n"
+"	 border: none;\n"
+"	 /*border-left: 22px solid transparent;*/\n"
+"	 /*text-align: center;*/\n"
+"	padding-right: 10px;\n"
+"}\n"
+"#menuBar .QToolButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#menuBar .QToolButton:pressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"#extraMenuBar ."
+                        "QToolButton {\n"
+"     background-position: left center;\n"
+"     background-repeat: no-repeat;\n"
+"	 border: none;\n"
+"	 /*border-left: 22px solid transparent;*/\n"
+"	 /*text-align: center;*/\n"
+"	padding-right: 10px;\n"
+"}\n"
+"#extraMenuBar .QToolButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#extraMenuBar .QToolButton:pressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"#extraMenuBar .QPushButton {\n"
+"   /*background-position: left center;*/\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 22px solid transparent;\n"
+"	text-align: center;\n"
+"	/*padding-left: 44px;*/\n"
+"}\n"
+"#extraMenuBar .QPushButton:hover {\n"
+"	background-color: rgb(40, 44, 52);\n"
+"}\n"
+"#extraMenuBar .QPushButton:pressed {	\n"
+"	background-color: rgb(189, 147, 249);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"/* QMenu ------------------------------------------------------------------\n"
+"\n"
+"examples: https://doc.qt.io/"
+                        "qt-5/stylesheet-examples.html#customizing-qmenu\n"
+"\n"
+"--------------------------------------------------------------------------- */\n"
+"QMenu {\n"
+"    background-color: rgb(40, 44, 52);\n"
+"    margin: 2px; /* some spacing around the menu */\n"
+"}\n"
+"\n"
+"QMenu::item {\n"
+"    padding: 2px 25px 2px 20px;\n"
+"    border: 1px solid transparent; /* reserve space for selection border */\n"
+"}\n"
+"\n"
+"QMenu::item:selected {\n"
+"    border-color: darkblue;\n"
+"    background: rgba(100, 100, 100, 150);\n"
+"}\n"
+"\n"
+"QMenu::icon:checked { /* appearance of a 'checked' icon */\n"
+"    background: gray;\n"
+"    border: 1px inset gray;\n"
+"    position: absolute;\n"
+"    top: 1px;\n"
+"    right: 1px;\n"
+"    bottom: 1px;\n"
+"    left: 1px;\n"
+"}\n"
+"\n"
+"QMenu::separator {\n"
+"    height: 2px;\n"
+"    background: lightblue;\n"
+"    margin-left: 10px;\n"
+"    margin-right: 5px;\n"
+"}\n"
+"\n"
+"QMenu::indicator {\n"
+"    width: 13px;\n"
+"    height: 13px;\n"
+"}\n"
+"\n"
+"/*\n"
+"\n"
+"QMenu::indicator:non-exclusive:unch"
+                        "ecked {\n"
+"    image: url(:/images/checkbox_unchecked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:non-exclusive:unchecked:selected {\n"
+"    image: url(:/images/checkbox_unchecked_hover.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:non-exclusive:checked {\n"
+"    image: url(:/images/checkbox_checked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:non-exclusive:checked:selected {\n"
+"    image: url(:/images/checkbox_checked_hover.png);\n"
+"}\n"
+"\n"
+"\n"
+"QMenu::indicator:exclusive:unchecked {\n"
+"    image: url(:/images/radiobutton_unchecked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:exclusive:unchecked:selected {\n"
+"    image: url(:/images/radiobutton_unchecked_hover.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:exclusive:checked {\n"
+"    image: url(:/images/radiobutton_checked.png);\n"
+"}\n"
+"\n"
+"QMenu::indicator:exclusive:checked:selected {\n"
+"    image: url(:/images/radiobutton_checked_hover.png);\n"
+"}*/\n"
+"\n"
+"QTabWidget::pane {\n"
+"  border: 1px solid lightgray;\n"
+"  top:-1px; \n"
+"  background:  rgb(40, 44, 52); \n"
+"} \n"
+"\n"
+"Q"
+                        "TabBar::tab {\n"
+"  background: rgb(40, 44, 52);; \n"
+"  border: 1px solid lightgray; \n"
+"  padding: 2px;\n"
+"	padding-left: 10px;\n"
+"	padding-right: 10px;\n"
+"} \n"
+"\n"
+"QTabBar::tab:selected { \n"
+"  background:  rgb(189, 147, 249);\n"
+"  margin-bottom: -1px; \n"
+"}")
+        self.appMargins = QVBoxLayout(self.styleSheet)
+        self.appMargins.setSpacing(0)
+        self.appMargins.setObjectName(u"appMargins")
+        self.appMargins.setContentsMargins(10, 10, 10, 10)
+        self.bgApp = QFrame(self.styleSheet)
+        self.bgApp.setObjectName(u"bgApp")
+        self.bgApp.setToolTipDuration(0)
+        self.bgApp.setStyleSheet(u"")
+        self.bgApp.setFrameShape(QFrame.NoFrame)
+        self.bgApp.setFrameShadow(QFrame.Plain)
+        self.appLayout = QHBoxLayout(self.bgApp)
+        self.appLayout.setSpacing(0)
+        self.appLayout.setObjectName(u"appLayout")
+        self.appLayout.setContentsMargins(0, 0, 0, 0)
+        self.leftMenuBg = QFrame(self.bgApp)
+        self.leftMenuBg.setObjectName(u"leftMenuBg")
+        self.leftMenuBg.setMinimumSize(QSize(60, 0))
+        self.leftMenuBg.setMaximumSize(QSize(60, 16777215))
+        self.leftMenuBg.setFrameShape(QFrame.NoFrame)
+        self.leftMenuBg.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_3 = QVBoxLayout(self.leftMenuBg)
+        self.verticalLayout_3.setSpacing(0)
+        self.verticalLayout_3.setObjectName(u"verticalLayout_3")
+        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+        self.topLogoInfo = QFrame(self.leftMenuBg)
+        self.topLogoInfo.setObjectName(u"topLogoInfo")
+        self.topLogoInfo.setMinimumSize(QSize(0, 50))
+        self.topLogoInfo.setMaximumSize(QSize(16777215, 50))
+        self.topLogoInfo.setFrameShape(QFrame.NoFrame)
+        self.topLogoInfo.setFrameShadow(QFrame.Raised)
+        self.titleLeftApp = QLabel(self.topLogoInfo)
+        self.titleLeftApp.setObjectName(u"titleLeftApp")
+        self.titleLeftApp.setGeometry(QRect(60, 3, 160, 20))
+        font = QFont()
+        font.setFamilies([u"Segoe UI Semibold"])
+        font.setPointSize(12)
+        font.setBold(False)
+        font.setItalic(False)
+        self.titleLeftApp.setFont(font)
+        self.titleLeftApp.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
+        self.topLogo = QFrame(self.topLogoInfo)
+        self.topLogo.setObjectName(u"topLogo")
+        self.topLogo.setGeometry(QRect(10, 4, 42, 42))
+        self.topLogo.setMinimumSize(QSize(42, 42))
+        self.topLogo.setMaximumSize(QSize(42, 42))
+        self.topLogo.setFrameShape(QFrame.NoFrame)
+        self.topLogo.setFrameShadow(QFrame.Raised)
+        self.titleLeftDescription = QLabel(self.topLogoInfo)
+        self.titleLeftDescription.setObjectName(u"titleLeftDescription")
+        self.titleLeftDescription.setGeometry(QRect(60, 22, 160, 16))
+        self.titleLeftDescription.setMaximumSize(QSize(16777215, 16))
+        font1 = QFont()
+        font1.setFamilies([u"Segoe UI"])
+        font1.setPointSize(8)
+        font1.setBold(False)
+        font1.setItalic(False)
+        self.titleLeftDescription.setFont(font1)
+        self.titleLeftDescription.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
+
+        self.verticalLayout_3.addWidget(self.topLogoInfo)
+
+        self.leftMenuFrame = QFrame(self.leftMenuBg)
+        self.leftMenuFrame.setObjectName(u"leftMenuFrame")
+        self.leftMenuFrame.setEnabled(True)
+        self.leftMenuFrame.setMinimumSize(QSize(0, 0))
+        self.leftMenuFrame.setMaximumSize(QSize(16777215, 16777215))
+        self.leftMenuFrame.setToolTipDuration(0)
+        self.leftMenuFrame.setLayoutDirection(Qt.LeftToRight)
+        self.leftMenuFrame.setFrameShape(QFrame.NoFrame)
+        self.leftMenuFrame.setFrameShadow(QFrame.Raised)
+        self.verticalMenuLayout = QVBoxLayout(self.leftMenuFrame)
+        self.verticalMenuLayout.setSpacing(0)
+        self.verticalMenuLayout.setObjectName(u"verticalMenuLayout")
+        self.verticalMenuLayout.setContentsMargins(0, 0, 0, 0)
+        self.toggleBox = QFrame(self.leftMenuFrame)
+        self.toggleBox.setObjectName(u"toggleBox")
+        self.toggleBox.setMaximumSize(QSize(16777215, 45))
+        self.toggleBox.setFrameShape(QFrame.NoFrame)
+        self.toggleBox.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_4 = QVBoxLayout(self.toggleBox)
+        self.verticalLayout_4.setSpacing(0)
+        self.verticalLayout_4.setObjectName(u"verticalLayout_4")
+        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
+        self.toggleButton = QPushButton(self.toggleBox)
+        self.toggleButton.setObjectName(u"toggleButton")
+        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.toggleButton.sizePolicy().hasHeightForWidth())
+        self.toggleButton.setSizePolicy(sizePolicy)
+        self.toggleButton.setMinimumSize(QSize(0, 45))
+        font2 = QFont()
+        font2.setFamilies([u"Segoe UI"])
+        font2.setPointSize(10)
+        font2.setBold(False)
+        font2.setItalic(False)
+        self.toggleButton.setFont(font2)
+        self.toggleButton.setCursor(QCursor(Qt.PointingHandCursor))
+        self.toggleButton.setLayoutDirection(Qt.LeftToRight)
+        self.toggleButton.setStyleSheet(u"background-image: url(:/icons/images/icons/icon_menu.png);")
+
+        self.verticalLayout_4.addWidget(self.toggleButton)
+
+
+        self.verticalMenuLayout.addWidget(self.toggleBox)
+
+        self.topMenu = QFrame(self.leftMenuFrame)
+        self.topMenu.setObjectName(u"topMenu")
+        self.topMenu.setMinimumSize(QSize(0, 10))
+        self.topMenu.setLayoutDirection(Qt.LeftToRight)
+        self.topMenu.setFrameShape(QFrame.NoFrame)
+        self.topMenu.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_8 = QVBoxLayout(self.topMenu)
+        self.verticalLayout_8.setSpacing(0)
+        self.verticalLayout_8.setObjectName(u"verticalLayout_8")
+        self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
+        self.btn_start_measuring_routine = QPushButton(self.topMenu)
+        self.btn_start_measuring_routine.setObjectName(u"btn_start_measuring_routine")
+        self.btn_start_measuring_routine.setMinimumSize(QSize(60, 60))
+        self.btn_start_measuring_routine.setMaximumSize(QSize(16660, 60))
+        self.btn_start_measuring_routine.setStyleSheet(u"QPushButton {	\n"
+"	background-position: left center;\n"
+"    background-repeat: no-repeat;\n"
+"	border: none;\n"
+"	border-left: 22px solid transparent;\n"
+"	background-color: rgb(36, 209, 21);\n"
+"	text-align: left;\n"
+"	padding-left: 44px;\n"
+"    background-image: url(:/icons/images/icons/cil-media-play.png);\n"
+"}\n"
+"\n"
+"QPushButton:hover {\n"
+"	background-color: rgb(26, 153, 16);\n"
+"}\n"
+"\n"
+"QPushButton:pressed {	\n"
+"	background-color: rgb(20, 120, 12);\n"
+"	color: rgb(255, 255, 255);\n"
+"}\n"
+"\n"
+"\n"
+"")
+
+        self.verticalLayout_8.addWidget(self.btn_start_measuring_routine)
+
+        self.btn_home = QPushButton(self.topMenu)
+        self.btn_home.setObjectName(u"btn_home")
+        sizePolicy.setHeightForWidth(self.btn_home.sizePolicy().hasHeightForWidth())
+        self.btn_home.setSizePolicy(sizePolicy)
+        self.btn_home.setMinimumSize(QSize(0, 45))
+        self.btn_home.setMaximumSize(QSize(16777215, 16777215))
+        self.btn_home.setFont(font2)
+        self.btn_home.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_home.setLayoutDirection(Qt.LeftToRight)
+        self.btn_home.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-home.png);")
+
+        self.verticalLayout_8.addWidget(self.btn_home)
+
+        self.btn_adc_control = QPushButton(self.topMenu)
+        self.btn_adc_control.setObjectName(u"btn_adc_control")
+        sizePolicy.setHeightForWidth(self.btn_adc_control.sizePolicy().hasHeightForWidth())
+        self.btn_adc_control.setSizePolicy(sizePolicy)
+        self.btn_adc_control.setMinimumSize(QSize(0, 45))
+        self.btn_adc_control.setFont(font2)
+        self.btn_adc_control.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_adc_control.setLayoutDirection(Qt.LeftToRight)
+        self.btn_adc_control.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-signal-cellular-3.png);")
+        self.btn_adc_control.setIconSize(QSize(16, 16))
+
+        self.verticalLayout_8.addWidget(self.btn_adc_control)
+
+        self.btn_laser_control = QPushButton(self.topMenu)
+        self.btn_laser_control.setObjectName(u"btn_laser_control")
+        sizePolicy.setHeightForWidth(self.btn_laser_control.sizePolicy().hasHeightForWidth())
+        self.btn_laser_control.setSizePolicy(sizePolicy)
+        self.btn_laser_control.setMinimumSize(QSize(0, 45))
+        self.btn_laser_control.setFont(font2)
+        self.btn_laser_control.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_laser_control.setLayoutDirection(Qt.LeftToRight)
+        self.btn_laser_control.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-lightbulb.png);")
+
+        self.verticalLayout_8.addWidget(self.btn_laser_control)
+
+        self.btn_probe_control = QPushButton(self.topMenu)
+        self.btn_probe_control.setObjectName(u"btn_probe_control")
+        self.btn_probe_control.setEnabled(True)
+        sizePolicy.setHeightForWidth(self.btn_probe_control.sizePolicy().hasHeightForWidth())
+        self.btn_probe_control.setSizePolicy(sizePolicy)
+        self.btn_probe_control.setMinimumSize(QSize(0, 45))
+        self.btn_probe_control.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-action-redo.png);")
+
+        self.verticalLayout_8.addWidget(self.btn_probe_control)
+
+        self.btn_measured_data = QPushButton(self.topMenu)
+        self.btn_measured_data.setObjectName(u"btn_measured_data")
+        self.btn_measured_data.setMinimumSize(QSize(0, 45))
+        self.btn_measured_data.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-description.png);")
+
+        self.verticalLayout_8.addWidget(self.btn_measured_data)
+
+        self.btn_exit = QPushButton(self.topMenu)
+        self.btn_exit.setObjectName(u"btn_exit")
+        sizePolicy.setHeightForWidth(self.btn_exit.sizePolicy().hasHeightForWidth())
+        self.btn_exit.setSizePolicy(sizePolicy)
+        self.btn_exit.setMinimumSize(QSize(60, 45))
+        self.btn_exit.setFont(font2)
+        self.btn_exit.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_exit.setLayoutDirection(Qt.LeftToRight)
+        self.btn_exit.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-x.png);")
+
+        self.verticalLayout_8.addWidget(self.btn_exit)
+
+
+        self.verticalMenuLayout.addWidget(self.topMenu)
+
+        self.bottomMenu = QFrame(self.leftMenuFrame)
+        self.bottomMenu.setObjectName(u"bottomMenu")
+        self.bottomMenu.setFrameShape(QFrame.NoFrame)
+        self.bottomMenu.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_9 = QVBoxLayout(self.bottomMenu)
+        self.verticalLayout_9.setSpacing(0)
+        self.verticalLayout_9.setObjectName(u"verticalLayout_9")
+        self.verticalLayout_9.setContentsMargins(0, 0, 0, 0)
+        self.toggleLeftBox = QPushButton(self.bottomMenu)
+        self.toggleLeftBox.setObjectName(u"toggleLeftBox")
+        sizePolicy.setHeightForWidth(self.toggleLeftBox.sizePolicy().hasHeightForWidth())
+        self.toggleLeftBox.setSizePolicy(sizePolicy)
+        self.toggleLeftBox.setMinimumSize(QSize(0, 45))
+        self.toggleLeftBox.setFont(font2)
+        self.toggleLeftBox.setCursor(QCursor(Qt.PointingHandCursor))
+        self.toggleLeftBox.setLayoutDirection(Qt.LeftToRight)
+        self.toggleLeftBox.setStyleSheet(u"background-image: url(:/icons/images/icons/icon_settings.png);")
+
+        self.verticalLayout_9.addWidget(self.toggleLeftBox)
+
+
+        self.verticalMenuLayout.addWidget(self.bottomMenu)
+
+
+        self.verticalLayout_3.addWidget(self.leftMenuFrame)
+
+
+        self.appLayout.addWidget(self.leftMenuBg)
+
+        self.extraLeftBox = QFrame(self.bgApp)
+        self.extraLeftBox.setObjectName(u"extraLeftBox")
+        self.extraLeftBox.setMinimumSize(QSize(0, 0))
+        self.extraLeftBox.setMaximumSize(QSize(0, 16777215))
+        self.extraLeftBox.setFrameShape(QFrame.NoFrame)
+        self.extraLeftBox.setFrameShadow(QFrame.Raised)
+        self.extraLeftBox.setLineWidth(0)
+        self.extraColumLayout = QVBoxLayout(self.extraLeftBox)
+        self.extraColumLayout.setSpacing(0)
+        self.extraColumLayout.setObjectName(u"extraColumLayout")
+        self.extraColumLayout.setContentsMargins(0, 0, 0, 0)
+        self.extraTopBg = QFrame(self.extraLeftBox)
+        self.extraTopBg.setObjectName(u"extraTopBg")
+        self.extraTopBg.setMinimumSize(QSize(0, 50))
+        self.extraTopBg.setMaximumSize(QSize(16777215, 50))
+        self.extraTopBg.setFrameShape(QFrame.NoFrame)
+        self.extraTopBg.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_5 = QVBoxLayout(self.extraTopBg)
+        self.verticalLayout_5.setSpacing(0)
+        self.verticalLayout_5.setObjectName(u"verticalLayout_5")
+        self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
+        self.extraTopLayout = QGridLayout()
+        self.extraTopLayout.setObjectName(u"extraTopLayout")
+        self.extraTopLayout.setHorizontalSpacing(10)
+        self.extraTopLayout.setVerticalSpacing(0)
+        self.extraTopLayout.setContentsMargins(10, -1, 10, -1)
+        self.extraIcon = QFrame(self.extraTopBg)
+        self.extraIcon.setObjectName(u"extraIcon")
+        self.extraIcon.setMinimumSize(QSize(20, 0))
+        self.extraIcon.setMaximumSize(QSize(20, 20))
+        self.extraIcon.setFrameShape(QFrame.NoFrame)
+        self.extraIcon.setFrameShadow(QFrame.Raised)
+
+        self.extraTopLayout.addWidget(self.extraIcon, 0, 0, 1, 1)
+
+        self.extraLabel = QLabel(self.extraTopBg)
+        self.extraLabel.setObjectName(u"extraLabel")
+        self.extraLabel.setMinimumSize(QSize(150, 0))
+
+        self.extraTopLayout.addWidget(self.extraLabel, 0, 1, 1, 1)
+
+        self.extraCloseColumnBtn = QPushButton(self.extraTopBg)
+        self.extraCloseColumnBtn.setObjectName(u"extraCloseColumnBtn")
+        self.extraCloseColumnBtn.setMinimumSize(QSize(28, 28))
+        self.extraCloseColumnBtn.setMaximumSize(QSize(28, 28))
+        self.extraCloseColumnBtn.setCursor(QCursor(Qt.PointingHandCursor))
+        icon = QIcon()
+        icon.addFile(u":/icons/images/icons/icon_close.png", QSize(), QIcon.Normal, QIcon.Off)
+        self.extraCloseColumnBtn.setIcon(icon)
+        self.extraCloseColumnBtn.setIconSize(QSize(20, 20))
+
+        self.extraTopLayout.addWidget(self.extraCloseColumnBtn, 0, 2, 1, 1)
+
+
+        self.verticalLayout_5.addLayout(self.extraTopLayout)
+
+
+        self.extraColumLayout.addWidget(self.extraTopBg)
+
+        self.extraContent = QFrame(self.extraLeftBox)
+        self.extraContent.setObjectName(u"extraContent")
+        self.extraContent.setFrameShape(QFrame.NoFrame)
+        self.extraContent.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_12 = QVBoxLayout(self.extraContent)
+        self.verticalLayout_12.setSpacing(0)
+        self.verticalLayout_12.setObjectName(u"verticalLayout_12")
+        self.verticalLayout_12.setContentsMargins(0, 0, 0, 0)
+        self.extraTopMenu = QFrame(self.extraContent)
+        self.extraTopMenu.setObjectName(u"extraTopMenu")
+        self.extraTopMenu.setFrameShape(QFrame.NoFrame)
+        self.extraTopMenu.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_11 = QVBoxLayout(self.extraTopMenu)
+        self.verticalLayout_11.setSpacing(0)
+        self.verticalLayout_11.setObjectName(u"verticalLayout_11")
+        self.verticalLayout_11.setContentsMargins(0, 0, 0, 0)
+        self.btn_share = QPushButton(self.extraTopMenu)
+        self.btn_share.setObjectName(u"btn_share")
+        sizePolicy.setHeightForWidth(self.btn_share.sizePolicy().hasHeightForWidth())
+        self.btn_share.setSizePolicy(sizePolicy)
+        self.btn_share.setMinimumSize(QSize(0, 45))
+        self.btn_share.setFont(font2)
+        self.btn_share.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_share.setLayoutDirection(Qt.LeftToRight)
+        self.btn_share.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-share-boxed.png);")
+
+        self.verticalLayout_11.addWidget(self.btn_share)
+
+        self.btn_adjustments = QPushButton(self.extraTopMenu)
+        self.btn_adjustments.setObjectName(u"btn_adjustments")
+        sizePolicy.setHeightForWidth(self.btn_adjustments.sizePolicy().hasHeightForWidth())
+        self.btn_adjustments.setSizePolicy(sizePolicy)
+        self.btn_adjustments.setMinimumSize(QSize(0, 45))
+        self.btn_adjustments.setFont(font2)
+        self.btn_adjustments.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_adjustments.setLayoutDirection(Qt.LeftToRight)
+        self.btn_adjustments.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-equalizer.png);")
+
+        self.verticalLayout_11.addWidget(self.btn_adjustments)
+
+        self.btn_more = QPushButton(self.extraTopMenu)
+        self.btn_more.setObjectName(u"btn_more")
+        sizePolicy.setHeightForWidth(self.btn_more.sizePolicy().hasHeightForWidth())
+        self.btn_more.setSizePolicy(sizePolicy)
+        self.btn_more.setMinimumSize(QSize(0, 45))
+        self.btn_more.setFont(font2)
+        self.btn_more.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_more.setLayoutDirection(Qt.LeftToRight)
+        self.btn_more.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-layers.png);")
+
+        self.verticalLayout_11.addWidget(self.btn_more)
+
+
+        self.verticalLayout_12.addWidget(self.extraTopMenu, 0, Qt.AlignTop)
+
+        self.extraCenter = QFrame(self.extraContent)
+        self.extraCenter.setObjectName(u"extraCenter")
+        self.extraCenter.setFrameShape(QFrame.NoFrame)
+        self.extraCenter.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_10 = QVBoxLayout(self.extraCenter)
+        self.verticalLayout_10.setObjectName(u"verticalLayout_10")
+        self.textEdit = QTextEdit(self.extraCenter)
+        self.textEdit.setObjectName(u"textEdit")
+        self.textEdit.setMinimumSize(QSize(222, 0))
+        self.textEdit.setStyleSheet(u"background: transparent;")
+        self.textEdit.setFrameShape(QFrame.NoFrame)
+        self.textEdit.setReadOnly(True)
+
+        self.verticalLayout_10.addWidget(self.textEdit)
+
+
+        self.verticalLayout_12.addWidget(self.extraCenter)
+
+        self.extraBottom = QFrame(self.extraContent)
+        self.extraBottom.setObjectName(u"extraBottom")
+        self.extraBottom.setFrameShape(QFrame.NoFrame)
+        self.extraBottom.setFrameShadow(QFrame.Raised)
+
+        self.verticalLayout_12.addWidget(self.extraBottom)
+
+
+        self.extraColumLayout.addWidget(self.extraContent)
+
+
+        self.appLayout.addWidget(self.extraLeftBox)
+
+        self.contentBox = QFrame(self.bgApp)
+        self.contentBox.setObjectName(u"contentBox")
+        self.contentBox.setFrameShape(QFrame.NoFrame)
+        self.contentBox.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_2 = QVBoxLayout(self.contentBox)
+        self.verticalLayout_2.setSpacing(0)
+        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
+        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+        self.contentTopBg = QFrame(self.contentBox)
+        self.contentTopBg.setObjectName(u"contentTopBg")
+        self.contentTopBg.setMinimumSize(QSize(0, 50))
+        self.contentTopBg.setMaximumSize(QSize(16777215, 50))
+        self.contentTopBg.setFrameShape(QFrame.NoFrame)
+        self.contentTopBg.setFrameShadow(QFrame.Raised)
+        self.horizontalLayout = QHBoxLayout(self.contentTopBg)
+        self.horizontalLayout.setSpacing(0)
+        self.horizontalLayout.setObjectName(u"horizontalLayout")
+        self.horizontalLayout.setContentsMargins(0, 0, 10, 0)
+        self.leftBox = QFrame(self.contentTopBg)
+        self.leftBox.setObjectName(u"leftBox")
+        sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
+        sizePolicy1.setHorizontalStretch(0)
+        sizePolicy1.setVerticalStretch(0)
+        sizePolicy1.setHeightForWidth(self.leftBox.sizePolicy().hasHeightForWidth())
+        self.leftBox.setSizePolicy(sizePolicy1)
+        self.leftBox.setFocusPolicy(Qt.NoFocus)
+        self.leftBox.setFrameShape(QFrame.NoFrame)
+        self.leftBox.setFrameShadow(QFrame.Raised)
+        self.horizontalLayout_3 = QHBoxLayout(self.leftBox)
+        self.horizontalLayout_3.setSpacing(0)
+        self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
+        self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
+        self.verticalFrame = QFrame(self.leftBox)
+        self.verticalFrame.setObjectName(u"verticalFrame")
+        self.formLayout = QFormLayout(self.verticalFrame)
+        self.formLayout.setObjectName(u"formLayout")
+        self.formLayout.setHorizontalSpacing(0)
+        self.formLayout.setContentsMargins(0, 0, 0, 0)
+        self.menuBar = QFrame(self.verticalFrame)
+        self.menuBar.setObjectName(u"menuBar")
+        sizePolicy2 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
+        sizePolicy2.setHorizontalStretch(0)
+        sizePolicy2.setVerticalStretch(0)
+        sizePolicy2.setHeightForWidth(self.menuBar.sizePolicy().hasHeightForWidth())
+        self.menuBar.setSizePolicy(sizePolicy2)
+        self.menuBar.setMinimumSize(QSize(0, 0))
+        self.menuBar.setFocusPolicy(Qt.NoFocus)
+        self.menuBar.setFrameShadow(QFrame.Raised)
+        self.horizontalLayout_6 = QHBoxLayout(self.menuBar)
+        self.horizontalLayout_6.setSpacing(0)
+        self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
+        self.horizontalLayout_6.setSizeConstraint(QLayout.SetDefaultConstraint)
+        self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
+        self.menu_file = QToolButton(self.menuBar)
+        self.menu_file.setObjectName(u"menu_file")
+        self.menu_file.setEnabled(True)
+        sizePolicy3 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+        sizePolicy3.setHorizontalStretch(0)
+        sizePolicy3.setVerticalStretch(0)
+        sizePolicy3.setHeightForWidth(self.menu_file.sizePolicy().hasHeightForWidth())
+        self.menu_file.setSizePolicy(sizePolicy3)
+        self.menu_file.setMinimumSize(QSize(0, 16))
+        self.menu_file.setMaximumSize(QSize(16777215, 16777215))
+        font3 = QFont()
+        font3.setFamilies([u"Segoe UI"])
+        font3.setPointSize(10)
+        font3.setBold(False)
+        font3.setItalic(False)
+        font3.setKerning(True)
+        self.menu_file.setFont(font3)
+        self.menu_file.setMouseTracking(True)
+        self.menu_file.setLayoutDirection(Qt.LeftToRight)
+        self.menu_file.setAutoFillBackground(False)
+        self.menu_file.setStyleSheet(u"")
+        self.menu_file.setCheckable(False)
+        self.menu_file.setPopupMode(QToolButton.InstantPopup)
+        self.menu_file.setToolButtonStyle(Qt.ToolButtonTextOnly)
+        self.menu_file.setAutoRaise(True)
+
+        self.horizontalLayout_6.addWidget(self.menu_file)
+
+        self.menu_edit = QToolButton(self.menuBar)
+        self.menu_edit.setObjectName(u"menu_edit")
+
+        self.horizontalLayout_6.addWidget(self.menu_edit)
+
+        self.menu_run = QToolButton(self.menuBar)
+        self.menu_run.setObjectName(u"menu_run")
+        self.menu_run.setMinimumSize(QSize(0, 0))
+        self.menu_run.setStyleSheet(u"")
+        self.menu_run.setPopupMode(QToolButton.InstantPopup)
+        self.menu_run.setToolButtonStyle(Qt.ToolButtonTextOnly)
+        self.menu_run.setAutoRaise(True)
+
+        self.horizontalLayout_6.addWidget(self.menu_run)
+
+
+        self.formLayout.setWidget(1, QFormLayout.LabelRole, self.menuBar)
+
+        self.titleRight = QLabel(self.verticalFrame)
+        self.titleRight.setObjectName(u"titleRight")
+        sizePolicy4 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
+        sizePolicy4.setHorizontalStretch(0)
+        sizePolicy4.setVerticalStretch(0)
+        sizePolicy4.setHeightForWidth(self.titleRight.sizePolicy().hasHeightForWidth())
+        self.titleRight.setSizePolicy(sizePolicy4)
+        self.titleRight.setMaximumSize(QSize(16777215, 45))
+        self.titleRight.setFont(font2)
+        self.titleRight.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
+
+        self.formLayout.setWidget(0, QFormLayout.LabelRole, self.titleRight)
+
+
+        self.horizontalLayout_3.addWidget(self.verticalFrame)
+
+
+        self.horizontalLayout.addWidget(self.leftBox)
+
+        self.rightButtons = QFrame(self.contentTopBg)
+        self.rightButtons.setObjectName(u"rightButtons")
+        self.rightButtons.setMinimumSize(QSize(0, 28))
+        self.rightButtons.setFrameShape(QFrame.NoFrame)
+        self.rightButtons.setFrameShadow(QFrame.Raised)
+        self.horizontalLayout_2 = QHBoxLayout(self.rightButtons)
+        self.horizontalLayout_2.setSpacing(5)
+        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
+        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+        self.settingsTopBtn = QPushButton(self.rightButtons)
+        self.settingsTopBtn.setObjectName(u"settingsTopBtn")
+        self.settingsTopBtn.setMinimumSize(QSize(28, 28))
+        self.settingsTopBtn.setMaximumSize(QSize(28, 28))
+        self.settingsTopBtn.setCursor(QCursor(Qt.PointingHandCursor))
+        icon1 = QIcon()
+        icon1.addFile(u":/icons/images/icons/icon_settings.png", QSize(), QIcon.Normal, QIcon.Off)
+        self.settingsTopBtn.setIcon(icon1)
+        self.settingsTopBtn.setIconSize(QSize(20, 20))
+
+        self.horizontalLayout_2.addWidget(self.settingsTopBtn)
+
+        self.minimizeAppBtn = QPushButton(self.rightButtons)
+        self.minimizeAppBtn.setObjectName(u"minimizeAppBtn")
+        self.minimizeAppBtn.setMinimumSize(QSize(28, 28))
+        self.minimizeAppBtn.setMaximumSize(QSize(28, 28))
+        self.minimizeAppBtn.setCursor(QCursor(Qt.PointingHandCursor))
+        icon2 = QIcon()
+        icon2.addFile(u":/icons/images/icons/icon_minimize.png", QSize(), QIcon.Normal, QIcon.Off)
+        self.minimizeAppBtn.setIcon(icon2)
+        self.minimizeAppBtn.setIconSize(QSize(20, 20))
+
+        self.horizontalLayout_2.addWidget(self.minimizeAppBtn)
+
+        self.maximizeRestoreAppBtn = QPushButton(self.rightButtons)
+        self.maximizeRestoreAppBtn.setObjectName(u"maximizeRestoreAppBtn")
+        self.maximizeRestoreAppBtn.setMinimumSize(QSize(28, 28))
+        self.maximizeRestoreAppBtn.setMaximumSize(QSize(28, 28))
+        font4 = QFont()
+        font4.setFamilies([u"Segoe UI"])
+        font4.setPointSize(10)
+        font4.setBold(False)
+        font4.setItalic(False)
+        font4.setStyleStrategy(QFont.PreferDefault)
+        self.maximizeRestoreAppBtn.setFont(font4)
+        self.maximizeRestoreAppBtn.setCursor(QCursor(Qt.PointingHandCursor))
+        icon3 = QIcon()
+        icon3.addFile(u":/icons/images/icons/icon_maximize.png", QSize(), QIcon.Normal, QIcon.Off)
+        self.maximizeRestoreAppBtn.setIcon(icon3)
+        self.maximizeRestoreAppBtn.setIconSize(QSize(20, 20))
+
+        self.horizontalLayout_2.addWidget(self.maximizeRestoreAppBtn)
+
+        self.closeAppBtn = QPushButton(self.rightButtons)
+        self.closeAppBtn.setObjectName(u"closeAppBtn")
+        self.closeAppBtn.setMinimumSize(QSize(28, 28))
+        self.closeAppBtn.setMaximumSize(QSize(28, 28))
+        self.closeAppBtn.setCursor(QCursor(Qt.PointingHandCursor))
+        self.closeAppBtn.setIcon(icon)
+        self.closeAppBtn.setIconSize(QSize(20, 20))
+
+        self.horizontalLayout_2.addWidget(self.closeAppBtn)
+
+
+        self.horizontalLayout.addWidget(self.rightButtons, 0, Qt.AlignRight)
+
+
+        self.verticalLayout_2.addWidget(self.contentTopBg)
+
+        self.contentBottom = QFrame(self.contentBox)
+        self.contentBottom.setObjectName(u"contentBottom")
+        self.contentBottom.setFrameShape(QFrame.NoFrame)
+        self.contentBottom.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_6 = QVBoxLayout(self.contentBottom)
+        self.verticalLayout_6.setSpacing(0)
+        self.verticalLayout_6.setObjectName(u"verticalLayout_6")
+        self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
+        self.content = QFrame(self.contentBottom)
+        self.content.setObjectName(u"content")
+        self.content.setFrameShape(QFrame.NoFrame)
+        self.content.setFrameShadow(QFrame.Raised)
+        self.horizontalLayout_4 = QHBoxLayout(self.content)
+        self.horizontalLayout_4.setSpacing(0)
+        self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
+        self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
+        self.pagesContainer = QFrame(self.content)
+        self.pagesContainer.setObjectName(u"pagesContainer")
+        self.pagesContainer.setStyleSheet(u"")
+        self.pagesContainer.setFrameShape(QFrame.NoFrame)
+        self.pagesContainer.setFrameShadow(QFrame.Raised)
+        self.gridLayout_5 = QGridLayout(self.pagesContainer)
+        self.gridLayout_5.setObjectName(u"gridLayout_5")
+        self.gridLayout_5.setContentsMargins(10, 10, 10, 10)
+        self.stackedWidget = QStackedWidget(self.pagesContainer)
+        self.stackedWidget.setObjectName(u"stackedWidget")
+        self.stackedWidget.setStyleSheet(u"background: transparent;")
+        self.home = QWidget()
+        self.home.setObjectName(u"home")
+        self.home.setStyleSheet(u"")
+        self.gridLayout_7 = QGridLayout(self.home)
+        self.gridLayout_7.setObjectName(u"gridLayout_7")
+        self.home_layout = QGridLayout()
+        self.home_layout.setObjectName(u"home_layout")
+
+        self.gridLayout_7.addLayout(self.home_layout, 0, 0, 1, 1)
+
+        self.stackedWidget.addWidget(self.home)
+        self.prober_control = QWidget()
+        self.prober_control.setObjectName(u"prober_control")
+        self.verticalLayout_20 = QVBoxLayout(self.prober_control)
+        self.verticalLayout_20.setObjectName(u"verticalLayout_20")
+        self.prober_control_layout = QGridLayout()
+        self.prober_control_layout.setObjectName(u"prober_control_layout")
+        self.prober_control_layout.setContentsMargins(1, 2, 3, -1)
+
+        self.verticalLayout_20.addLayout(self.prober_control_layout)
+
+        self.stackedWidget.addWidget(self.prober_control)
+        self.adc_control = QWidget()
+        self.adc_control.setObjectName(u"adc_control")
+        self.gridLayout_6 = QGridLayout(self.adc_control)
+        self.gridLayout_6.setObjectName(u"gridLayout_6")
+        self.adc_control_layout = QGridLayout()
+        self.adc_control_layout.setObjectName(u"adc_control_layout")
+
+        self.gridLayout_6.addLayout(self.adc_control_layout, 0, 0, 1, 1)
+
+        self.stackedWidget.addWidget(self.adc_control)
+        self.laser_control = QWidget()
+        self.laser_control.setObjectName(u"laser_control")
+        self.gridLayout_4 = QGridLayout(self.laser_control)
+        self.gridLayout_4.setObjectName(u"gridLayout_4")
+        self.laser_control_layout = QGridLayout()
+        self.laser_control_layout.setObjectName(u"laser_control_layout")
+
+        self.gridLayout_4.addLayout(self.laser_control_layout, 0, 0, 1, 1)
+
+        self.stackedWidget.addWidget(self.laser_control)
+        self.measured_data = QWidget()
+        self.measured_data.setObjectName(u"measured_data")
+        self.gridLayout_2 = QGridLayout(self.measured_data)
+        self.gridLayout_2.setObjectName(u"gridLayout_2")
+        self.measured_data_layout = QGridLayout()
+        self.measured_data_layout.setObjectName(u"measured_data_layout")
+
+        self.gridLayout_2.addLayout(self.measured_data_layout, 0, 0, 1, 1)
+
+        self.stackedWidget.addWidget(self.measured_data)
+
+        self.gridLayout_5.addWidget(self.stackedWidget, 0, 0, 1, 1)
+
+
+        self.horizontalLayout_4.addWidget(self.pagesContainer)
+
+        self.extraRightBox = QFrame(self.content)
+        self.extraRightBox.setObjectName(u"extraRightBox")
+        self.extraRightBox.setMinimumSize(QSize(0, 0))
+        self.extraRightBox.setMaximumSize(QSize(0, 16777215))
+        self.extraRightBox.setFrameShape(QFrame.NoFrame)
+        self.extraRightBox.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_7 = QVBoxLayout(self.extraRightBox)
+        self.verticalLayout_7.setSpacing(0)
+        self.verticalLayout_7.setObjectName(u"verticalLayout_7")
+        self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
+        self.themeSettingsTopDetail = QFrame(self.extraRightBox)
+        self.themeSettingsTopDetail.setObjectName(u"themeSettingsTopDetail")
+        self.themeSettingsTopDetail.setMaximumSize(QSize(16777215, 3))
+        self.themeSettingsTopDetail.setFrameShape(QFrame.NoFrame)
+        self.themeSettingsTopDetail.setFrameShadow(QFrame.Raised)
+
+        self.verticalLayout_7.addWidget(self.themeSettingsTopDetail)
+
+        self.contentSettings = QFrame(self.extraRightBox)
+        self.contentSettings.setObjectName(u"contentSettings")
+        self.contentSettings.setFrameShape(QFrame.NoFrame)
+        self.contentSettings.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_13 = QVBoxLayout(self.contentSettings)
+        self.verticalLayout_13.setSpacing(0)
+        self.verticalLayout_13.setObjectName(u"verticalLayout_13")
+        self.verticalLayout_13.setContentsMargins(0, 0, 0, 0)
+        self.txt_logs = QTextEdit(self.contentSettings)
+        self.txt_logs.setObjectName(u"txt_logs")
+
+        self.verticalLayout_13.addWidget(self.txt_logs)
+
+        self.topMenus = QFrame(self.contentSettings)
+        self.topMenus.setObjectName(u"topMenus")
+        self.topMenus.setFrameShape(QFrame.NoFrame)
+        self.topMenus.setFrameShadow(QFrame.Raised)
+        self.verticalLayout_14 = QVBoxLayout(self.topMenus)
+        self.verticalLayout_14.setSpacing(0)
+        self.verticalLayout_14.setObjectName(u"verticalLayout_14")
+        self.verticalLayout_14.setContentsMargins(0, 0, 0, 0)
+        self.btn_print = QPushButton(self.topMenus)
+        self.btn_print.setObjectName(u"btn_print")
+        sizePolicy.setHeightForWidth(self.btn_print.sizePolicy().hasHeightForWidth())
+        self.btn_print.setSizePolicy(sizePolicy)
+        self.btn_print.setMinimumSize(QSize(0, 45))
+        self.btn_print.setFont(font2)
+        self.btn_print.setCursor(QCursor(Qt.PointingHandCursor))
+        self.btn_print.setLayoutDirection(Qt.LeftToRight)
+        self.btn_print.setStyleSheet(u"background-image: url(:/icons/images/icons/cil-print.png);")
+
+        self.verticalLayout_14.addWidget(self.btn_print)
+
+
+        self.verticalLayout_13.addWidget(self.topMenus, 0, Qt.AlignTop)
+
+
+        self.verticalLayout_7.addWidget(self.contentSettings)
+
+
+        self.horizontalLayout_4.addWidget(self.extraRightBox)
+
+
+        self.verticalLayout_6.addWidget(self.content)
+
+        self.bottomBar = QFrame(self.contentBottom)
+        self.bottomBar.setObjectName(u"bottomBar")
+        self.bottomBar.setMinimumSize(QSize(0, 22))
+        self.bottomBar.setMaximumSize(QSize(16777215, 22))
+        self.bottomBar.setFrameShape(QFrame.NoFrame)
+        self.bottomBar.setFrameShadow(QFrame.Raised)
+        self.horizontalLayout_5 = QHBoxLayout(self.bottomBar)
+        self.horizontalLayout_5.setSpacing(0)
+        self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
+        self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
+        self.creditsLabel = QLabel(self.bottomBar)
+        self.creditsLabel.setObjectName(u"creditsLabel")
+        self.creditsLabel.setMaximumSize(QSize(16777215, 16))
+        font5 = QFont()
+        font5.setFamilies([u"Segoe UI"])
+        font5.setBold(False)
+        font5.setItalic(False)
+        self.creditsLabel.setFont(font5)
+        self.creditsLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignVCenter)
+
+        self.horizontalLayout_5.addWidget(self.creditsLabel)
+
+        self.version = QLabel(self.bottomBar)
+        self.version.setObjectName(u"version")
+        self.version.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
+
+        self.horizontalLayout_5.addWidget(self.version)
+
+        self.frame_size_grip = QFrame(self.bottomBar)
+        self.frame_size_grip.setObjectName(u"frame_size_grip")
+        self.frame_size_grip.setMinimumSize(QSize(20, 0))
+        self.frame_size_grip.setMaximumSize(QSize(20, 16777215))
+        self.frame_size_grip.setFrameShape(QFrame.NoFrame)
+        self.frame_size_grip.setFrameShadow(QFrame.Raised)
+
+        self.horizontalLayout_5.addWidget(self.frame_size_grip)
+
+
+        self.verticalLayout_6.addWidget(self.bottomBar)
+
+
+        self.verticalLayout_2.addWidget(self.contentBottom)
+
+
+        self.appLayout.addWidget(self.contentBox)
+
+
+        self.appMargins.addWidget(self.bgApp)
+
+        MainWindow.setCentralWidget(self.styleSheet)
+
+        self.retranslateUi(MainWindow)
+
+        self.stackedWidget.setCurrentIndex(4)
+
+
+        QMetaObject.connectSlotsByName(MainWindow)
+    # setupUi
+
+    def retranslateUi(self, MainWindow):
+        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+        self.titleLeftApp.setText(QCoreApplication.translate("MainWindow", u"PyDracula", None))
+        self.titleLeftDescription.setText(QCoreApplication.translate("MainWindow", u"Modern GUI / Flat Style", None))
+        self.toggleButton.setText(QCoreApplication.translate("MainWindow", u"Hide", None))
+        self.btn_start_measuring_routine.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
+        self.btn_home.setText(QCoreApplication.translate("MainWindow", u"Home", None))
+        self.btn_adc_control.setText(QCoreApplication.translate("MainWindow", u"ADC Control", None))
+        self.btn_laser_control.setText(QCoreApplication.translate("MainWindow", u"Laser Control", None))
+        self.btn_probe_control.setText(QCoreApplication.translate("MainWindow", u"Probe Control", None))
+        self.btn_measured_data.setText(QCoreApplication.translate("MainWindow", u"Measured Data", None))
+        self.btn_exit.setText(QCoreApplication.translate("MainWindow", u"Exit", None))
+        self.toggleLeftBox.setText(QCoreApplication.translate("MainWindow", u"Left Box", None))
+        self.extraLabel.setText(QCoreApplication.translate("MainWindow", u"Left Box", None))
+#if QT_CONFIG(tooltip)
+        self.extraCloseColumnBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Close left box", None))
+#endif // QT_CONFIG(tooltip)
+        self.extraCloseColumnBtn.setText("")
+        self.btn_share.setText(QCoreApplication.translate("MainWindow", u"Share", None))
+        self.btn_adjustments.setText(QCoreApplication.translate("MainWindow", u"Adjustments", None))
+        self.btn_more.setText(QCoreApplication.translate("MainWindow", u"More", None))
+        self.textEdit.setHtml(QCoreApplication.translate("MainWindow", u"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
+"<html><head><meta name=\"qrichtext\" content=\"1\" /><meta charset=\"utf-8\" /><style type=\"text/css\">\n"
+"p, li { white-space: pre-wrap; }\n"
+"</style></head><body style=\" font-family:'Segoe UI'; font-size:10pt; font-weight:400; font-style:normal;\">\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600; color:#ff79c6;\">PyDracula</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" color:#ffffff;\">An interface created using Python and PySide (support for PyQt), and with colors based on the Dracula theme created by Zeno Rocha.</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-inde"
+                        "nt:0; text-indent:0px;\"><span style=\" color:#ffffff;\">MIT License</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" color:#bd93f9;\">Created by: Wanderson M. Pimenta</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600; color:#ff79c6;\">Convert UI</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:9pt; color:#ffffff;\">pyside6-uic main.ui &gt; ui_main.py</span></p>\n"
+"<p align=\"center\" style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:12pt; font-weight:600; color:#ff79c6;\">Convert QRC</span></p>\n"
+"<p align=\"center\" "
+                        "style=\" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-size:9pt; color:#ffffff;\">pyside6-rcc resources.qrc -o resources_rc.py</span></p></body></html>", None))
+        self.menu_file.setText(QCoreApplication.translate("MainWindow", u"File", None))
+        self.menu_edit.setText(QCoreApplication.translate("MainWindow", u"Edit", None))
+        self.menu_run.setText(QCoreApplication.translate("MainWindow", u"Run", None))
+        self.titleRight.setText(QCoreApplication.translate("MainWindow", u"FlexSensor 6", None))
+#if QT_CONFIG(tooltip)
+        self.settingsTopBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Settings", None))
+#endif // QT_CONFIG(tooltip)
+        self.settingsTopBtn.setText("")
+#if QT_CONFIG(tooltip)
+        self.minimizeAppBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Minimize", None))
+#endif // QT_CONFIG(tooltip)
+        self.minimizeAppBtn.setText("")
+#if QT_CONFIG(tooltip)
+        self.maximizeRestoreAppBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Maximize", None))
+#endif // QT_CONFIG(tooltip)
+        self.maximizeRestoreAppBtn.setText("")
+#if QT_CONFIG(tooltip)
+        self.closeAppBtn.setToolTip(QCoreApplication.translate("MainWindow", u"Close", None))
+#endif // QT_CONFIG(tooltip)
+        self.closeAppBtn.setText("")
+        self.btn_print.setText(QCoreApplication.translate("MainWindow", u"Print", None))
+        self.creditsLabel.setText(QCoreApplication.translate("MainWindow", u"Flexsensor 6", None))
+        self.version.setText(QCoreApplication.translate("MainWindow", u"v1.0.3", None))
+    # retranslateUi
+
diff --git a/src/FlexSensor/MainWindow/view/StepThroughView.py b/src/FlexSensor/MainWindow/view/StepThroughView.py
new file mode 100644
index 0000000000000000000000000000000000000000..37e506f32435d5834af85a0cd03abbbdfa61b4c4
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/StepThroughView.py
@@ -0,0 +1,126 @@
+import traceback
+from PySide6.QtWidgets import (
+        QMainWindow, QWidget, QGridLayout, QPushButton, QLineEdit,
+)
+from PySide6.QtGui import QIcon
+
+import Prober as Prober
+
+import ConfigHandler.controller.VASInputFileParser as input_file_parser
+from Prober.controller.ProberController import ProberController
+from constants.FlexsensorConstants import Probe
+
+
+class StepThroughView(QMainWindow):
+    def __init__(self, grouped_structures, prober: ProberController):
+        super(StepThroughView, self).__init__()
+        self.prober = prober
+        self.grouped_structures = grouped_structures
+        self.idx_struct = 0
+        self.idx_group = 0
+        self.init_UI()
+        self.move_to_structure()
+        self.msg_server = None
+       
+
+    def init_UI(self):
+        # create a layout
+        layout = QGridLayout()
+        widget = QWidget()
+        # add a label
+        self.group_name = QLineEdit("This is a label")
+        self.structure_name = QLineEdit("This is a label")
+        # add a button
+        self.btn_prev = QPushButton("Previous")
+        self.btn_prev.clicked.connect(self.on_click_prev)
+
+         # add a button
+        self.btn_next = QPushButton("Next")
+        self.btn_next.clicked.connect(self.on_click_next)
+
+        self.btn_search_for_light = QPushButton("Search for light")
+        self.btn_search_for_light.clicked.connect(self.on_search_for_light)
+
+        # Add the widgets to the layout
+        layout.addWidget(self.group_name, 0, 0, 1, 2)
+        layout.addWidget(self.structure_name, 1, 0, 1, 2)
+        layout.addWidget(self.btn_prev, 2, 0)
+        layout.addWidget(self.btn_next, 2, 1)
+        
+
+        widget.setLayout(layout)
+        self.setCentralWidget(widget)
+        #self.layout.setLayout(tree)
+
+        self.setWindowTitle(f'Step Structure')   
+        self.setWindowIcon(QIcon('icon.ico')) 
+
+    def move_to_structure(self):
+      
+        self.group: str = list(self.grouped_structures)[self.idx_group]
+        self.structures: dict = self.grouped_structures[self.group]
+        self.structure: input_file_parser.Structure = list(self.structures.values())[self.idx_struct]
+        try:
+            #with Prober.velox_api.MessageServerInterface() as self.msg_server:
+                #velox_api.MoveChuck(0, 0)
+                #print(f"New structure group ({self.idx_groups}): {self.groups}. {len(structures)} structures in group.")
+
+
+                # Move to die
+                #print(f"Move chuck (first probe) to X({self.structure.x_in}), Y({self.structure.y_in}).")
+                self.prober.move_chuck(self.structure.x_in, self.structure.y_in)
+
+                try:
+                    if self.structure.in_out_diff_x > 50:
+                        #print(
+                        #    f"Move second probe to X({self.structure.x_out}), Y({self.structure.y_out}) "
+                        #    f"- Difference x({self.structure.in_out_diff_x}) y({self.structure.in_out_diff_y})"
+                        #)
+                        self.prober.opt_if.move_optical_probe(Probe.OUTPUT, self.structure.in_out_diff_x, self.structure.in_out_diff_y, pos_ref="H")
+                        #self.msg_server.sendSciCommand("MoveOpticalProbe",rparams='1 %s %s H' %
+                        #    (self.structure.in_out_diff_x, self.structure.in_out_diff_y)
+                        #)
+                    else:
+                        raise Exception("Optical Probe Home not safe! x difference < 50 um: {self.structure.in_out_diff_x}")
+                except Exception as e:
+                    print("error", f"Can't move optical probe safely. {e}")
+                    print((
+                        type(e), f"Can't move optical probe safely. {e}. Omitting Structure!", traceback.format_exc()
+                    ))
+                    print("warning", f"[!] Omitting structure {self.structure.name}")
+        except Exception as e:
+            print("error", f"Can't move optical probe safely. {e}")
+            print((
+                   type(e), f"Can't move optical probe safely. {e}. Omitting Structure!", traceback.format_exc()
+                ))  
+
+        self.group_name.setText(f"Group: {self.group}")
+        self.structure_name.setText(f"Structure: {self.structure.name}")
+
+    def on_search_for_light(self):
+        self.prober.opt_if.store_optical_probe_pos()
+        #self.prober.opt_if.restore_optical_probe_motor_pos(probe=Probe.INPUT)
+        #self.prober.opt_if.restore_optical_probe_motor_pos(probe=Probe.OUTPUT)
+
+    
+    def on_click_prev(self):
+        self.idx_struct = self.idx_struct - 1
+        if self.idx_struct < 0:
+            self.idx_group =  self.idx_group - 1
+            if self.idx_group < 0:
+                self.idx_group = len(self.grouped_structures) - 1
+            
+            group: str = list(self.grouped_structures)[self.idx_group]
+            self.idx_struct = len(self.grouped_structures[group]) - 1
+        self.move_to_structure()
+
+    def on_click_next(self):
+        self.idx_struct = self.idx_struct + 1
+        if self.idx_struct >= len(self.structures):
+            self.idx_group =  self.idx_group + 1
+            if self.idx_group >= len(self.grouped_structures):
+                self.idx_group = 0
+            self.idx_struct = 0
+        self.move_to_structure()
+        
+        
\ No newline at end of file
diff --git a/src/FlexSensor/MainWindow/view/__init__.py b/src/FlexSensor/MainWindow/view/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/view/widgets/HomeStatusWidget.py b/src/FlexSensor/MainWindow/view/widgets/HomeStatusWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..cf4b98992cb76d348fc55ba5e0805b32ec10628d
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/HomeStatusWidget.py
@@ -0,0 +1,93 @@
+import sys
+
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QGroupBox, QGridLayout, QLineEdit, QLabel, QProgressBar
+
+import __version__
+from MainWindow.view import MainView
+from Prober.view.widgets.ProberPositionWidget import ProberPositionWidget
+
+
+class HomeStatusWidget(QWidget):
+
+    def __init__(self, view: MainView):
+        super().__init__()
+
+        self.velox_kernel_version = None
+        self.python_version = None
+        self.script_version = None
+
+        self.view: MainView = view
+        layout = QGridLayout()
+        layout.addWidget(self.init_UI_wafer_info(), 0, 0, 1, 1)
+        layout.addWidget(self.init_UI_status_wdg(), 0, 1, 1, 1)
+        layout.addWidget(self.init_UI_version_info(), 1, 0, 1, 2)
+
+        self.setLayout(layout)
+
+    def init_UI_wafer_info(self):
+
+        grid_group_box = QGroupBox()
+        layout = QGridLayout()
+
+        self.tb_wafer_version = QLineEdit(parent=self, text=str(self.view.model.vaut_config.wafer_version))
+        #self.tb_wafer_version.textChanged.connect(self.on_wafer_version_changed)
+        layout.addWidget(QLabel("Wafer Version"), 0, 0, 1, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_wafer_version, 1, 0, 1, 2)  # row, column, rowspan, colspan
+
+        self.tb_wafer_nr = QLineEdit(parent=self, text=str(self.view.model.vaut_config.wafer_nr))
+        #self.tb_wafer_nr.textChanged.connect(self.on_wafer_nr_changed)
+        layout.addWidget(QLabel("Wafer number"), 0, 2, 1, 1)
+        layout.addWidget(self.tb_wafer_nr, 1, 2, 1, 2)
+
+        grid_group_box.setLayout(layout)
+
+        return grid_group_box
+
+    def init_UI_status_wdg(self):
+        grid_group_box = QGroupBox()
+        layout = QVBoxLayout()
+        layout.addWidget(ProberPositionWidget(self.view.model.prober_model, "Horizontal"))
+
+        self.progress = QProgressBar(self)
+        self.progress.setStyleSheet(
+            "#GreenProgressBar { min-height: 12px; max-height: 12px; border-radius: 6px;}")
+        layout.addWidget(self.progress)
+        self.progress.setFixedHeight(self.progress.sizeHint().height() / 2)
+
+        grid_group_box.setLayout(layout)
+
+        return grid_group_box
+
+    def init_UI_version_info(self):
+
+        grid_group_box = QGroupBox()
+        layout = QGridLayout()
+        try:
+            self.velox_kernel_version = QLineEdit(parent=self,
+                                                  text=self.view.model.prober_model.report_velox_kernel_version())
+
+        except Exception as e:
+            print(e)
+            self.velox_kernel_version = QLineEdit(
+                parent=self, text="Velox kernel version not available")
+
+        self.velox_kernel_version.setReadOnly(True)
+        # self.velox_kernel_version.setEnabled(False)
+        layout.addWidget(QLabel("Velox Kernel Version"), 2, 0)
+        layout.addWidget(self.velox_kernel_version, 3, 0)
+
+        self.python_version = QLineEdit(parent=self, text=str(sys.version))
+        self.python_version.setReadOnly(True)
+        # self.python_version.setEnabled(False)
+        layout.addWidget(QLabel("Python Version"), 2, 1)
+        layout.addWidget(self.python_version, 3, 1)
+
+        self.script_version = QLineEdit(parent=self, text=__version__.__version__)
+        self.script_version.setReadOnly(True)
+        self.script_version.setEnabled(False)
+        layout.addWidget(QLabel("Script Version"), 2, 2)
+        layout.addWidget(self.script_version, 3, 2)
+
+        grid_group_box.setLayout(layout)
+
+        return grid_group_box
diff --git a/src/FlexSensor/MainWindow/view/widgets/ScopeWidget.py b/src/FlexSensor/MainWindow/view/widgets/ScopeWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..8301a8aa6287a6a254a7a525a3e76c1887130059
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/ScopeWidget.py
@@ -0,0 +1,32 @@
+import pyqtgraph as pg
+from PySide6.QtWidgets import QVBoxLayout, QWidget
+from pyqtgraph.dockarea import DockArea, Dock
+
+from MainWindow.view import MainView
+
+
+class ScopeWidget(QWidget):
+
+    def __init__(self, parent_view: MainView):
+        super().__init__()
+        self.parent_view = parent_view
+        layout = QVBoxLayout()
+        area = DockArea()
+
+        d1 = Dock("Analog Discovery 2")
+        d2 = Dock("Filtered")
+        area.addDock(d1, 'bottom')
+        area.addDock(d2, 'bottom', d1)
+
+        self.scope_original = pg.PlotWidget(title="AD2 Acquisition")
+        # self.scope_original.plot(np.random.normal(size=100)*1e12)
+        self.scope_original.plotItem.showGrid(x=True, y=True, alpha=1)
+        d1.addWidget(self.scope_original)
+
+        self.scope_filtered = pg.PlotWidget(title="Filtered Data")
+        # self.scope_filtered.plot(np.random.normal(size=100))
+        self.scope_filtered.plotItem.showGrid(x=True, y=True, alpha=1)
+        d2.addWidget(self.scope_filtered)
+        layout.addWidget(area)
+        self.setMinimumWidth(800)
+        self.setLayout(layout)
diff --git a/src/FlexSensor/MainWindow/view/widgets/WidgetSettingsFilesFolders.py b/src/FlexSensor/MainWindow/view/widgets/WidgetSettingsFilesFolders.py
new file mode 100644
index 0000000000000000000000000000000000000000..240ac93a1dc076903db0255eb560d5d92d0445f9
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/WidgetSettingsFilesFolders.py
@@ -0,0 +1,323 @@
+from PySide6.QtWidgets import QWidget, QGridLayout, QGroupBox, QLineEdit, QPushButton, QLabel, QDoubleSpinBox
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.view.ConfigView import ConfigView
+
+
+class WidgetSettingsInFilesFolders(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+
+        self.btn_select_list_of_structures = QPushButton(parent=self, text="...")
+        self.btn_select_working_directory = QPushButton(parent=self, text="...")
+
+        self.layout = QGridLayout()
+        self.init_UI()
+
+    def init_UI(self):
+        grid_group_box = QGroupBox("Input Files")
+        layout = QGridLayout()
+        # Working directory
+        self.tb_working_directory = QLineEdit(parent=self, text=str(self.vaut_config.get_output_directory().relative))
+        self.btn_select_working_directory.setMaximumWidth(self.btn_select_working_directory.sizeHint().height())
+        layout.addWidget(QLabel("Working directory"), 0, 0)
+        layout.addWidget(self.tb_working_directory, 0, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.btn_select_working_directory, 0, 3)  # row, column, rowspan, colspan
+
+        # List of structures
+        self.tb_list_of_structures = QLineEdit(parent=self, text=str(self.vaut_config.wafer_config.get_structure_file().relative))
+        self.btn_select_list_of_structures.setMaximumWidth(self.btn_select_list_of_structures.sizeHint().height())
+        layout.addWidget(QLabel("Input Structure File"), 1, 0)
+        layout.addWidget(self.tb_list_of_structures, 1, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.btn_select_list_of_structures, 1, 3)  # row, column, rowspan, colspan
+
+        grid_group_box.setLayout(layout)
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
+
+class WidgetSettingsOutFilesFolders(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+
+        self.tb_log_file = QLineEdit(
+            text="self.vaut_config.wafer_config.get_log_file().filename")
+        self.tb_measurement_output = QLineEdit(
+            text="self.vaut_config.wafer_config.get_measurement_output().filename")
+        self.tb_mat_files_output = QLineEdit(
+            text="self.vaut_config.wafer_config.get_measurement_mat_file().filename")
+        self.tb_bookmark_file = QLineEdit(
+            text="self.vaut_config.wafer_config.get_bookmark_file()._mat_filename")
+        self.tb_scope_image_file = QLineEdit(
+            text="self.vaut_config.wafer_config.get_scope_image_file()._mat_filename")
+
+
+
+        self.layout = QGridLayout()
+        self.init_UI()
+
+    def init_UI(self):
+        layout = QGridLayout()
+        grid_group_box = QGroupBox("Output Files")
+        grid_group_box.setLayout(layout)
+
+
+
+
+
+
+        self.lbl_log_file = QLabel(parent=self)
+        self.tb_log_file.textChanged.connect(self.on_tb_log_file_text_changed)
+        self.on_tb_log_file_text_changed(self.tb_log_file.text())
+        layout.addWidget(QLabel("Log File"), 0, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_log_file, 0, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_log_file, 1, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # measurement output
+        self.lbl_measurement_output = QLabel(parent=self)
+        self.tb_measurement_output.textChanged.connect(self.on_tb_measurement_output_text_changed)
+        self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+        layout.addWidget(QLabel("Measurement output"), 2, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_measurement_output, 2, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_measurement_output, 3, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # Mat files output
+        self.lbl_mat_files_output = QLabel(parent=self)
+        self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+
+        self.tb_mat_files_output.textChanged.connect(self.on_tb_mat_files_output_text_changed)
+        layout.addWidget(QLabel("Matlab Files"), 4, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_mat_files_output, 4, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_mat_files_output, 5, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # bookmark files
+        self.lbl_bookmark_file = QLabel(parent=self)
+        self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+        self.tb_bookmark_file.textChanged.connect(self.on_tb_bookmark_file_text_changed)
+        self.tb_scope_image_file.textChanged.connect(self.on_tb_scope_image_file_text_changed)
+        layout.addWidget(QLabel("Bookmark files"), 6, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_bookmark_file, 6, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_bookmark_file, 7, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # scope shots
+        self.lbl_scope_image_file = QLabel(parent=self)
+        self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+        layout.addWidget(QLabel("Scope Shots"), 8, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_scope_image_file, 8, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_scope_image_file, 9, 0, 1, 2)
+
+
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
+    def on_tb_scope_image_file_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_scope_image_file().set_obj(value)
+        val = self.vaut_config.wafer_config.get_scope_image_file().relative.replace(self.vaut_config.get_output_directory().relative,
+                                                                         "<b>wd</b>")
+        self.lbl_scope_image_file.setText(val)
+        # set label hover text
+        self.lbl_scope_image_file.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+    def on_tb_measurement_output_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_measurement_output().set_obj(value)
+        val = self.vaut_config.wafer_config.get_measurement_output().relative.replace(self.vaut_config.get_output_directory().relative,
+                                                                           "<b>wd</b>")
+        self.lbl_measurement_output.setText(val)
+        # set label hover text
+        self.lbl_measurement_output.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+    def on_tb_bookmark_file_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_bookmark_file().set_obj(value)
+        val = self.vaut_config.wafer_config.get_bookmark_file().relative.replace(self.vaut_config.get_output_directory().relative,
+                                                                      "<b>wd</b>")
+        self.lbl_bookmark_file.setText(val)
+        # set label hover text
+        self.lbl_bookmark_file.setToolTip(self.vaut_config.wafer_config.get_bookmark_file().absolute)
+
+        config = self.vaut_config
+
+    def on_tb_mat_files_output_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_measurement_mat_file().set_obj(value)
+        val = self.vaut_config.wafer_config.get_measurement_mat_file().relative.replace(
+            self.vaut_config.get_output_directory().relative,
+                                                                             "<b>wd</b>")
+        self.lbl_mat_files_output.setText(val)
+        self.lbl_mat_files_output.setToolTip(self.vaut_config.wafer_config.get_measurement_mat_file().absolute)
+
+    def on_tb_log_file_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_log_file().set_obj(value)
+
+        val = self.vaut_config.wafer_config.get_log_file().relative.replace(self.vaut_config.get_output_directory().relative, "<b>wd</b>")
+        self.lbl_log_file.setText(val)
+        self.lbl_log_file.setToolTip(self.vaut_config.wafer_config.get_log_file().absolute)
+
+class WidgetAD2Settings(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+        self.c = ConfigView(vaut_config)
+
+
+        self.num_sample_rate = QDoubleSpinBox()
+        self.num_total_samples = QDoubleSpinBox()
+        self.num_sample_time = QDoubleSpinBox()
+
+        self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+        self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+        self.layout = QGridLayout()
+        self.init_UI()
+
+
+    def show_config(self):
+        self.c = ConfigView(self.vaut_config)
+        self.c.show()
+
+    def init_UI(self):
+        layout = QGridLayout()
+        grid_group_box = QGroupBox("Analog Discovery 2 Settings")
+        grid_group_box.setLayout(layout)
+
+        lbl_sample_rate = QLabel("Sample Rate")
+        layout.addWidget(lbl_sample_rate, 1, 0)
+        self.num_sample_rate.valueChanged.connect(lambda v: self.vaut_config.ad2_device_config.set_sample_rate(v))
+        self.num_sample_rate.setRange(0, 10**8)
+        self.num_sample_rate.setSingleStep(1)
+        self.num_sample_rate.setValue(self.vaut_config.ad2_device_config.get_sample_rate())
+        self.num_sample_rate.setSuffix(" Hz")
+        self.num_sample_rate.setDecimals(3)
+        self.num_sample_rate.setKeyboardTracking(False)
+        layout.addWidget(self.num_sample_rate, 1, 1, 1, 2)
+
+        lbl_total_samples = QLabel("Total Samples")
+        layout.addWidget(lbl_total_samples, 2, 0)
+        self.num_total_samples.setRange(0, 10**8)
+        self.num_total_samples.setSingleStep(1)
+        self.num_total_samples.setValue(self.vaut_config.ad2_device_config.get_total_samples())
+        self.num_total_samples.setDecimals(3)
+        self.num_total_samples.setKeyboardTracking(False)
+        layout.addWidget(self.num_total_samples, 2, 1, 1, 2)
+
+        lbl_sample_time = QLabel("Sample Time")
+        layout.addWidget(lbl_sample_time, 3, 0)
+        self.num_sample_time.setRange(0, 10**8)
+        self.num_sample_time.setSingleStep(1)
+        self.num_sample_time.setValue(self.vaut_config.ad2_device_config.get_sample_time())
+        self.num_sample_time.setSuffix(" s")
+        self.num_sample_time.setDecimals(3)
+        self.num_sample_time.setKeyboardTracking(False)
+        layout.addWidget(self.num_sample_time, 3, 1, 1, 2)
+
+        lbl_ad2_raw_out_file = QLabel("Raw Out File")
+        layout.addWidget(lbl_ad2_raw_out_file, 4, 0)
+        tb_ad2_raw_out_file = QLineEdit(text=self.vaut_config.ad2_device_config.get_ad2_raw_out_file().relative)
+        layout.addWidget(tb_ad2_raw_out_file, 4, 1)
+        layout.addWidget(self.btn_select_ad2_raw_out_file, 4, 2)
+
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
+class WidgetLaserSettings(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+        self.c = None
+
+
+        self.num_wavelength_sweep_start = QDoubleSpinBox()
+        self.num_wavelength_range_stop = QDoubleSpinBox()
+        self.num_velocity = QDoubleSpinBox()
+        self.num_acceleration = QDoubleSpinBox()
+        self.num_deceleration = QDoubleSpinBox()
+
+
+        #self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+        #self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+        self.layout = QGridLayout()
+        self.init_UI()
+
+
+    def show_config(self):
+        self.c = ConfigView(self.vaut_config)
+        self.c.show()
+
+    def init_UI(self):
+        layout = QGridLayout()
+        grid_group_box = QGroupBox("Laser Settings")
+        grid_group_box.setLayout(layout)
+
+        lbl_wavelength_sweep_start = QLabel("Wavelength Sweep")
+        layout.addWidget(lbl_wavelength_sweep_start, 1, 0)
+
+
+
+        self.num_wavelength_sweep_start.setRange(0, 10 ** 8)
+        self.num_wavelength_sweep_start.setSingleStep(1)
+        self.num_wavelength_sweep_start.setValue(self.vaut_config.laser_config.get_wavelength_range()[0])
+        self.num_wavelength_sweep_start.setSuffix(" nm")
+        self.num_wavelength_sweep_start.setDecimals(3)
+        self.num_wavelength_sweep_start.setKeyboardTracking(False)
+        layout.addWidget(self.num_wavelength_sweep_start, 1, 1)
+        self.num_wavelength_sweep_start.valueChanged.connect(
+            lambda v: self.vaut_config.laser_config.set_wavelength_range(
+                [float(v), float(self.num_wavelength_range_stop.value())])
+        )
+
+        self.num_wavelength_range_stop.setRange(0, 10 ** 8)
+        self.num_wavelength_range_stop.setSingleStep(1)
+        self.num_wavelength_range_stop.setValue(self.vaut_config.laser_config.get_wavelength_range()[1])
+        self.num_wavelength_range_stop.setSuffix(" nm")
+        self.num_wavelength_range_stop.setDecimals(3)
+        self.num_wavelength_range_stop.setKeyboardTracking(False)
+        layout.addWidget(self.num_wavelength_range_stop, 1, 2)
+
+        self.num_wavelength_range_stop.valueChanged.connect(
+            lambda v: self.vaut_config.laser_config.set_wavelength_range(
+                [float(self.num_wavelength_sweep_start.value()), float(v)]
+        ))
+
+        lbl_velocity = QLabel("Velocity")
+        layout.addWidget(lbl_velocity, 2, 0)
+        self.num_velocity.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_velocity(v))
+        self.num_velocity.setRange(0, 10**8)
+        self.num_velocity.setSingleStep(1)
+        self.num_velocity.setValue(self.vaut_config.laser_config.get_velocity())
+        self.num_acceleration.setSuffix(" m/s")
+        self.num_velocity.setDecimals(3)
+        self.num_velocity.setKeyboardTracking(False)
+        layout.addWidget(self.num_velocity, 2, 1, 1, 2)
+
+        lbl_acceleration = QLabel("Acceleration")
+        layout.addWidget(lbl_acceleration, 3, 0)
+        self.num_acceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_acceleration(v))
+        self.num_acceleration.setRange(0, 10**8)
+        self.num_acceleration.setSingleStep(1)
+        self.num_acceleration.setValue(self.vaut_config.laser_config.get_acceleration())
+        self.num_acceleration.setSuffix(" m/s^2")
+        self.num_acceleration.setDecimals(3)
+        self.num_acceleration.setKeyboardTracking(False)
+        layout.addWidget(self.num_acceleration, 3, 1, 1, 2)
+
+        lbl_deceleration = QLabel("Deceleration")
+        layout.addWidget(lbl_deceleration, 4, 0)
+        self.num_deceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_deceleration(v))
+        self.num_deceleration.setRange(0, 10 ** 8)
+        self.num_deceleration.setSingleStep(1)
+        self.num_deceleration.setValue(self.vaut_config.laser_config.get_deceleration())
+        self.num_deceleration.setSuffix(" m/s^2")
+        self.num_deceleration.setDecimals(3)
+        self.num_deceleration.setKeyboardTracking(False)
+        layout.addWidget(self.num_deceleration, 4, 1, 1, 2)
+
+
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
diff --git a/src/FlexSensor/MainWindow/view/widgets/__init__.py b/src/FlexSensor/MainWindow/view/widgets/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/view/widgets/custom_grips/__init__.py b/src/FlexSensor/MainWindow/view/widgets/custom_grips/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..edc45ae18fc40102f8a27651f77dac72d5026488
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/custom_grips/__init__.py
@@ -0,0 +1,17 @@
+# ///////////////////////////////////////////////////////////////
+#
+# BY: WANDERSON M.PIMENTA
+# PROJECT MADE WITH: Qt Designer and PySide6
+# V: 1.0.0
+#
+# This project can be used freely for all uses, as long as they maintain the
+# respective credits only in the Python scripts, any information in the visual
+# interface (GUI) can be modified without any implication.
+#
+# There are limitations on Qt licenses if you want to use your products
+# commercially, I recommend reading them on the official website:
+# https://doc.qt.io/qtforpython/licenses.html
+#
+# ///////////////////////////////////////////////////////////////
+
+from . custom_grips import CustomGrip
diff --git a/src/FlexSensor/MainWindow/view/widgets/custom_grips/custom_grips.py b/src/FlexSensor/MainWindow/view/widgets/custom_grips/custom_grips.py
new file mode 100644
index 0000000000000000000000000000000000000000..53a15a1d68cb56d2f1fe1821a1ce9dd261b6f340
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/custom_grips/custom_grips.py
@@ -0,0 +1,238 @@
+# ///////////////////////////////////////////////////////////////
+#
+# BY: WANDERSON M.PIMENTA
+# PROJECT MADE WITH: Qt Designer and PySide6
+# V: 1.0.0
+#
+# This project can be used freely for all uses, as long as they maintain the
+# respective credits only in the Python scripts, any information in the visual
+# interface (GUI) can be modified without any implication.
+#
+# There are limitations on Qt licenses if you want to use your products
+# commercially, I recommend reading them on the official website:
+# https://doc.qt.io/qtforpython/licenses.html
+#
+# ///////////////////////////////////////////////////////////////
+
+from PySide6.QtCore import *
+from PySide6.QtGui import *
+from PySide6.QtWidgets import *
+
+class CustomGrip(QWidget):
+    def __init__(self, parent, position, disable_color = False):
+
+        # SETUP UI
+        QWidget.__init__(self)
+        self.parent = parent
+        self.setParent(parent)
+        self.wi = Widgets()
+
+        # SHOW TOP GRIP
+        if position == Qt.TopEdge:
+            self.wi.top(self)
+            self.setGeometry(0, 0, self.parent.width(), 10)
+            self.setMaximumHeight(10)
+
+            # GRIPS
+            top_left = QSizeGrip(self.wi.top_left)
+            top_right = QSizeGrip(self.wi.top_right)
+
+            # RESIZE TOP
+            def resize_top(event):
+                delta = event.pos()
+                height = max(self.parent.minimumHeight(), self.parent.height() - delta.y())
+                geo = self.parent.geometry()
+                geo.setTop(geo.bottom() - height)
+                self.parent.setGeometry(geo)
+                event.accept()
+            self.wi.top.mouseMoveEvent = resize_top
+
+            # ENABLE COLOR
+            if disable_color:
+                self.wi.top_left.setStyleSheet("background: transparent")
+                self.wi.top_right.setStyleSheet("background: transparent")
+                self.wi.top.setStyleSheet("background: transparent")
+
+        # SHOW BOTTOM GRIP
+        elif position == Qt.BottomEdge:
+            self.wi.bottom(self)
+            self.setGeometry(0, self.parent.height() - 10, self.parent.width(), 10)
+            self.setMaximumHeight(10)
+
+            # GRIPS
+            self.bottom_left = QSizeGrip(self.wi.bottom_left)
+            self.bottom_right = QSizeGrip(self.wi.bottom_right)
+
+            # RESIZE BOTTOM
+            def resize_bottom(event):
+                delta = event.pos()
+                height = max(self.parent.minimumHeight(), self.parent.height() + delta.y())
+                self.parent.resize(self.parent.width(), height)
+                event.accept()
+            self.wi.bottom.mouseMoveEvent = resize_bottom
+
+            # ENABLE COLOR
+            if disable_color:
+                self.wi.bottom_left.setStyleSheet("background: transparent")
+                self.wi.bottom_right.setStyleSheet("background: transparent")
+                self.wi.bottom.setStyleSheet("background: transparent")
+
+        # SHOW LEFT GRIP
+        elif position == Qt.LeftEdge:
+            self.wi.left(self)
+            self.setGeometry(0, 10, 10, self.parent.height())
+            self.setMaximumWidth(10)
+
+            # RESIZE LEFT
+            def resize_left(event):
+                delta = event.pos()
+                width = max(self.parent.minimumWidth(), self.parent.width() - delta.x())
+                geo = self.parent.geometry()
+                geo.setLeft(geo.right() - width)
+                self.parent.setGeometry(geo)
+                event.accept()
+            self.wi.leftgrip.mouseMoveEvent = resize_left
+
+            # ENABLE COLOR
+            if disable_color:
+                self.wi.leftgrip.setStyleSheet("background: transparent")
+
+        # RESIZE RIGHT
+        elif position == Qt.RightEdge:
+            self.wi.right(self)
+            self.setGeometry(self.parent.width() - 10, 10, 10, self.parent.height())
+            self.setMaximumWidth(10)
+
+            def resize_right(event):
+                delta = event.pos()
+                width = max(self.parent.minimumWidth(), self.parent.width() + delta.x())
+                self.parent.resize(width, self.parent.height())
+                event.accept()
+            self.wi.rightgrip.mouseMoveEvent = resize_right
+
+            # ENABLE COLOR
+            if disable_color:
+                self.wi.rightgrip.setStyleSheet("background: transparent")
+
+
+    def mouseReleaseEvent(self, event):
+        self.mousePos = None
+
+    def resizeEvent(self, event):
+        if hasattr(self.wi, 'container_top'):
+            self.wi.container_top.setGeometry(0, 0, self.width(), 10)
+
+        elif hasattr(self.wi, 'container_bottom'):
+            self.wi.container_bottom.setGeometry(0, 0, self.width(), 10)
+
+        elif hasattr(self.wi, 'leftgrip'):
+            self.wi.leftgrip.setGeometry(0, 0, 10, self.height() - 20)
+
+        elif hasattr(self.wi, 'rightgrip'):
+            self.wi.rightgrip.setGeometry(0, 0, 10, self.height() - 20)
+
+class Widgets(object):
+    def top(self, Form):
+        if not Form.objectName():
+            Form.setObjectName(u"Form")
+        self.container_top = QFrame(Form)
+        self.container_top.setObjectName(u"container_top")
+        self.container_top.setGeometry(QRect(0, 0, 500, 10))
+        self.container_top.setMinimumSize(QSize(0, 10))
+        self.container_top.setMaximumSize(QSize(16777215, 10))
+        self.container_top.setFrameShape(QFrame.NoFrame)
+        self.container_top.setFrameShadow(QFrame.Raised)
+        self.top_layout = QHBoxLayout(self.container_top)
+        self.top_layout.setSpacing(0)
+        self.top_layout.setObjectName(u"top_layout")
+        self.top_layout.setContentsMargins(0, 0, 0, 0)
+        self.top_left = QFrame(self.container_top)
+        self.top_left.setObjectName(u"top_left")
+        self.top_left.setMinimumSize(QSize(10, 10))
+        self.top_left.setMaximumSize(QSize(10, 10))
+        self.top_left.setCursor(QCursor(Qt.SizeFDiagCursor))
+        self.top_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+        self.top_left.setFrameShape(QFrame.NoFrame)
+        self.top_left.setFrameShadow(QFrame.Raised)
+        self.top_layout.addWidget(self.top_left)
+        self.top = QFrame(self.container_top)
+        self.top.setObjectName(u"top")
+        self.top.setCursor(QCursor(Qt.SizeVerCursor))
+        self.top.setStyleSheet(u"background-color: rgb(85, 255, 255);")
+        self.top.setFrameShape(QFrame.NoFrame)
+        self.top.setFrameShadow(QFrame.Raised)
+        self.top_layout.addWidget(self.top)
+        self.top_right = QFrame(self.container_top)
+        self.top_right.setObjectName(u"top_right")
+        self.top_right.setMinimumSize(QSize(10, 10))
+        self.top_right.setMaximumSize(QSize(10, 10))
+        self.top_right.setCursor(QCursor(Qt.SizeBDiagCursor))
+        self.top_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+        self.top_right.setFrameShape(QFrame.NoFrame)
+        self.top_right.setFrameShadow(QFrame.Raised)
+        self.top_layout.addWidget(self.top_right)
+
+    def bottom(self, Form):
+        if not Form.objectName():
+            Form.setObjectName(u"Form")
+        self.container_bottom = QFrame(Form)
+        self.container_bottom.setObjectName(u"container_bottom")
+        self.container_bottom.setGeometry(QRect(0, 0, 500, 10))
+        self.container_bottom.setMinimumSize(QSize(0, 10))
+        self.container_bottom.setMaximumSize(QSize(16777215, 10))
+        self.container_bottom.setFrameShape(QFrame.NoFrame)
+        self.container_bottom.setFrameShadow(QFrame.Raised)
+        self.bottom_layout = QHBoxLayout(self.container_bottom)
+        self.bottom_layout.setSpacing(0)
+        self.bottom_layout.setObjectName(u"bottom_layout")
+        self.bottom_layout.setContentsMargins(0, 0, 0, 0)
+        self.bottom_left = QFrame(self.container_bottom)
+        self.bottom_left.setObjectName(u"bottom_left")
+        self.bottom_left.setMinimumSize(QSize(10, 10))
+        self.bottom_left.setMaximumSize(QSize(10, 10))
+        self.bottom_left.setCursor(QCursor(Qt.SizeBDiagCursor))
+        self.bottom_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+        self.bottom_left.setFrameShape(QFrame.NoFrame)
+        self.bottom_left.setFrameShadow(QFrame.Raised)
+        self.bottom_layout.addWidget(self.bottom_left)
+        self.bottom = QFrame(self.container_bottom)
+        self.bottom.setObjectName(u"bottom")
+        self.bottom.setCursor(QCursor(Qt.SizeVerCursor))
+        self.bottom.setStyleSheet(u"background-color: rgb(85, 170, 0);")
+        self.bottom.setFrameShape(QFrame.NoFrame)
+        self.bottom.setFrameShadow(QFrame.Raised)
+        self.bottom_layout.addWidget(self.bottom)
+        self.bottom_right = QFrame(self.container_bottom)
+        self.bottom_right.setObjectName(u"bottom_right")
+        self.bottom_right.setMinimumSize(QSize(10, 10))
+        self.bottom_right.setMaximumSize(QSize(10, 10))
+        self.bottom_right.setCursor(QCursor(Qt.SizeFDiagCursor))
+        self.bottom_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
+        self.bottom_right.setFrameShape(QFrame.NoFrame)
+        self.bottom_right.setFrameShadow(QFrame.Raised)
+        self.bottom_layout.addWidget(self.bottom_right)
+
+    def left(self, Form):
+        if not Form.objectName():
+            Form.setObjectName(u"Form")
+        self.leftgrip = QFrame(Form)
+        self.leftgrip.setObjectName(u"left")
+        self.leftgrip.setGeometry(QRect(0, 10, 10, 480))
+        self.leftgrip.setMinimumSize(QSize(10, 0))
+        self.leftgrip.setCursor(QCursor(Qt.SizeHorCursor))
+        self.leftgrip.setStyleSheet(u"background-color: rgb(255, 121, 198);")
+        self.leftgrip.setFrameShape(QFrame.NoFrame)
+        self.leftgrip.setFrameShadow(QFrame.Raised)
+
+    def right(self, Form):
+        if not Form.objectName():
+            Form.setObjectName(u"Form")
+        Form.resize(500, 500)
+        self.rightgrip = QFrame(Form)
+        self.rightgrip.setObjectName(u"right")
+        self.rightgrip.setGeometry(QRect(0, 0, 10, 500))
+        self.rightgrip.setMinimumSize(QSize(10, 0))
+        self.rightgrip.setCursor(QCursor(Qt.SizeHorCursor))
+        self.rightgrip.setStyleSheet(u"background-color: rgb(255, 0, 127);")
+        self.rightgrip.setFrameShape(QFrame.NoFrame)
+        self.rightgrip.setFrameShadow(QFrame.Raised)
diff --git a/src/FlexSensor/MainWindow/view/widgets/menu_bar_widget.py b/src/FlexSensor/MainWindow/view/widgets/menu_bar_widget.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MainWindow/view/widgets/widget_settings_folder.py b/src/FlexSensor/MainWindow/view/widgets/widget_settings_folder.py
new file mode 100644
index 0000000000000000000000000000000000000000..dcbe0d82efa3172ce5ecda09fa96125df16b4310
--- /dev/null
+++ b/src/FlexSensor/MainWindow/view/widgets/widget_settings_folder.py
@@ -0,0 +1,317 @@
+from PySide6.QtWidgets import QWidget, QGridLayout, QGroupBox, QLineEdit, QPushButton, QLabel, QDoubleSpinBox
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.view.ConfigView import ConfigView
+
+
+class WidgetSettingsInFilesFolders(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+
+        self.btn_select_list_of_structures = QPushButton(parent=self, text="...")
+        self.btn_select_working_directory = QPushButton(parent=self, text="...")
+
+        self.layout = QGridLayout()
+        self.init_UI()
+
+    def init_UI(self):
+        grid_group_box = QGroupBox("Input Files")
+        layout = QGridLayout()
+        # Working directory
+        self.tb_working_directory = QLineEdit(parent=self, text=str(self.vaut_config.get_output_directory().relative))
+        self.btn_select_working_directory.setMaximumWidth(self.btn_select_working_directory.sizeHint().height())
+        layout.addWidget(QLabel("Working directory"), 0, 0)
+        layout.addWidget(self.tb_working_directory, 0, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.btn_select_working_directory, 0, 3)  # row, column, rowspan, colspan
+
+        # List of structures
+        self.tb_list_of_structures = QLineEdit(parent=self, text=str(self.vaut_config.wafer_config.get_structure_file().relative))
+        self.btn_select_list_of_structures.setMaximumWidth(self.btn_select_list_of_structures.sizeHint().height())
+        layout.addWidget(QLabel("Input Structure File"), 1, 0)
+        layout.addWidget(self.tb_list_of_structures, 1, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.btn_select_list_of_structures, 1, 3)  # row, column, rowspan, colspan
+
+        grid_group_box.setLayout(layout)
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
+
+class WidgetSettingsOutFilesFolders(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+
+        self.tb_log_file = QLineEdit(text=self.vaut_config.wafer_config.get_log_file().filename)
+        self.tb_measurement_output = QLineEdit(text=self.vaut_config.wafer_config.get_measurement_output().filename)
+        self.tb_mat_files_output = QLineEdit(text=self.vaut_config.wafer_config.get_measurement_mat_file().filename)
+        self.tb_bookmark_file = QLineEdit(text=self.vaut_config.wafer_config.get_bookmark_file().filename)
+        self.tb_scope_image_file = QLineEdit(text=self.vaut_config.wafer_config.get_scope_image_file().filename)
+
+
+        self.layout = QGridLayout()
+        self.init_UI()
+
+    def init_UI(self):
+        layout = QGridLayout()
+        grid_group_box = QGroupBox("Output Files")
+        grid_group_box.setLayout(layout)
+
+
+
+
+
+
+        self.lbl_log_file = QLabel(parent=self)
+        self.tb_log_file.textChanged.connect(self.on_tb_log_file_text_changed)
+        self.on_tb_log_file_text_changed(self.tb_log_file.text())
+        layout.addWidget(QLabel("Log File"), 0, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_log_file, 0, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_log_file, 1, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # measurement output
+        self.lbl_measurement_output = QLabel(parent=self)
+        self.tb_measurement_output.textChanged.connect(self.on_tb_measurement_output_text_changed)
+        self.on_tb_measurement_output_text_changed(self.tb_measurement_output.text())
+        layout.addWidget(QLabel("Measurement output"), 2, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_measurement_output, 2, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_measurement_output, 3, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # Mat files output
+        self.lbl_mat_files_output = QLabel(parent=self)
+        self.on_tb_mat_files_output_text_changed(self.tb_mat_files_output.text())
+
+        self.tb_mat_files_output.textChanged.connect(self.on_tb_mat_files_output_text_changed)
+        layout.addWidget(QLabel("Matlab Files"), 4, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_mat_files_output, 4, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_mat_files_output, 5, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # bookmark files
+        self.lbl_bookmark_file = QLabel(parent=self)
+        self.on_tb_bookmark_file_text_changed(self.tb_bookmark_file.text())
+        self.tb_bookmark_file.textChanged.connect(self.on_tb_bookmark_file_text_changed)
+        self.tb_scope_image_file.textChanged.connect(self.on_tb_scope_image_file_text_changed)
+        layout.addWidget(QLabel("Bookmark files"), 6, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_bookmark_file, 6, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_bookmark_file, 7, 0, 1, 2)  # row, column, rowspan, colspan
+
+        # scope shots
+        self.lbl_scope_image_file = QLabel(parent=self)
+        self.on_tb_scope_image_file_text_changed(self.tb_scope_image_file.text())
+        layout.addWidget(QLabel("Scope Shots"), 8, 0)  # row, column, rowspan, colspan
+        layout.addWidget(self.tb_scope_image_file, 8, 1)  # row, column, rowspan, colspan
+        layout.addWidget(self.lbl_scope_image_file, 9, 0, 1, 2)
+
+
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
+    def on_tb_scope_image_file_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_scope_image_file().set_obj(value)
+        val = self.vaut_config.wafer_config.get_scope_image_file().relative.replace(self.vaut_config.get_output_directory().relative,
+                                                                         "<b>wd</b>")
+        self.lbl_scope_image_file.setText(val)
+        # set label hover text
+        self.lbl_scope_image_file.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+    def on_tb_measurement_output_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_measurement_output().set_obj(value)
+        val = self.vaut_config.wafer_config.get_measurement_output().relative.replace(self.vaut_config.get_output_directory().relative,
+                                                                           "<b>wd</b>")
+        self.lbl_measurement_output.setText(val)
+        # set label hover text
+        self.lbl_measurement_output.setToolTip(self.vaut_config.wafer_config.get_scope_image_file().absolute)
+
+    def on_tb_bookmark_file_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_bookmark_file().set_obj(value)
+        val = self.vaut_config.wafer_config.get_bookmark_file().relative.replace(self.vaut_config.get_output_directory().relative,
+                                                                      "<b>wd</b>")
+        self.lbl_bookmark_file.setText(val)
+        # set label hover text
+        self.lbl_bookmark_file.setToolTip(self.vaut_config.wafer_config.get_bookmark_file().absolute)
+
+        config = self.vaut_config
+
+    def on_tb_mat_files_output_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_measurement_mat_file().set_obj(value)
+        val = self.vaut_config.wafer_config.get_measurement_mat_file().relative.replace(
+            self.vaut_config.get_output_directory().relative,
+                                                                             "<b>wd</b>")
+        self.lbl_mat_files_output.setText(val)
+        self.lbl_mat_files_output.setToolTip(self.vaut_config.wafer_config.get_measurement_mat_file().absolute)
+
+    def on_tb_log_file_text_changed(self, value):
+        if value is not None:
+            self.vaut_config.wafer_config.get_log_file().set_obj(value)
+
+        val = self.vaut_config.wafer_config.get_log_file().relative.replace(self.vaut_config.get_output_directory().relative, "<b>wd</b>")
+        self.lbl_log_file.setText(val)
+        self.lbl_log_file.setToolTip(self.vaut_config.wafer_config.get_log_file().absolute)
+
+class WidgetAD2Settings(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+        self.c = ConfigView(vaut_config)
+
+
+        self.num_sample_rate = QDoubleSpinBox()
+        self.num_total_samples = QDoubleSpinBox()
+        self.num_sample_time = QDoubleSpinBox()
+
+        self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+        self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+        self.layout = QGridLayout()
+        self.init_UI()
+
+
+    def show_config(self):
+        self.c = ConfigView(self.vaut_config)
+        self.c.show()
+
+    def init_UI(self):
+        layout = QGridLayout()
+        grid_group_box = QGroupBox("Analog Discovery 2 Settings")
+        grid_group_box.setLayout(layout)
+
+        lbl_sample_rate = QLabel("Sample Rate")
+        layout.addWidget(lbl_sample_rate, 1, 0)
+        self.num_sample_rate.valueChanged.connect(lambda v: self.vaut_config.ad2_device_config.set_sample_rate(v))
+        self.num_sample_rate.setRange(0, 10**8)
+        self.num_sample_rate.setSingleStep(1)
+        self.num_sample_rate.setValue(self.vaut_config.ad2_device_config.get_sample_rate())
+        self.num_sample_rate.setSuffix(" Hz")
+        self.num_sample_rate.setDecimals(3)
+        self.num_sample_rate.setKeyboardTracking(False)
+        layout.addWidget(self.num_sample_rate, 1, 1, 1, 2)
+
+        lbl_total_samples = QLabel("Total Samples")
+        layout.addWidget(lbl_total_samples, 2, 0)
+        self.num_total_samples.setRange(0, 10**8)
+        self.num_total_samples.setSingleStep(1)
+        self.num_total_samples.setValue(self.vaut_config.ad2_device_config.get_total_samples())
+        self.num_total_samples.setDecimals(3)
+        self.num_total_samples.setKeyboardTracking(False)
+        layout.addWidget(self.num_total_samples, 2, 1, 1, 2)
+
+        lbl_sample_time = QLabel("Sample Time")
+        layout.addWidget(lbl_sample_time, 3, 0)
+        self.num_sample_time.setRange(0, 10**8)
+        self.num_sample_time.setSingleStep(1)
+        self.num_sample_time.setValue(self.vaut_config.ad2_device_config.get_sample_time())
+        self.num_sample_time.setSuffix(" s")
+        self.num_sample_time.setDecimals(3)
+        self.num_sample_time.setKeyboardTracking(False)
+        layout.addWidget(self.num_sample_time, 3, 1, 1, 2)
+
+        lbl_ad2_raw_out_file = QLabel("Raw Out File")
+        layout.addWidget(lbl_ad2_raw_out_file, 4, 0)
+        tb_ad2_raw_out_file = QLineEdit(text=self.vaut_config.ad2_device_config.get_ad2_raw_out_file().relative)
+        layout.addWidget(tb_ad2_raw_out_file, 4, 1)
+        layout.addWidget(self.btn_select_ad2_raw_out_file, 4, 2)
+
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
+class WidgetLaserSettings(QWidget):
+    def __init__(self, vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.vaut_config = vaut_config
+        self.c = None
+
+
+        self.num_wavelength_sweep_start = QDoubleSpinBox()
+        self.num_wavelength_range_stop = QDoubleSpinBox()
+        self.num_velocity = QDoubleSpinBox()
+        self.num_acceleration = QDoubleSpinBox()
+        self.num_deceleration = QDoubleSpinBox()
+
+
+        #self.btn_select_ad2_raw_out_file = QPushButton(parent=self, text="....")
+
+        #self.btn_select_ad2_raw_out_file.clicked.connect(self.show_config)
+        self.layout = QGridLayout()
+        self.init_UI()
+
+
+    def show_config(self):
+        self.c = ConfigView(self.vaut_config)
+        self.c.show()
+
+    def init_UI(self):
+        layout = QGridLayout()
+        grid_group_box = QGroupBox("Laser Settings")
+        grid_group_box.setLayout(layout)
+
+        lbl_wavelength_sweep_start = QLabel("Wavelength Sweep")
+        layout.addWidget(lbl_wavelength_sweep_start, 1, 0)
+
+
+
+        self.num_wavelength_sweep_start.setRange(0, 10 ** 8)
+        self.num_wavelength_sweep_start.setSingleStep(1)
+        self.num_wavelength_sweep_start.setValue(self.vaut_config.laser_config.get_wavelength_range()[0])
+        self.num_wavelength_sweep_start.setSuffix(" nm")
+        self.num_wavelength_sweep_start.setDecimals(3)
+        self.num_wavelength_sweep_start.setKeyboardTracking(False)
+        layout.addWidget(self.num_wavelength_sweep_start, 1, 1)
+        self.num_wavelength_sweep_start.valueChanged.connect(
+            lambda v: self.vaut_config.laser_config.set_wavelength_range(
+                [float(v), float(self.num_wavelength_range_stop.value())])
+        )
+
+        self.num_wavelength_range_stop.setRange(0, 10 ** 8)
+        self.num_wavelength_range_stop.setSingleStep(1)
+        self.num_wavelength_range_stop.setValue(self.vaut_config.laser_config.get_wavelength_range()[1])
+        self.num_wavelength_range_stop.setSuffix(" nm")
+        self.num_wavelength_range_stop.setDecimals(3)
+        self.num_wavelength_range_stop.setKeyboardTracking(False)
+        layout.addWidget(self.num_wavelength_range_stop, 1, 2)
+
+        self.num_wavelength_range_stop.valueChanged.connect(
+            lambda v: self.vaut_config.laser_config.set_wavelength_range(
+                [float(self.num_wavelength_sweep_start.value()), float(v)]
+        ))
+
+        lbl_velocity = QLabel("Velocity")
+        layout.addWidget(lbl_velocity, 2, 0)
+        self.num_velocity.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_velocity(v))
+        self.num_velocity.setRange(0, 10**8)
+        self.num_velocity.setSingleStep(1)
+        self.num_velocity.setValue(self.vaut_config.laser_config.get_velocity())
+        self.num_acceleration.setSuffix(" m/s")
+        self.num_velocity.setDecimals(3)
+        self.num_velocity.setKeyboardTracking(False)
+        layout.addWidget(self.num_velocity, 2, 1, 1, 2)
+
+        lbl_acceleration = QLabel("Acceleration")
+        layout.addWidget(lbl_acceleration, 3, 0)
+        self.num_acceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_acceleration(v))
+        self.num_acceleration.setRange(0, 10**8)
+        self.num_acceleration.setSingleStep(1)
+        self.num_acceleration.setValue(self.vaut_config.laser_config.get_acceleration())
+        self.num_acceleration.setSuffix(" m/s^2")
+        self.num_acceleration.setDecimals(3)
+        self.num_acceleration.setKeyboardTracking(False)
+        layout.addWidget(self.num_acceleration, 3, 1, 1, 2)
+
+        lbl_deceleration = QLabel("Deceleration")
+        layout.addWidget(lbl_deceleration, 4, 0)
+        self.num_deceleration.valueChanged.connect(lambda v: self.vaut_config.laser_config.set_deceleration(v))
+        self.num_deceleration.setRange(0, 10 ** 8)
+        self.num_deceleration.setSingleStep(1)
+        self.num_deceleration.setValue(self.vaut_config.laser_config.get_deceleration())
+        self.num_deceleration.setSuffix(" m/s^2")
+        self.num_deceleration.setDecimals(3)
+        self.num_deceleration.setKeyboardTracking(False)
+        layout.addWidget(self.num_deceleration, 4, 1, 1, 2)
+
+
+        self.layout.addWidget(grid_group_box)
+        self.setLayout(self.layout)
+
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/MeasuredData.py b/src/FlexSensor/MeasurementData/MeasuredData/MeasuredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..217bfe27e638dd16e05d1575c480ff76f60c1331
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/MeasuredData.py
@@ -0,0 +1,184 @@
+import logging
+import os
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+import scipy
+from numpy import ndarray
+
+from MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
+from MeasurementData.Properties.LaserProperties import LaserProperties
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataTables import MeasurementDataTables
+from MeasurementData.Properties.MeasurementProperties import MeasurementProperties, \
+    MPropertiesFindPeaks, WaveguideProperties
+from MeasurementData.Properties.WaferProperties import WaferProperties
+
+
+class MeasuredData:
+
+
+    def __init__(self, laser_properties: LaserProperties, ad2_properties: AD2CaptDeviceProperties,
+                 wafer_properties: WaferProperties, waveguide_properties: WaveguideProperties,
+                 measurement_properties: MeasurementProperties):
+        #super().__init__()
+        self.logger = logging.getLogger("MeasuredSignal")
+        # ==============================================================================================================
+        # Tables
+        self._tables: MeasurementDataTables = MeasurementDataTables()
+
+        # ==============================================================================================================
+        # Properties for storing information
+        self._laser_properties: LaserProperties = laser_properties  # Laser Properties
+        self._ad2_properties: AD2CaptDeviceProperties = ad2_properties  # AD2CaptDev Properties
+        self._wafer_properties: WaferProperties = wafer_properties  # Wafer Properties
+        self._waveguide_properties: WaveguideProperties = waveguide_properties  # Waveguide Properties
+        # Measurement properties like findpeaks parameter
+        self._measurement_properties: MeasurementProperties = MeasurementProperties(
+            MPropertiesFindPeaks(0.1, 10000, None))
+
+        # ==============================================================================================================
+        # Dataframe with measured values
+        self._measured_data: pd.DataFrame = self._tables.append(pd.DataFrame(), '_measured_data', "Measured Data")
+        # Calculation Tables
+        # Stores the found peaks
+        self._peaks: pd.DataFrame = self._tables.append(pd.DataFrame(), '_peaks', 'Peaks')
+        # Store wg parameters like FSR, and ng
+        self._wg_param: pd.DataFrame = self._tables.append(pd.DataFrame(), '_wg_param', 'Waveguide Parameters')
+
+        # ==============================================================================================================
+        # COnnect the signals
+        self._measurement_properties.find_peaks.properties_changed.connect(self.find_peaks)
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    @property
+    def waveguide_properties(self):
+        return self._waveguide_properties
+
+    @waveguide_properties.setter
+    def waveguide_properties(self, value):
+        self._waveguide_properties = value
+
+    @property
+    def measurement_properties(self):
+        return self._measurement_properties
+
+    @measurement_properties.setter
+    def measurement_properties(self, value):
+        self._measurement_properties = value
+
+    @property
+    def ad2_properties(self):
+        return self._ad2_properties
+
+    @ad2_properties.setter
+    def ad2_properties(self, value):
+        self._ad2_properties = value
+
+    @property
+    def laser_properties(self):
+        return self._laser_properties
+
+    @laser_properties.setter
+    def laser_properties(self, value):
+        self._laser_properties = value
+
+    @property
+    def wafer_properties(self):
+        return self._wafer_properties
+
+    @wafer_properties.setter
+    def wafer_properties(self, value):
+        self._wafer_properties = value
+
+    # ==================================================================================================================
+    # Properties
+    # ==================================================================================================================
+    @property
+    def tables(self) -> MeasurementDataTables:
+        return self._tables
+
+    @property
+    def peaks(self) -> pd.DataFrame:
+        return self._peaks
+
+    # ==================================================================================================================
+    # Calculations and table creations
+    # ==================================================================================================================
+    def calculate_wg_params(self, table="_peaks"):
+        peaks_wl: ndarray = self.tables.get(table)['wavelength'].to_numpy()
+        try:
+            if len(peaks_wl) % 2 == 1:
+                self.logger.warning(f"[{self}] | Number of peaks not even ({len(peaks_wl)}), removing last peak.")
+                peaks_wl = peaks_wl[:-1]
+            self.logger.info(f"[{self}] | Reshaping {np.shape(peaks_wl)} to (-1, 2)")
+            self._wg_param = pd.DataFrame(peaks_wl.reshape(-1, 2), columns=['P1', 'P2'])
+            self._wg_param['FSR'] = self._wg_param.apply(lambda row: row['P2'] - row['P1'], axis=1)
+            self._wg_param['lambda'] = self._wg_param.apply(lambda row: np.mean((row['P2'], row['P1'])), axis=1)
+            self._wg_param['ng'] = self.waveguide_properties.group_index(self._wg_param)
+            # self._wg_param.apply(lambda row: (row['lambda'] ** 2) / (row['FSR'] * dl), axis=1)
+            # Filter outliers
+            self._wg_param = self._tables.update(self._wg_param[(np.abs(scipy.stats.zscore(self._wg_param['ng'])) < 2)],
+                                                 '_wg_param')
+        except Exception as e:
+            print(f"Error {e}")
+
+    def __str__(self):
+        return f"{self.wafer_properties.wafer_number}/" \
+               f"{self.wafer_properties.die_number}/" \
+               f"{self.wafer_properties.structure_name} - {self.wafer_properties.repetition}"
+
+    # ==================================================================================================================
+    # I/O - Operations and Plotting
+    # ==================================================================================================================
+    def _save_mat_file(self, filename: str) -> object:
+
+        self._mat_filename = Path(filename)
+        dirname = self._mat_filename.parent.absolute()
+        self.logger.info(f"[{self}] | Generating mat file and saving to {self._mat_filename.name} (folder: {dirname})")
+        if self._mat_filename is None or self._mat_filename == "":
+            raise ValueError("No mat file generated. Filename is not defined")
+
+        if not str(self._mat_filename).endswith(".mat"):
+            raise ValueError("No mat file generated. Filename does not end with .mat")
+        if self._measured_data is None:
+            raise ValueError(
+                "No mat file generated. No measured amplitude data. No mat file produced fot this structure.")
+        # Get the file name from file
+
+        # Make a path
+        # Check if path exists
+        if not os.path.exists(dirname):
+            try:
+                os.makedirs(dirname)
+            except OSError as exc:  # Guard against
+                raise ValueError("No mat file generated. Could not create directory")
+        mdic = self.to_dict()
+        #print(mdic)
+        scipy.io.savemat(self._mat_filename, mdict=mdic)
+        #self._measured_data.to_csv(self.datafile)
+        self.write_matlab_file(self._mat_filename, self.datafile, f"{self._mat_filename.parent}/load_all.m")
+
+        self.logger.info(f"[{self}] | Stored matlab file to {self._mat_filename}")
+
+        return self._mat_filename
+
+    def write_matlab_file(self, mat_file, csv_file, filename: str) -> object:
+        mfile = ""
+        mfile += "load('" + str(filename) + "');"
+        # load csv with matlab
+        mfile += "data = readcsv('" + str(self.datafile) + "');"
+        # save matlab file
+        with open(filename, 'w') as f:
+            f.write(mfile)
+
+    # ==================================================================================================================
+    # abstract methods
+    # ==================================================================================================================
+    def find_peaks(self):
+        raise NotImplementedError()
+
+    def to_dict(self) -> dict:
+        raise NotImplementedError()
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/MultiMeasuredData.py b/src/FlexSensor/MeasurementData/MeasuredData/MultiMeasuredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..77293227af0a117a1792590b8e355de068bf5d12
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/MultiMeasuredData.py
@@ -0,0 +1,142 @@
+import time
+
+import numpy as np
+import pandas as pd
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QProgressDialog
+from numpy import ndarray
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+import mcpy
+from MeasurementData.MeasuredData.SupportClasses.MatplotlibPlottingHelpers import MPLPlottingHelper
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader
+from generics.logger import setup_logging
+from wrappers.QProgressBarWindow import QProgressBarWindow
+
+
+class MultiMeasuredData(MeasuredData):
+
+    def __init__(self, single_measurements: list[SingleMeasuredData]):
+        self._single_measurements = single_measurements
+
+        super().__init__(laser_properties=self._single_measurements[0].laser_properties,
+                         ad2_properties=self._single_measurements[0].ad2_properties,
+                         wafer_properties=self._single_measurements[0].wafer_properties,
+                         waveguide_properties=self._single_measurements[0].waveguide_properties,
+                         measurement_properties=self._single_measurements[0].measurement_properties,
+                         )
+        self.wafer_properties._structure_name += " - Mean"
+
+        self._recalculate_measured_data()
+        self.consolidate_measurement()
+        self.calculate_mean_and_std()
+        self.calculate_wg_params(table='_peaks')
+        self.calculate_all(table='_peaks')
+
+    def consolidate_measurement(self):
+        self.logger.info("Consolidating all measurements to one measurement")
+        progress = QProgressDialog(f"Reading files...", "Abort", 0, len(self._single_measurements))
+        progress.setWindowModality(Qt.WindowModal)
+        progress.show()
+
+        tmp_measured_data = []
+        for i, mea, it in QProgressBarWindow(self._single_measurements):
+            it.print(f"Consolidating measurement {str(mea)}")
+            tmp_measured_data.append(pd.DataFrame(
+                mea.tables.get('_peaks')['wavelength'].reset_index()[:].values,
+                columns=[f'index_{mea.wafer_properties.repetition}',
+                         f'wavelength_{mea.wafer_properties.repetition}']
+            ))
+
+        self._measured_data = self._tables.update(pd.concat(tmp_measured_data, axis=1), '_measured_data')
+
+    def _recalculate_measured_data(self):
+        self.logger.info("Recalculating all measurements")
+
+        for i, mea, it  in QProgressBarWindow(self._single_measurements):
+            mea.calulate_all()
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def calculate_mean_and_std(self):
+        self._peaks['wavelength'] = self._measured_data.filter(like='wavelength').apply(
+            lambda row: mcpy.DirectObservations(row), axis=1)
+        self._peaks['index'] = self._measured_data.filter(like='index').apply(
+            lambda row: mcpy.DirectObservations(row), axis=1)
+        self._tables.update(self._peaks, '_peaks')
+
+    def calculate_all(self, table='_peaks', N=100000):
+        peaks_wl: ndarray = self.tables.get(table)['wavelength'].to_numpy()
+        try:
+            if len(peaks_wl) % 2 == 1:
+                self.logger.warning(f"[{self}] | Number of peaks not even ({len(peaks_wl)}), removing last peak.")
+                peaks_wl = peaks_wl[:-1]
+            self.logger.info(f"[{self}] | Reshaping {np.shape(peaks_wl)} to (-1, 2)")
+            self._wg_param = pd.DataFrame(peaks_wl.reshape(-1, 2), columns=['P1', 'P2'])  # .astype(Uncertainty)
+
+            self._wg_param['P1 (MC)'] = self._wg_param.apply(
+                lambda row: row['P1'].rand(N), axis=1)
+
+            self._wg_param['P2 (MC)'] = self._wg_param.apply(
+                lambda row: row['P2'].rand(N), axis=1)
+
+            self._wg_param['FSR (MC)'] = self._wg_param.apply(
+                lambda row: row['P2 (MC)'] - row['P1 (MC)'], axis=1)
+
+            self._wg_param['lambda (MC)'] = self._wg_param.apply(
+                lambda row: (row['P2 (MC)']+row['P1 (MC)'])/2, axis=1)
+
+            self._wg_param['ng (MC)'] = self._wg_param.apply(
+                lambda row: self.waveguide_properties.group_index(row['lambda (MC)'], row['FSR (MC)'] ), axis=1)
+            # Place here any other calculations
+
+            # Update the _tables
+            self._tables.update(self._wg_param, '_wg_param')
+            self._tables.add_plot('ng (FSR)',
+                                  plot_function=lambda plotwidget: MPLPlottingHelper.plt_errorbar_mcsamples(
+                                      plotwidget,
+                                      x_values=self._wg_param['lambda (MC)'],
+                                      y_values=self._wg_param['ng (MC)']))
+            self._tables.add_plot('FSR (FSR)',
+                                  plot_function=lambda plotwidget: MPLPlottingHelper.plt_errorbar_mcsamples(
+                                      plotwidget,
+                                      x_values=self._wg_param['lambda (MC)'],
+                                      y_values=self._wg_param['FSR (MC)']))
+        except Exception as e:
+            print(f"Error {e}")
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def to_dict(self) -> dict:
+        return {
+            "laser_properties": self._laser_properties.to_dict(),
+            "wafer_properties": self._wafer_properties.to_dict(),
+            "measurement_properties": self._measurement_properties.to_dict(),
+            "waveguide_properties": self._waveguide_properties.to_dict(),
+            "amplitudes": [i.to_dict() for i in self._single_measurements],
+
+        }
+
+    def __str__(self):
+        return f"{self.wafer_properties.wafer_number}/" \
+               f"{self.wafer_properties.die_number}/" \
+               f"{self.wafer_properties.structure_name}-Sum"
+
+
+if __name__ == "__main__":
+    setup_logging()
+
+    mypath = 'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement_small'
+    mm_data = MeasurementDataLoader.from_folder(mypath)
+    print(mm_data.wafers)
+    print(mm_data.dies)
+    print(mm_data.structure_name)
+
+    filtered_files = mm_data.get_measurement_series(structure_name='mzi2-2')
+
+    data = MultiMeasuredData(filtered_files)
+    print(data._wg_param)
+    # ädata.generate_mat_file(r'E:\test.mat')
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SingleMeasuredData.py b/src/FlexSensor/MeasurementData/MeasuredData/SingleMeasuredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..e21abc0db0a958240a6bf1e0fdb270909a2d12ff
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SingleMeasuredData.py
@@ -0,0 +1,667 @@
+import sys
+sys.path.append("../flexsensorpy")
+sys.path.append("../mcpy")
+import pathlib
+from datetime import datetime
+
+
+import scipy.io
+import numpy as np
+import pandas as pd
+
+import logging
+from pathlib import Path
+
+from PySide6.QtWidgets import QApplication
+from numpy import linspace
+from scipy import signal
+from scipy.io import matlab
+from scipy.signal import find_peaks
+import scipy
+
+from MeasurementData.Properties.AD2CaptDeviceProperties import AD2CaptDeviceProperties
+
+from MeasurementData.Properties.LaserProperties import LaserProperties
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.Properties.MeasurementProperties import (WaveguideProperties,
+                                                              MeasurementProperties,
+                                                              WaveguidePropertiesMZI,
+                                                              MPropertiesFindPeaks)
+
+import mcpy
+
+from MeasurementData.Properties.WaferProperties import WaferProperties
+from generics.logger import setup_logging
+
+
+class SingleMeasuredData(MeasuredData):
+
+    # ==================================================================================================================
+    # Load a Measurement data from a matlab mat-file
+    # ==================================================================================================================
+    @classmethod
+    def from_mat(cls, mat_file: Path | str) -> 'SingleMeasuredData':
+        """
+        This allows to open "old" mat files, that do not have some data.
+        """
+        mat_file = pathlib.Path(mat_file)
+        logging.info(f"Loading {mat_file.name}")
+        matf = scipy.io.loadmat(mat_file)
+
+        inst = cls(
+            laser_properties=LaserProperties(
+                mcpy.Rectangular(2, 0.01, unit='nm/s'),
+                mcpy.Rectangular(2, 0.01, unit='nm/s'),
+                mcpy.Rectangular(0.5, 0.01, unit='nm/s^2'),
+                (mcpy.Rectangular(835, 0.01, unit='nm'), mcpy.Rectangular(870, 0.01, unit='nm'))
+            ),
+            ad2_properties=AD2CaptDeviceProperties(
+                0, 0, matf['ad2_sample_rate'], matf['ad2_total_samples'], matf['measure_time']
+            ),
+            wafer_properties=WaferProperties(
+                matf['wafer_nr'],
+                matf['structure_name'],
+                matf['die_nr'],
+                matf['chuck_col'],
+                matf['chuck_row'],
+                (int(matf['structure_x_in']), int(matf['structure_y_in'])),
+                (int(matf['structure_x_out']), int(matf['structure_y_out'])),
+                int(mat_file.name.split('_')[9].replace('.mat', ''))
+            ),
+            waveguide_properties=WaveguidePropertiesMZI(
+                length1=mcpy.Rectangular(10e6, 20, unit='nm'),
+                length2=mcpy.Rectangular(10.38e6, 20, unit='nm'),
+                width=mcpy.Rectangular(550, 20, unit='nm'),
+                height=mcpy.Rectangular(625, 2.405, unit='nm')),
+            measurement_properties=MeasurementProperties(
+                MPropertiesFindPeaks(0.1, 10000, None)
+            ),
+            timestamp=matf['timestamp'],
+            measurement_file=None,
+            measurement_data=matf['amplitude'][0]
+        )
+        """
+        date_format = '%a %b %d %H:%M:%S %Y'
+        x = datetime. strptime(
+        re.search('(?<=Created on: ).*', matf['__header__'].decode('UTF-8')).group(0),
+        date_format)"""
+
+        return inst
+
+    @classmethod
+    def from_mat_v2(cls, mat_file: Path | str):
+        def loadmat(filename):
+            '''
+            this function should be called instead of direct spio.loadmat
+            as it cures the problem of not properly recovering python dictionaries
+            from mat files. It calls the function check keys to cure all entries
+            which are still mat-objects
+            '''
+            data = scipy.io.loadmat(filename, struct_as_record=False, squeeze_me=True)
+            return _check_keys(data)
+
+        def _check_keys(dict):
+            '''
+            checks if entries in dictionary are mat-objects. If yes
+            todict is called to change them to nested dictionaries
+            '''
+            for key in dict:
+                if isinstance(dict[key], matlab.mio5_params.mat_struct):
+                    dict[key] = _todict(dict[key])
+            return dict
+
+        def _todict(matobj):
+            '''
+            A recursive function which constructs from matobjects nested dictionaries
+            '''
+            dict = {}
+            for strg in matobj._fieldnames:
+                elem = matobj.__dict__[strg]
+                if isinstance(elem, matlab.mio5_params.mat_struct):
+                    dict[strg] = _todict(elem)
+                else:
+                    dict[strg] = elem
+            return dict
+
+        if isinstance(mat_file, str):
+            mat_file = Path(mat_file)
+
+        logging.info(f"Loading {mat_file.name}")
+        matf = loadmat(mat_file)
+        # mcpy.Uncertainty.from_tuple(matf['laser_properties']['laser_wavelength'])
+        inst = cls(
+            laser_properties=LaserProperties.from_dict(matf['laser_properties']),
+            ad2_properties=AD2CaptDeviceProperties.from_dict(matf['ad2_properties']),
+            wafer_properties=WaferProperties.from_dict(matf['wafer_properties']),
+            waveguide_properties=WaveguidePropertiesMZI.from_dict(matf['waveguide_properties']),
+            measurement_properties=MeasurementProperties.from_dict(matf['measurement_properties']),
+            timestamp=matf['timestamp'],
+            measurement_data=pd.DataFrame({
+                            'wavelength': matf['wavelength'],
+                            'amplitude': matf['amplitude'],
+                            'amplitude_detrended': matf['amplitude_detrended']}),
+
+            #measurement_file=Path(f"{mat_file.absolute().parent}/{matf['measurement_file']}").absolute()
+        )
+        return inst
+
+    @staticmethod
+    def convert(mat_file):
+        """Reads the mat file and converts the new format to the old format"""
+        data = SingleMeasuredData.from_mat(mat_file)
+        filename = mat_file.name.replace('.mat', '_v2.mat')
+        path = str(mat_file.parent).replace('measurements', 'measurements_v2')
+        # create a folder converted and save the file there
+        file = Path(f"{path}/{filename}")
+        data.save(str(file))
+
+
+    def __init__(self,
+                 laser_properties: LaserProperties,
+                 ad2_properties: AD2CaptDeviceProperties,
+                 wafer_properties: WaferProperties,
+                 waveguide_properties: WaveguideProperties,
+                 measurement_properties: MeasurementProperties,
+                 timestamp: datetime,
+                 measurement_file: Path | str = None,
+                 measurement_data = None,
+                 *args, **kwargs
+                 ):
+        super().__init__(laser_properties, ad2_properties, wafer_properties, waveguide_properties, measurement_properties)
+
+        if isinstance(measurement_data, list) or isinstance(measurement_data, np.ndarray):
+            self.measurement_file = measurement_file
+            # Store ot
+            self._measured_data: pd.DataFrame = self._tables.update(
+                    pd.DataFrame(measurement_data, columns=['amplitude']), '_measured_data')
+            self._measurement_length = len(self._measured_data)
+            self.logger.debug(f"Measurement signal length: {self._measurement_length}")
+            # Generate the wacelength vector
+            self._create_wavelength_vector()
+            # Detrend the signal
+            self._detrend_signal()
+        else:
+            #self._raw_measurement_data: dask.array = dd.read_parquet(self.measurement_file)
+            self._measured_data = self._tables.update(measurement_data, '_measured_data')
+
+
+        self.print_enabled = True
+        self._calculated = False
+        # ==============================================================================================================
+        self._timestamp = timestamp
+        self._measure_time = self._ad2_properties.measurement_time
+
+        self.datafile = None
+        # Measured Data (raw)
+
+        # self._measurement_data_smoothed = self._smooth_signal(self._measurement_data_detrend)
+
+        # ==============================================================================================================
+        # Dataframe with measured values
+
+        # self._create_wavelength_vector()
+        # self._detrend_signal()
+
+    @property
+    def measured_data(self):
+        return self._measured_data
+
+    @measured_data.setter
+    def measured_data(self, value):
+        self._measured_data = value
+
+    # ==================================================================================================================
+    # Generate a wavelength vector from the given settings
+    # ==================================================================================================================
+    def _create_wavelength_vector(self):
+        """ 
+            Creates the wavelength vector for the measured data.
+            The wavelength vector is created based on the given laser properties.
+        """
+        
+        sample_rate = float(self._ad2_properties.sample_rate)
+        acc = float(self._laser_properties.acceleration)
+        dec = float(self._laser_properties.deceleration)
+        vel = float(self._laser_properties.velocity)
+        wl_range = self._laser_properties.wavelength_range
+
+        self.logger.debug(f"Creating wavelenght vector.")
+        self.logger.debug(f"Velocity: {vel}, Acc: {acc}, Dec: {dec}, Range: {wl_range}")
+        
+        # the duration of a sample in s
+        duration_sample = 1 / sample_rate
+        t_acc = vel / acc  # Acceleration time of the laser; s
+        t_dec = vel / dec  # Deceleration time of the laser; s
+        self.logger.debug(f"duration_sample: {duration_sample}, t_acc: {t_acc}, Dec: {t_dec}")
+
+        self.p_acc_stop = int(t_acc * sample_rate)
+        self.logger.debug(f"Point acc_stop [{t_acc}*{sample_rate}]: {self.p_acc_stop}")
+
+        self.p_dec_start = int(self._measurement_length - t_acc * sample_rate)
+        self.logger.debug(f"Point dec_start [{self._measurement_length}-{t_acc}*{sample_rate}]: {self.p_dec_start}")
+
+        if self.p_acc_stop > self.p_dec_start:
+            raise ValueError("The Acceleration point cant be before the decceleration point: {self.p_acc_stop} > {self.p_dec_start}")
+        
+        s_acc = []
+        for j in range(0, self.p_acc_stop):
+            s_acc.append(
+                ((1 / 2) * t_acc * (duration_sample * j) ** 2)
+            )
+        wl_acc = np.add(s_acc, float(wl_range[0]))
+        self.logger.debug(f"Length of acc vector: {len(wl_acc)}")    
+        wl_dec = np.subtract(float(wl_range[len(wl_range) - 1]),
+                             s_acc)[::-1]
+        self.logger.debug(f"Length of dec vector: {len(wl_dec)}")                     
+        # Acceleration Phase/Deceleration Phase - Start and stop point
+        self.wl_acc_stop = wl_acc[-1]
+        self.wl_dec_start = wl_dec[0]
+        #self.logger.debug(f"lenght: {self.p_dec_start} - {self.p_acc_stop}")
+        length = int((self.p_dec_start - self.p_acc_stop))
+        rounding_diff = self._measurement_length - (length + len(wl_acc) + len(wl_dec))
+        length += rounding_diff
+        self.logger.debug(f"0 {length}")
+        # self.logger.debug(f"+1 {length+2}")
+        #self.logger.debug(f"+3{length+3}")
+        #length = length + 1
+        # self.logger.debug(f"+1 {length}")
+        wl_move = linspace(self.wl_acc_stop, self.wl_dec_start, length)
+       
+        wl = np.concatenate((wl_acc, wl_move, wl_dec))
+        self.logger.debug(f"[{self}] | Created wavelength vector: [0 - {self.p_acc_stop}] (Diff {len(wl_acc)}) -- "
+                          f"<{len(wl_move)}> -- "
+                          f"[{self.p_dec_start} - {len(wl)}] (Diff {len(wl_dec)})")
+
+        self._measured_data['wavelength'] = wl
+
+    def _smooth_signal(self, vec, window=150):
+
+        return np.convolve(vec, np.ones(window), 'valid') / window
+
+    def _detrend_signal(self):
+        self._measured_data['detrend'] = signal.detrend(self._measured_data['amplitude'])
+
+    # ==================================================================================================================
+    # Calculations and table creations
+    # ==================================================================================================================
+    def find_peaks(self):
+        self._detrend_signal()
+        vec = self._measured_data['detrend']
+        _peaks, _ = find_peaks(vec,
+                               height=self.measurement_properties.find_peaks.height,
+                               distance=self.measurement_properties.find_peaks.distance,
+                               prominence=self.measurement_properties.find_peaks.prominence)
+        peaks = np.zeros(len(vec))
+        peaks[_peaks] = 1
+        self._measured_data['peaks'] = peaks.astype(bool)
+        self._peaks = self._tables.update(self._measured_data[self._measured_data['peaks'] == True], '_peaks')
+        self.logger.debug(f"[{self}] | Found {len(self._peaks)} peaks. "
+                          f"Parameters {self.measurement_properties.find_peaks}")
+
+    def calulate_all(self, recalculate=False):
+        if not self._calculated or recalculate:
+            self.logger.info(f"[{self}] | Recalculating measurements {str(self)}")
+
+            self.find_peaks()
+            self.calculate_wg_params()
+            self._calculated = True
+
+    # ==================================================================================================================
+    # Filtering (old)
+    # ==================================================================================================================
+    def apply_filter(self):
+        if not self._ad2_properties_set:
+            raise Exception("AD2 properties not set. Please set them first.")
+
+        if not self._laser_properties_set:
+            raise Exception("Laser properties not set. Please set them first.")
+
+        (
+            self._filtered_amplitude,
+            first_start, self.start_idx,
+            first_end, self.end_idx,
+            self.signal_end_expected,
+            self.marker_start,
+            self.marker_stop
+        ) = self.filter_signal(self.measured_data, column='measurements')
+
+        self.time_start_point = self.start_idx / self.ad2_sample_rate
+        self.time_end_point = self.end_idx / self.ad2_sample_rate
+        self.time_end_point_expected = self.signal_end_expected / self.ad2_sample_rate
+
+        self._filtered_amplitude = self.assign_wavelength(self._filtered_amplitude, self.wavelength_range[0],
+                                                          self.wavelength_range[1])
+        self.signal_length = len(self._filtered_amplitude)
+
+        # Sanity check if the found length is approximatly the same as the expected length
+        tolerance = 0.025  # 2,5 % tolerance = 0.25 sec
+        if 1 - abs(self.signal_end_expected / self.end_idx) > tolerance:
+            raise Exception(
+                f"The found signal length ({self.signal_end_expected})"
+                f"is not approximatly the same as the expected signal length ({self.end_idx})."
+            )
+
+        return (self._filtered_amplitude,
+                self.start_idx, self.time_start_point,
+                self.end_idx, self.time_end_point,
+                self.signal_end_expected, self.time_end_point_expected
+                )
+
+    def find_index(self, samples_sweep=None, keyword='filtered', threshold=0.0005, reverse_signal=False):
+        rolling_keyword = 'rolling'
+        marker = {
+            'first_hit': 0,
+            'steady_mean': 0,
+            'steady_mean_pt': 0,
+            'steady_mean_mt': 0,
+            'steady_min': 0,
+            'steady_max': 0,
+            'window_for_mean': [0, 0],
+            'window_for_search': [0, 0],
+            'second_hit': 0,
+        }
+        if reverse_signal:
+            self.logger.debug("[FILTER:FIND INDEX] Reversing the signal")
+            samples = samples_sweep[::-1]
+            samples = samples.reset_index(drop=True)
+        else:
+            samples = samples_sweep
+
+        # create a new dataframe
+        # Drop values that have been already marked as invalid
+        samples = samples.dropna()
+
+        # *****************************************************************************************
+        # (1): Extract 200 ms and calculate a mean value. This will be used to find the
+        # approximative start point of the signal.
+        #      (1.1) Cut a part that we are sure is steady (e.g. 100 ms after the start up to 300ms)
+        start_idx = int(self.ad2_sample_rate / 10)
+        stop_idx = int((self.ad2_sample_rate / 10) * 3)
+        sample_window_steady = samples[keyword][start_idx:stop_idx]
+        self.logger.debug(
+            "[FILTER:FIND INDEX:1.1] Extract 200 ms and find min and max values. start_idx %s, stop_idx %s" % (
+                start_idx, stop_idx))
+        #      (1.2) We now want to approximatly find the part where the signal starts rising or fluctuatig.
+        #            This is, where the Signal is greater than our min or max values
+        #            Also, store these values as a marker
+        signal_min = float(sample_window_steady.min());
+        marker['steady_min'] = signal_min
+        signal_max = float(sample_window_steady.max());
+        marker['steady_max'] = signal_max
+        self.logger.debug(
+            "[FILTER:FIND INDEX:1.2] Signal processed. signal_min %s, signal_max %s" % (signal_min, signal_max))
+        #      (1.3) Extract the first approximate starting position. This is, where the signal exceed
+        #             our min or max values. We have found the first approximate starting point.
+        index_first_hit = samples[
+            (samples[rolling_keyword] >= signal_max) | (samples[rolling_keyword] <= signal_min)
+            ].first_valid_index()
+        index_first_hit_abs = samples.index1[index_first_hit]
+        self.logger.info(
+            f"[FILTER:FIND INDEX:1.3] First index found at {index_first_hit_abs / self.ad2_sample_rate} sec. index_first_hit {int(index_first_hit_abs)}/{len(samples)} (rel: {index_first_hit})")
+
+        # *****************************************************************************************
+        # (2) Now we want to calculate a mean that is near our starting point. For this, we go back
+        #     200 ms and calculate the mean of 200 ms. This should yield to a mean value that corresponds
+        #     to our signal shortly bevor it starts.
+        value = int(self.ad2_sample_rate / 10)
+        if reverse_signal:
+            start_idx = int(index_first_hit - value * 4)
+            start_idx_abs = int(index_first_hit_abs + value * 2)
+            stop_idx = int(index_first_hit - value * 2)
+            stop_idx_abs = int(index_first_hit_abs + value * 4)
+        else:
+            start_idx = int(index_first_hit - value * 4)
+            start_idx_abs = int(index_first_hit_abs - value * 4)
+            stop_idx = int(index_first_hit - value * 2)
+            stop_idx_abs = int(index_first_hit_abs - value * 2)
+
+        window_for_mean = samples[keyword].loc[start_idx:stop_idx];
+        marker['window_for_mean'] = [start_idx_abs, stop_idx_abs]
+        self.logger.debug(
+            "[FILTER:FIND INDEX:2.1] Extract 200 ms and calculate a new mean value. start_idx %s (rel %s), stop_idx %s (rel: %s). len <%s>"
+            % (start_idx_abs, start_idx,
+               stop_idx_abs, stop_idx, len(window_for_mean)))
+        #      (2.1) Calculate the mean value of the 200 ms window
+        signal_mean = float(window_for_mean.mean());
+        marker['steady_mean'] = signal_mean
+        self.logger.debug("[FILTER:FIND INDEX:2.2] Signal processed. signal_mean %s" % (signal_mean))
+
+        # *****************************************************************************************
+        # (3) Since we have found a mean value that hopefully cooresponds to our mean value of the steady
+        #     part near our first starting point, we can try to find a more accurate starting point.
+        #     Again, this si done by defining a threshold that, if exceeded, mark our new, more accurate starting point.
+        treshold_max = signal_mean * (1 + threshold);
+        marker['steady_mean_pt'] = treshold_max
+        treshold_min = signal_mean * (1 - threshold);
+        marker['steady_mean_mt'] = treshold_min
+        self.logger.debug(
+            "[FILTER:FIND INDEX:3.1] Defining new thresholds for mean: <%s>: treshold_max <%s>, treshold_min <%s>" % (
+                signal_mean, treshold_max, treshold_min))
+
+        #      (3.1) New get a window of our expected signal start. 
+        #            self.print_m("[3]: dataframe 'samples_cut \n%s" % samples)
+        value = int(self.ad2_sample_rate / 10)
+        start_idx = int(index_first_hit - value)
+        start_idx_abs = int(index_first_hit_abs - value)
+        stop_idx = int(index_first_hit + value)
+        stop_idx_abs = int(index_first_hit_abs + value)
+        window_for_search = samples.loc[start_idx:stop_idx];
+        marker['window_for_search'] = [start_idx_abs, stop_idx_abs]
+        self.logger.debug(
+            "[FILTER:FIND INDEX:3.2] Extract 200 ms around the starting point. start_idx %s (rel %s), stop_idx %s (rel: %s). len <%s>"
+            % (start_idx_abs, start_idx, stop_idx_abs, stop_idx, len(window_for_search)))
+        #     (3.2) Now we want to find the first point where the signal exceeds our threshold.
+        index_second_hit = window_for_search[
+            (window_for_search[rolling_keyword] > treshold_max) | (window_for_search[rolling_keyword] < treshold_min)
+            ].first_valid_index()
+        if index_second_hit is None:
+            raise Exception("End of Signal not found. index_second_hit %s" % index_second_hit)
+        #    (3.3) This window may have not the corrct indices. We need to get the correct one
+        index_second_hit_abs = samples.index1[index_second_hit]
+        self.logger.info(
+            f"[FILTER:FIND INDEX:3.3] Second index found at {index_second_hit_abs / self.ad2_sample_rate} sec. index_second_hit {index_second_hit_abs}/{len(samples)} (rel: {index_second_hit})"
+        )
+
+        if index_second_hit == None:
+            index_second_hit = 0
+        else:
+            index_second_hit = samples.index1[index_second_hit]
+            marker['second_hit'] = index_second_hit
+        index_first_hit = samples.index1[index_first_hit]
+        marker['first_hit'] = index_first_hit
+
+        return index_first_hit_abs, index_second_hit_abs, marker
+
+    def filter_signal(self, measured_amplitude, column='measurements'):
+        self.logger.info("[FILTER] Applying filter to given signal.")
+        # Filter the first second of the measurement
+        measured_amplitude = measured_amplitude.reset_index().rename({'index': 'index1'}, axis='columns')
+        measured_amplitude['filtered'] = measured_amplitude[column]
+        measured_amplitude.loc[:self.ad2_sample_rate] = None
+        # Calculate the moving average
+        measured_amplitude["rolling"] = measured_amplitude['filtered'].rolling(window=1000).mean().shift(
+            -500)  # [1000-1:] # 0,01nm
+        self.logger.debug(f"[FILTER] Total Length of given signal {len(measured_amplitude)}")
+
+        first_start, second_start, marker_start = self.find_index(measured_amplitude, column)
+        self.logger.info(f"[FILTER] Starting index found at {second_start} (first hit at {first_start}) ")
+        measured_amplitude['filtered'].loc[:second_start] = None
+
+        # Now we need to find the end of the signal. For this we assume, that the laser movement is "nearly" correct.
+        # The laser waits approximatly 500 ms to move the laser back to it's starting position.
+        index_signal_end_expected = int(second_start + (self.laser_movement_time * self.ad2_sample_rate))
+        self.logger.debug(f"[FILTER] Expected end: {index_signal_end_expected}")
+
+        # We found the expected length, the laser waits for 500 ms until moving back
+        # We want to use this, to get the mean value of the amplitude of this specific wave length
+        # For this we cut the signal 400 ms (= ad2_sample_rate * 0.4) after the expected end
+        measured_amplitude['filtered'].loc[int(index_signal_end_expected + (self.ad2_sample_rate * 0.4)):] = None
+        # Reverse the signal and do the same procedure again
+
+        first_end, second_end, marker_stop = self.find_index(measured_amplitude, column, reverse_signal=True)
+        self.logger.info(f"[FILTER] End index found at {second_end} (first hit at {first_end}).")
+        measured_amplitude['filtered'].loc[second_end:] = None
+
+        measured_amplitude.dropna(inplace=True)
+        # measured_amplitude = measured_amplitude.drop(['index1'], axis = 1)
+        filtered_aplitude = measured_amplitude.filter(['filtered'], axis=1).reset_index(drop=True)
+        self.logger.info(
+            f"[FILTER] AD2 sample rate: {self.ad2_sample_rate} samples/sec. "
+            f"AD2 samples: {self.ad2_total_samples} samples. "
+            f"AD2 measurement duration: {self.ad2_total_measurement_time} sec."
+        )
+        self.logger.info(
+            f"[FILTER] Laser movement ({self.wavelength_range[0]}-{self.wavelength_range[1]}): {self.laser_movement_time} sec. "
+            f"Laser velovity: {self.laser_velocity} m/s. "
+            f"Laser samples expected: {self.laser_samples_expected} samples ({self.laser_samples_expected / self.ad2_sample_rate}) sec."
+        )
+        self.logger.info(
+            f"[FILTER] Signal length {len(self._measured_data)} ({len(self._measured_data) / self.ad2_sample_rate} sec). "
+            f"Start {second_start} ({second_start / self.ad2_sample_rate} sec). "
+            f"End {second_end} ({second_end / self.ad2_sample_rate} sec). "
+            f"Expected: {index_signal_end_expected} ({index_signal_end_expected / self.ad2_sample_rate} sec). "
+            f"Diff {second_end - second_start} ({second_end / self.ad2_sample_rate - second_start / self.ad2_sample_rate} sec)."
+        )
+
+        # self.print_m(samples_sweep_down)
+        return (filtered_aplitude,
+                first_start, second_start,
+                first_end, second_end,
+                index_signal_end_expected,
+                marker_start,
+                marker_stop
+                )
+
+    def assign_wavelength(self, filtered_amplitude: list = None, wavelength_start: float = 850,
+                          wavelength_stop: float = 855, start_point: int = None):
+        measurment_points = len(filtered_amplitude)
+        filtered_amplitude['wavelength'] = pd.Series(
+            np.linspace(wavelength_start, wavelength_stop, measurment_points)
+        )
+        # filtered_amplitude.set_index('wavelength',inplace=True)
+        # if start_point is None:
+        #     # Get the number of measruement points (should be 50000):
+
+        #     #self.print_m(measurment_points)
+
+        #     #self.print_m(measured_amplitude)
+        # else:
+        #     # We need to assign the first n (up to the start_point) points the l
+        #     end_point = start_point + self.laser_samples_expected
+        #     filtered_amplitude['wavelength'] = 0
+        #     filtered_amplitude.loc[0:start_point-1, 'wavelength'] = wavelength_start
+        #     filtered_amplitude.loc[start_point:end_point, 'wavelength'] = pd.Series(
+        #         np.linspace(wavelength_start, wavelength_stop, measurment_points)
+        #     )
+        #     filtered_amplitude.loc[end_point+1:measurment_points-1, 'wavelength'] = wavelength_stop
+
+        return filtered_amplitude
+
+    # ==================================================================================================================
+    # To dicts
+    # ==================================================================================================================
+    def save(self, filename: str = None):
+        self.filename = filename
+        self._save_mat_file(self.filename)
+        #self._save_measurement_parquet(self.measurement_file)
+
+    def _save_measurement_parquet(self, filename: str = None):
+        # Save the measurement file
+
+        if filename is None:
+            filename = self.filename
+        filename = filename.replace('.mat', '.parquet')
+        self.measurement_file = filename
+        self._measured_data.to_parquet(self.measurement_file)
+        self.logger.info(f"Saved measurement file to {self.measurement_file}")
+
+    def to_dict(self) -> dict:
+        return {
+            "laser_properties": self._laser_properties.to_dict(),
+            "ad2_properties": self._ad2_properties.to_dict(),
+            "wafer_properties": self._wafer_properties.to_dict(),
+            "measurement_properties": self._measurement_properties.to_dict(),
+            #"waveguide_properties": self._waveguide_properties.to_dict(),
+            #"measurement_file": str(Path(self.measurement_file).absolute().relative_to(Path(self._mat_filename).parent)),
+            "amplitude": self._measured_data['amplitude'].to_list(),
+            "wavelength": self._measured_data['wavelength'].to_list(),
+            "amplitude_detrended": self._measured_data['detrend'].to_list(),
+            'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
+            "version": "2.0.0"
+        }
+
+    # def flatten(self, parent_key='', sep='.'):
+    #     items = []
+    #     for key, value in self.to_dict().items():
+    #         new_key = f"{parent_key}{sep}{key}" if parent_key else key
+    #         if isinstance(value, dict):
+    #             items.extend(self.flatten(new_key, sep=sep).items())
+    #         else:
+    #             items.append((new_key, value))
+    #     return dict(items)
+
+    def plot(self):
+
+        downsample = 100
+        filtered_amplitude_down = self._measured_data.copy()
+        filtered_amplitude_down = filtered_amplitude_down[filtered_amplitude_down.reset_index().index % downsample == 0]
+        # measured_amplitude = self.measured_amplitude.copy()
+        # measured_amplitude = measured_amplitude[
+        #    measured_amplitude.reset_index().index % downsample == 0]  # [240000:300000]
+        # app.run_server(debug=True, port=8050)
+        fig = make_subplots(
+            rows=2, cols=1,
+            subplot_titles=("filtered", "measurement")
+        )
+        fig.append_trace(
+            go.Scatter(
+                x=self._measured_data['wavelength'],
+                y=self._measured_data['amplitude']),
+            row=1, col=1
+        )
+
+        # fig.append_trace(
+        #    go.Scatter(x=measured_amplitude.index, y=measured_amplitude['measurements']),
+        #    row=2, col=1
+        # )
+
+        fig.add_vrect(x0=self.wl_acc_stop, x1=self.wl_dec_start, row=1, col=1,
+                      annotation_text="valid: %s" % self._measurement_length, annotation_position="top left",
+                      fillcolor="green", opacity=0.25, line_width=0)
+
+        # fig.update_layout(title_text=str(self._wafer_nr))
+
+        html = fig.to_html(full_html=False, include_plotlyjs='cdn')
+        # html += '</body></html>'
+
+        with open('p_graph.html', 'a') as f:
+            f.write(html)
+
+        return html
+        # fig.show()
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def enable_print(self, enable: bool = True):
+        self.print_enabled = enable
+
+    def print_m(self, *args, **kwargs):
+        if self.print_enabled:
+            self.logger.info(*args, **kwargs)
+
+
+if __name__ == "__main__":
+    app = QApplication()
+
+    # Load a mat file from E:\03_Simulations\03_Simulations\measurements\Ary1 using scipy
+    setup_logging()
+    # filename = r"E:\03_Simulations\03_Simulations\measurements\Ary1\Ary1_2021-03-10_15-00-00.mat"
+    data1 = SingleMeasuredData.from_mat(
+        r"support/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11.mat"
+    )
+    data1.calulate_all()
+    data1._save_mat_file(r'test.mat')
+
+    data2 = SingleMeasuredData.from_mat_v2(r'test.mat')
+    print("done")
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MatplotlibPlottingHelpers.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MatplotlibPlottingHelpers.py
new file mode 100644
index 0000000000000000000000000000000000000000..0877d48ba056628516fba5707bba7668e2e7b358
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MatplotlibPlottingHelpers.py
@@ -0,0 +1,26 @@
+import numpy as np
+import pandas as pd
+
+import mcpy
+
+
+class MPLPlottingHelper:
+
+    @staticmethod
+    def plt_errorbar_mcsamples(plot_widget, x_values: pd.Series, y_values: pd.Series,
+                               xlable='Wavelength [nm]', ylable='(nm)'):
+        x = x_values
+        #y_values = y_values
+        y = y_values.apply(lambda row: row.mean)
+        err = y_values.apply(lambda row: row.uncertainty.ustd)
+        plot_widget.ax.clear()
+        # Plot the simple line
+        plot_widget.ax.errorbar(x, y, err)
+        #plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+        #plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+        # Scatter plot of the peaks
+        plot_widget.ax.set_xlabel(xlable)
+        plot_widget.ax.set_ylabel(ylable)
+        plot_widget.ax.grid(True)
+
+        plot_widget.canvas.draw()
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasuredDataModel.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasuredDataModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..91a7a2ad1881fec1c6ec3fe9f96447f08c7f4e29
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasuredDataModel.py
@@ -0,0 +1,70 @@
+from PySide6.QtCore import Qt, QAbstractItemModel, QModelIndex, Signal
+import collections
+
+from PySide6.QtGui import QStandardItem
+from PySide6.QtWidgets import QTreeWidgetItem, QTreeWidget
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MeasuredDataTree(QTreeWidget):
+
+    selected_data_changed = Signal(int)
+
+    def __init__(self, measured_data_list: list[SingleMeasuredData]):
+        super().__init__()
+        self.setHeaderLabels(['Name', 'Xin', 'Yin', 'Xout', 'Yout', 'number'])
+        self.grouped_data = {}
+        self.measured_data_list = measured_data_list
+        for it, data in enumerate(self.measured_data_list):
+            if data.wafer_properties.wafer_number not in self.grouped_data:
+                self.grouped_data[data.wafer_properties.wafer_number] = {}
+            if data.wafer_properties.die_number not in self.grouped_data[data.wafer_properties.wafer_number]:
+                self.grouped_data[data.wafer_properties.wafer_number][data.wafer_properties.die_number] = []
+            self.grouped_data[data.wafer_properties.wafer_number][data.wafer_properties.die_number].append((data, it))
+        self.populate_tree()
+
+
+
+
+    def populate_tree(self):
+
+        for wafer, die_dict in self.grouped_data.items():
+            wafer_item = QTreeWidgetItem([f'Wafer {wafer}'])
+            for die, data_list in die_dict.items():
+                die_item = QTreeWidgetItem([f'Die {die}'])
+                for data in data_list:
+                    data, it = data
+                    print(it)
+                    data_item = QTreeWidgetItem([
+                        data.wafer_properties.structure_name,
+                        str(data.wafer_properties.structure_x_in),
+                        str(data.wafer_properties.structure_y_in),
+                        str(data.wafer_properties.structure_x_out),
+                        str(data.wafer_properties.structure_y_out),
+                        str(it)
+                    ])
+                    die_item.addChild(data_item)
+                wafer_item.addChild(die_item)
+            self.addTopLevelItem(wafer_item)
+
+    # def selected_data(self):
+    #     item = self.currentItem()
+    #     if item.parent():
+    #         # Return MeasuredData instance for selected die
+    #         wafer_item = item.parent()
+    #         wafer_num = int(wafer_item.text(0).split()[-1])
+    #         die_num = int(item.text(0).split()[-1])
+    #         for data in self.measured_data_list:
+    #             if data.wafer_number == wafer_num and data.die_number == die_num:
+    #                 return data
+    #     else:
+    #         # Return None for selected wafer
+    #         return None
+
+    def mouseDoubleClickEvent(self, event):
+
+        item = self.currentItem()
+        print(item)
+        if item:
+            self.selected_data_changed.emit(int(item))
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataLoader.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataLoader.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a685ec39967f90049a0412301649b1e7482c589
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataLoader.py
@@ -0,0 +1,132 @@
+import logging
+import time
+from dataclasses import dataclass
+from os import listdir
+from os.path import isfile, join
+from pathlib import Path
+from typing import Dict, Any
+
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import QProgressDialog, QWidget
+
+import MeasurementEvaluationTool as met
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+from wrappers.QProgressBarWindow import QProgressBarWindow
+
+
+class MeasurementDataLoader(QWidget):
+
+    @staticmethod
+    def glob_files(path, glob):
+        """Recursively glob for files in a directory and subdirectories. Returns a list of paths"""
+        # use list comprehension and rglob
+        return [f for f in Path(path).rglob(glob)]
+
+    @classmethod
+    def from_folder(cls, path, to_database):
+        logging.info(f"Opening path {path}")
+        files = MeasurementDataLoader.glob_files(path, "*.mat") #[Path(f"{path}/{f}").absolute() for f in listdir(path) if isfile(join(path, f)) and ".mat" in f]
+        logging.info(f"Found {len(files)}.")
+
+        mea_list = []
+        for i, f, it in QProgressBarWindow(files):
+            it.print(f"Loading measurement {str(f.name)}")
+
+            #try:
+                #mea_list.append(SingleMeasuredData.from_mat_v2(f))
+            to_database.add_data(SingleMeasuredData.from_mat_v2(f))
+            #except Exception as e:
+            #    logging.error(f"Could not load file {f.name}: {e}")
+
+        return cls(mea_list)
+
+    def __init__(self, data: list[SingleMeasuredData]):
+        super().__init__()
+        self._data = data
+        self.logger = logging
+        self._wafers = set()
+        self._dies = set()
+        self._structure_name = set()
+        self._sorted_files = self.classify(self._data)
+        # Now  classify
+
+    @property
+    def structure_name(self) -> set[str]:
+        return self._structure_name
+
+    @property
+    def sorted_files(self) -> dict[str, dict[int, dict[Any, list[SingleMeasuredData]]]]:
+        return self._sorted_files
+
+    @property
+    def dies(self) -> set[int]:
+        return self._dies
+
+    @property
+    def wafers(self) -> set[str]:
+        return self._wafers
+
+    def classify(self, measurement_data: list[SingleMeasuredData]):
+        sorted_files = {}
+        for i, measurement, it in QProgressBarWindow(measurement_data):
+            it.print(f"Classifying {measurement}")
+            self.add_to_list(sorted_files, measurement)
+        return sorted_files
+
+    def get_measurement_series(self, wafer_number=None, die_number=None, structure_name=None) -> list[SingleMeasuredData]:
+        if wafer_number is None and len(self._sorted_files.keys()) > 1:
+            raise Exception(f"Wafer Number is ambiguous ({len(self._sorted_files)} possibilities). "
+                            f"Please specify the wafer number!")
+        elif wafer_number is None:
+            wafer_number = list(self._sorted_files.keys())[0]
+            print(f"Wafer Number is not ambiguous. Selected wafer number {wafer_number}")
+
+        if die_number is None and len(self._sorted_files[wafer_number]) > 1:
+            raise Exception(f"Die Number is ambiguous ({len(self._sorted_files[wafer_number])} possibilities). "
+                            f"Please specify the wafer number!")
+        elif die_number is None:
+            die_number = list(self._sorted_files[wafer_number].keys())[0]
+            print(f"Die Number is not ambiguous. Selected die number {die_number}")
+
+        if structure_name is None and len(self._sorted_files[wafer_number][die_number]) > 1:
+            raise Exception(f"Structure name is ambiguous ({len(self._sorted_files[wafer_number][die_number])} "
+                            f"possibilities). Please specify the structure name!")
+        elif structure_name is None:
+            structure_name = list(self._sorted_files[wafer_number][die_number].keys())[0]
+            print(f"Structure name is not ambiguous. Selected structure name {structure_name}")
+
+        return self._sorted_files[wafer_number][die_number][structure_name]
+
+    def get_measurement(self, repetition, wafer_number=None, die_number=None, structure_name=None, ) -> SingleMeasuredData:
+        return self.get_measurement_series(wafer_number, die_number, structure_name)[repetition]
+
+    def add_to_list(self, sorted_files: dict, measurement: SingleMeasuredData):
+        """
+            Adds a measurement to the measurement list
+        """
+        wafer_number = measurement.wafer_properties.wafer_number
+        die_number = measurement.wafer_properties.die_number
+        structure_name = measurement.wafer_properties.structure_name
+
+
+        if (wafer_number in sorted_files and
+                die_number in sorted_files[wafer_number] and
+                structure_name in sorted_files[wafer_number][die_number]):
+            sorted_files[wafer_number][die_number][structure_name].append(measurement)
+        elif (wafer_number in sorted_files and
+              die_number not in sorted_files[wafer_number]):
+            sorted_files[wafer_number][die_number] = {structure_name: [measurement]}
+        elif (wafer_number in sorted_files and
+              die_number in sorted_files[wafer_number] and
+              structure_name not in sorted_files[wafer_number][die_number]):
+            sorted_files[wafer_number][die_number][structure_name] = [measurement]
+        else:
+            sorted_files[wafer_number] = {die_number: {structure_name: [measurement]}}
+        self._wafers.add(wafer_number)
+        self._dies.add(die_number)
+        self._structure_name.add(structure_name)
+
+if __name__ == "__main__":
+    mypath = r'E:\test_measurements'
+    mm_data = MeasurementDataLoader(mypath)
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataTables.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataTables.py
new file mode 100644
index 0000000000000000000000000000000000000000..5810242617a638facf5de65af75929aa2d283235
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementDataTables.py
@@ -0,0 +1,45 @@
+import pandas as pd
+
+class MeasurementDataTables:
+
+    def __init__(self):
+        self._hidden_friendly_name: dict = {}
+        self._hidden_table_plt_functions: dict = {}
+
+    def append(self, new_table: pd.DataFrame, name, friendly_name=None):
+        if friendly_name is None:
+            friendly_name = name
+        self.__setattr__(name, new_table)
+        self._hidden_friendly_name[name] = friendly_name
+
+        return getattr(self, name)
+
+    def add_plot(self, name, plot_function = None):
+        if plot_function:
+            self._hidden_table_plt_functions[f"{name}"] = plot_function
+        return getattr(self, name)
+
+    def update(self, new_table: pd.DataFrame, name):
+        self.__setattr__(name, new_table)
+        return getattr(self, name)
+
+    def to_list(self) -> list[(pd.DataFrame, str, str)]:
+        # write a function that returns all attributes of this class
+        return [
+            (getattr(self, a), str(a), str(self._hidden_friendly_name[a])) for a in dir(self)
+            if not a.startswith('__')
+               and not callable(getattr(self, a))
+               and not '_hidden' in str(a)
+        ]
+
+    def get(self, table_name: str) -> pd.DataFrame:
+        return getattr(self, table_name)
+
+    def get_plot_function(self, name):
+        return self._hidden_table_plt_functions[name]
+
+    def get_plot_function_names(self):
+        return self._hidden_table_plt_functions.keys()
+
+    def plot(self):
+        pass
diff --git a/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementProperties.py b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..ac931f73649fc750400125673beb850275b87a58
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/MeasuredData/SupportClasses/MeasurementProperties.py
@@ -0,0 +1,203 @@
+import numpy as np
+from PySide6.QtCore import Signal
+
+import mcpy
+from mcpy import Uncertainty
+
+from generics.GenericProperties import GenericProperties
+
+
+class MPropertiesFindPeaks(GenericProperties):
+    properties_changed = Signal()
+
+    def __init__(self, prominence: float | None, distance: float | None, height: float | None):
+        super().__init__()
+        self.set_properties(prominence, distance, height)
+
+    def set_properties(self, prominence: float | None, distance: float | None, height: float | None):
+        self._prominence = prominence
+        self._distance = distance
+        self._height = height
+        self.properties_changed.emit()
+
+    @property
+    def height(self):
+        return self._height
+
+    @height.setter
+    def height(self, value):
+        self._height = value
+        self.properties_changed.emit()
+
+    @property
+    def prominence(self):
+        return self._prominence
+
+    @prominence.setter
+    def prominence(self, value):
+        self._prominence = value
+        self.properties_changed.emit()
+
+    @property
+    def distance(self):
+        return self._distance
+
+    @distance.setter
+    def distance(self, value):
+        self._distance = value
+        self.properties_changed.emit()
+
+    def fields(self) -> dict:
+        return {
+            'prominence':  self.prominence if self.prominence is not None else np.NaN,
+            'distance': self.distance if self.prominence is not None else np.NaN,
+            'height': self.height if self.height is not None else np.NaN,
+        }
+
+    def __str__(self):
+        return f"h: {self.height} - d: {self.distance} - p: {self.prominence}"
+
+
+class WaveguideProperties(GenericProperties):
+    def __init__(self, length: Uncertainty, width: Uncertainty, height: Uncertainty):
+        super().__init__()
+        self._length: Uncertainty = length
+        self._width: Uncertainty = width
+        self._height: Uncertainty = height
+
+    @property
+    def height(self):
+        return self._height
+
+    @height.setter
+    def height(self, value):
+        self._height = value
+
+    @property
+    def length(self):
+        return self._length
+
+    @length.setter
+    def length(self, value):
+        self._length = value
+
+    @property
+    def width(self):
+        return self._width
+
+    @width.setter
+    def width(self, value):
+        self._width = value
+
+    def fields(self) -> dict:
+        return {
+            'width':  self.width.to_tuple(),
+            'length': self.length.to_tuple(),
+            'height': self.height.to_tuple(),
+        }
+
+class WaveguidePropertiesMZI(WaveguideProperties):
+    def __init__(self, length1: Uncertainty, length2: Uncertainty, width: Uncertainty, height: Uncertainty):
+
+        self._arm1 = WaveguideProperties(length1, width, height)
+        self._arm2 = WaveguideProperties(length2, width, height)
+        super().__init__(mcpy.Uncertainty(float(self._arm1.length) - float(self._arm2.length)), width, height)
+
+    @property
+    def length_diff(self):
+        return self._length_diff
+
+    @length_diff.setter
+    def length_diff(self, value):
+        self._length_diff = value
+
+    @property
+    def arm1(self):
+        return self._arm1
+
+    @arm1.setter
+    def arm1(self, value):
+        self._arm1 = value
+
+    @property
+    def arm2(self):
+        return self._arm2
+
+    @arm2.setter
+    def arm2(self, value):
+        self._arm2 = value
+
+    @property
+    def width(self):
+        return self._width
+
+    @width.setter
+    def width(self, value):
+        self._width = value
+
+    def fields(self) -> dict:
+        return {
+            'width':  self.width,
+            'length': self.length,
+            'arm1': self.arm1,
+            'arm2': self.arm2
+        }
+
+class WaveguidePropertiesMRR(WaveguideProperties):
+    def __init__(self, length, width: float, radius, gap: float):
+        super().__init__()
+        super().__init__(length, width)
+        self._radius = radius
+        self._gap = gap
+
+    @property
+    def length_diff(self):
+        return self._length_diff
+
+    @length_diff.setter
+    def length_diff(self, value):
+        self._length_diff = value
+
+    @property
+    def arm1(self):
+        return self._arm1
+
+    @arm1.setter
+    def arm1(self, value):
+        self._arm1 = value
+
+    @property
+    def arm2(self):
+        return self._arm2
+
+    @arm2.setter
+    def arm2(self, value):
+        self._arm2 = value
+
+    @property
+    def width(self):
+        return self._width
+
+    @width.setter
+    def width(self, value):
+        self._width = value
+
+
+class MeasurementProperties(GenericProperties):
+    def __init__(self, find_peaks_properties: MPropertiesFindPeaks):
+        super().__init__()
+        self._find_peaks = find_peaks_properties
+
+    @property
+    def find_peaks(self):
+        return self._find_peaks
+
+    @find_peaks.setter
+    def find_peaks(self, value):
+        self._find_peaks = value
+
+    def fields(self) -> dict:
+        return {
+            'find_peaks': self.find_peaks.fields(),
+            'test': 1
+        }
diff --git a/src/FlexSensor/MeasurementData/Properties/AD2CaptDeviceProperties.py b/src/FlexSensor/MeasurementData/Properties/AD2CaptDeviceProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..231b75c81572eb64175920632ffaeb01129645e7
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/AD2CaptDeviceProperties.py
@@ -0,0 +1,79 @@
+import pandas as pd
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+
+
+class AD2CaptDeviceProperties(GenericProperties):
+
+    def __init__(self, samples_lost: float, samples_corrupted: float,
+                 acquisition_rate: float, n_samples: int,
+                 measurement_time: float):
+        super().__init__()
+        # Laser properties
+        self._samples_lost: float = self.to_float(samples_lost)
+        self._samples_currputed: float = self.to_float(samples_corrupted)
+        self._sample_rate: float = self.to_float(acquisition_rate)
+        self._n_samples: int = self.to_int(n_samples)
+        self._measurement_time: float = self.to_float(measurement_time)
+
+    @property
+    def samples_lost(self):
+            return self._samples_lost
+
+    @samples_lost.setter
+    def samples_lost(self, value):
+            self._samples_lost = value
+
+    @property
+    def samples_corrupted(self):
+            return self._samples_currputed
+
+    @samples_corrupted.setter
+    def samples_corrupted(self, value):
+            self._samples_currputed = value
+
+    @property
+    def n_samples(self):
+            return self._n_samples
+
+    @n_samples.setter
+    def n_samples(self, value):
+            self._n_samples = value
+
+    @property
+    def measurement_time(self):
+            return self._measurement_time
+
+    @measurement_time.setter
+    def measurement_time(self, value):
+            self._measurement_time = value
+
+    @property
+    def sample_rate(self):
+            return self._sample_rate
+
+    @sample_rate.setter
+    def sample_rate(self, value):
+            self._sample_rate = value
+
+
+    def to_dict(self) -> dict:
+        return {
+            'samples_lost': self.samples_lost,
+            'samples_corrupted': self.samples_corrupted,
+            'n_samples': self.n_samples,
+            'measurement_time': self.measurement_time,
+            'acquisition_rate': self.sample_rate
+        }
+
+    @classmethod
+    def from_dict(cls, mat_struct):
+        return cls(
+            samples_lost=mat_struct['samples_lost'],
+            samples_corrupted=mat_struct['samples_corrupted'],
+            acquisition_rate=mat_struct['acquisition_rate'],
+            n_samples=mat_struct['n_samples'],
+            measurement_time=mat_struct['measurement_time']
+        )
+
+
diff --git a/src/FlexSensor/MeasurementData/Properties/GenericProperties.py b/src/FlexSensor/MeasurementData/Properties/GenericProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..a112641f7fc64c3c074917318df0c7cf0fb0e047
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/GenericProperties.py
@@ -0,0 +1,49 @@
+import pandas as pd
+from PySide6.QtCore import QObject
+from numpy import ndarray
+
+class GenericProperties(QObject,):
+
+    def __init__(self):
+
+        super().__init__()
+
+    def to_str(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return self.to_str(value[0])
+        else:
+            return str(value)
+
+    def to_int(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return self.to_int(value[0])
+        else:
+            return int(value)
+
+    def to_float(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return self.to_float(value[0])
+        else:
+            return float(value)
+
+    def to_tuple(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return tuple(value[0])
+        else:
+            return tuple(value)
+
+    def to_dict(self) -> dict:
+        raise NotImplementedError
+
+    @classmethod
+    def from_dict(self, data: dict):
+        raise NotImplementedError
+
+    def to_sql(self, engine):
+        self.metadata.create_all(engine)
+        "Create a  relational table in the database with the given engine"
+        with Session(engine) as session:
+            session.add(self)
+            session.commit()
+        # df = pd.DataFrame(self.to_dict())
+        # df.to_sql(table_name, engine, if_exists='append', index=False)
diff --git a/src/FlexSensor/MeasurementData/Properties/LaserProperties.py b/src/FlexSensor/MeasurementData/Properties/LaserProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b2947cbe02dac59c28b14a3e363be2686c51ab8
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/LaserProperties.py
@@ -0,0 +1,68 @@
+import sys
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+import mcpy
+
+sys.path.append('../mcpy/mcpy')
+import mcpy
+
+
+class LaserProperties(GenericProperties):
+
+    def __init__(self, acceleration: mcpy.Uncertainty, deceleration: mcpy.Uncertainty, velocity: mcpy.Uncertainty,
+                 wavelength_range: tuple):
+        super().__init__()
+        # Laser properties
+        self._acceleration: mcpy.Uncertainty = acceleration
+        self._deceleration: mcpy.Uncertainty = deceleration
+        self._velocity: mcpy.Uncertainty = velocity
+        self._wavelength_range: list | tuple = wavelength_range
+
+    @property
+    def deceleration(self) -> mcpy.Uncertainty:
+        return self._deceleration
+
+    @deceleration.setter
+    def deceleration(self, value):
+        self._deceleration = value
+
+    @property
+    def velocity(self) -> mcpy.Uncertainty:
+        return self._velocity
+
+    @velocity.setter
+    def velocity(self, value):
+        self._velocity = value
+
+    @property
+    def wavelength_range(self) -> mcpy.Uncertainty:
+        return self._wavelength_range
+
+    @wavelength_range.setter
+    def wavelength_range(self, value):
+        self._wavelength_range = value
+
+    @property
+    def acceleration(self) -> mcpy.Uncertainty:
+        return self._acceleration
+
+    @acceleration.setter
+    def acceleration(self, value):
+        self._acceleration = value
+
+    def to_dict(self) -> dict:
+        return {
+            'deceleration': 1.997,#float(self.deceleration),
+            'velocity': 1.002,#float(self.velocity),
+            'wavelength_range': [840, 860],  # .to_tuple(),
+            'acceleration': 1.997 #float(self.acceleration)
+        }
+
+    @classmethod
+    def from_dict(cls, d):
+        return cls(
+            acceleration=mcpy.Uncertainty.from_dict(d['acceleration']),
+            deceleration=mcpy.Uncertainty.from_dict(d['deceleration']),
+            velocity=mcpy.Uncertainty.from_dict(d['deceleration']),
+            wavelength_range=()
+        )
diff --git a/src/FlexSensor/MeasurementData/Properties/MeasurementProperties.py b/src/FlexSensor/MeasurementData/Properties/MeasurementProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..12d544401fb913e439ae3a36cd30743c0472ca0c
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/MeasurementProperties.py
@@ -0,0 +1,247 @@
+import numpy as np
+from PySide6.QtCore import Signal
+
+import mcpy
+from mcpy import Uncertainty, MCSamples
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+
+
+class MPropertiesFindPeaks(GenericProperties):
+
+
+    properties_changed = Signal()
+
+    def __init__(self, prominence: float | None, distance: float | None, height: float | None):
+        super().__init__()
+        self.set_properties(prominence, distance, height)
+
+    def set_properties(self, prominence: float | None, distance: float | None, height: float | None):
+        self._prominence = prominence
+        self._distance = distance
+        self._height = height
+        self.properties_changed.emit()
+
+    @property
+    def height(self):
+        return self._height
+
+    @height.setter
+    def height(self, value):
+        self._height = value
+        self.properties_changed.emit()
+
+    @property
+    def prominence(self):
+        return self._prominence
+
+    @prominence.setter
+    def prominence(self, value):
+        self._prominence = value
+        self.properties_changed.emit()
+
+    @property
+    def distance(self):
+        return self._distance
+
+    @distance.setter
+    def distance(self, value):
+        self._distance = value
+        self.properties_changed.emit()
+
+    def to_dict(self) -> dict:
+        return {
+            'prominence': self.prominence if self.prominence is not None else np.NaN,
+            'distance': self.distance if self.prominence is not None else np.NaN,
+            'height': self.height if self.height is not None else np.NaN,
+        }
+
+    @classmethod
+    def from_dict(cls, data: dict):
+        return cls(
+            data['prominence'] if not np.isnan(data['prominence']) else None,
+            data['distance'] if not np.isnan(data['distance']) else None,
+            data['height'] if not np.isnan(data['height']) else None
+        )
+
+    def __str__(self):
+        return f"h: {self.height} - d: {self.distance} - p: {self.prominence}"
+
+
+class WaveguideProperties(GenericProperties):
+
+    def __init__(self, length: Uncertainty, width: Uncertainty, height: Uncertainty):
+        super().__init__()
+        self._length: Uncertainty = length
+        self._width: Uncertainty = width
+        self._height: Uncertainty = height
+
+    def group_index(self, lam0: MCSamples, FSR: MCSamples):
+        return (lam0 ** 2) / (FSR * self._length)
+
+    @property
+    def height(self):
+        return self._height
+
+    @height.setter
+    def height(self, value):
+        self._height = value
+
+    @property
+    def length(self):
+        return self._length
+
+    @length.setter
+    def length(self, value):
+        self._length = value
+
+    @property
+    def width(self):
+        return self._width
+
+    @width.setter
+    def width(self, value):
+        self._width = value
+
+    def to_dict(self) -> dict:
+        return {
+            'width': self.width.to_dict(),
+            'length': self.length.to_dict(),
+            'height': self.height.to_dict(),
+        }
+
+    @classmethod
+    def from_dict(cls, data: dict):
+        return cls(
+            Uncertainty.from_dict(data['length']),
+            Uncertainty.from_dict(data['width']),
+            Uncertainty.from_dict(data['height'])
+        )
+
+
+class WaveguidePropertiesMZI(WaveguideProperties):
+
+
+    def __init__(self, length1: Uncertainty, length2: Uncertainty, width: Uncertainty, height: Uncertainty):
+        self._arm1 = WaveguideProperties(length1, width, height)
+        self._arm2 = WaveguideProperties(length2, width, height)
+        super().__init__(mcpy.Uncertainty(float(self._arm1.length) - float(self._arm2.length)), width, height)
+
+    def group_index(self, lam0: MCSamples, FSR: MCSamples):
+        return (lam0 ** 2) / (FSR * (self.arm2.length.rand(lam0.N) -
+                                     self.arm1.length.rand(lam0.N)))
+
+    @property
+    def length_diff(self):
+        return self._length_diff
+
+    @length_diff.setter
+    def length_diff(self, value):
+        self._length_diff = value
+
+    @property
+    def arm1(self):
+        return self._arm1
+
+    @arm1.setter
+    def arm1(self, value):
+        self._arm1 = value
+
+    @property
+    def arm2(self):
+        return self._arm2
+
+    @arm2.setter
+    def arm2(self, value):
+        self._arm2 = value
+
+    @property
+    def width(self):
+        return self._width
+
+    @width.setter
+    def width(self, value):
+        self._width = value
+
+    def to_dict(self) -> dict:
+        return {
+            'width': self.width.to_dict(),
+            'length': self.length.to_dict(),
+            'arm1': self.arm1.to_dict(),
+            'arm2': self.arm2.to_dict(),
+            'height': self.height.to_dict(),
+        }
+
+    @classmethod
+    def from_dict(cls, data: dict):
+        return cls(
+            length1=mcpy.Uncertainty.from_dict(data['arm1']['length']),
+            length2=Uncertainty.from_dict(data['arm2']['length']),
+            width=Uncertainty.from_dict(data['width']),
+            height=Uncertainty.from_dict(data['height'])
+        )
+
+
+class WaveguidePropertiesMRR(WaveguideProperties):
+    def __init__(self, length, width: float, radius, gap: float):
+        super().__init__()
+        super().__init__(length, width)
+        self._radius = radius
+        self._gap = gap
+
+    @property
+    def length_diff(self):
+        return self._length_diff
+
+    @length_diff.setter
+    def length_diff(self, value):
+        self._length_diff = value
+
+    @property
+    def arm1(self):
+        return self._arm1
+
+    @arm1.setter
+    def arm1(self, value):
+        self._arm1 = value
+
+    @property
+    def arm2(self):
+        return self._arm2
+
+    @arm2.setter
+    def arm2(self, value):
+        self._arm2 = value
+
+    @property
+    def width(self):
+        return self._width
+
+    @width.setter
+    def width(self, value):
+        self._width = value
+
+
+class MeasurementProperties(GenericProperties):
+    def __init__(self, find_peaks_properties: MPropertiesFindPeaks):
+        super().__init__()
+        self._find_peaks = find_peaks_properties
+
+    @property
+    def find_peaks(self):
+        return self._find_peaks
+
+    @find_peaks.setter
+    def find_peaks(self, value):
+        self._find_peaks = value
+
+    def to_dict(self) -> dict:
+        return {
+            'find_peaks': self.find_peaks.to_dict(),
+        }
+
+    @classmethod
+    def from_dict(cls, d: dict):
+        return cls(
+            find_peaks_properties=MPropertiesFindPeaks.from_dict(d['find_peaks'])
+        )
diff --git a/src/FlexSensor/MeasurementData/Properties/WaferProperties.py b/src/FlexSensor/MeasurementData/Properties/WaferProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..546de51e3e227faafd3c2a2b8e9f750eb8a95135
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/Properties/WaferProperties.py
@@ -0,0 +1,108 @@
+
+
+from MeasurementData.Properties.GenericProperties import GenericProperties
+
+
+class WaferProperties(GenericProperties):
+
+
+    def __init__(self,
+                 wafer_number: str, structure_name: str,
+                 die_nr: int, chuck_col: int, chuck_row: int,
+                 structure_in: tuple, structure_out: tuple,
+                 repetitions: int
+                 ):
+        super().__init__()
+        self._structure_name = self.to_str(structure_name)
+        self._wafer_number = self.to_str(wafer_number)
+
+        self._die_number = self.to_int(die_nr)
+        self._chuck_col = self.to_int(chuck_col)
+        self._chuck_row = self.to_int(chuck_row)
+
+        self._structure_in = self.to_tuple(structure_in)
+        self._structure_out = self.to_tuple(structure_out)
+        self._structure_x_in = int(self._structure_in[0])
+        self._structure_y_in = int(self._structure_in[1])
+        self._structure_x_out = int(self._structure_out[0])
+        self._structure_y_out = int(self._structure_out[1])
+
+        self._repetitions: int = self.to_int(repetitions)
+
+    @property
+    def repetition(self):
+        return int(self._repetitions)
+
+    @property
+    def chuck_col(self):
+        return int(self._chuck_col)
+
+    @property
+    def chuck_row(self):
+        return int(self._chuck_row)
+
+    @property
+    def wafer_number(self) -> str:
+        return str(self._wafer_number)
+
+    @property
+    def structure_x_in(self):
+        return int(self._structure_x_in)
+
+    @property
+    def structure_y_in(self):
+        return int(self._structure_y_in)
+
+    @property
+    def structure_x_out(self):
+        return int(self._structure_x_out)
+
+    @property
+    def structure_name(self):
+        return str(self._structure_name)
+
+    @property
+    def die_number(self) -> int:
+        return int(self._die_number)
+
+    @property
+    def structure_y_out(self):
+        return int(self._structure_y_out)
+
+    @property
+    def structure_in(self):
+        return tuple(self._structure_in)
+
+    @property
+    def structure_out(self):
+        return tuple(self._structure_out)
+
+    @property
+    def chuck_row(self):
+        return int(self._chuck_row)
+
+    def to_dict(self) -> dict:
+        return {
+            'wafer_number': self.wafer_number,
+            'die_number': self.die_number,
+            'structure_name': self.structure_name,
+            'repetition': self.repetition,
+            'structure_in': self.structure_in,
+            'structure_out': self.structure_out,
+            'chuck_col': self.chuck_col,
+            'chuck_row': self.chuck_row
+
+        }
+
+    @classmethod
+    def from_dict(cls, d: dict):
+        return cls(
+            wafer_number=d['wafer_number'],
+            die_nr=d['die_number'],
+            structure_name=d['structure_name'],
+            repetitions=d['repetition'],
+            structure_in=d['structure_in'],
+            structure_out=d['structure_out'],
+            chuck_col=d['chuck_col'],
+            chuck_row=d['chuck_row']
+        )
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementData/__init__.py b/src/FlexSensor/MeasurementData/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MeasurementData/tests/testfiles/load_all.m b/src/FlexSensor/MeasurementData/tests/testfiles/load_all.m
new file mode 100644
index 0000000000000000000000000000000000000000..a9d12a2e008e05484775aafe784af9ec0083869d
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/tests/testfiles/load_all.m
@@ -0,0 +1 @@
+load('testfiles/load_all.m');data = readcsv('None');
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementData/tests/tmp/load_all.m b/src/FlexSensor/MeasurementData/tests/tmp/load_all.m
new file mode 100644
index 0000000000000000000000000000000000000000..284260549b90723aa2dbb4c94100899496cae33b
--- /dev/null
+++ b/src/FlexSensor/MeasurementData/tests/tmp/load_all.m
@@ -0,0 +1 @@
+load('tmp/load_all.m');data = readcsv('None');
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementData/tests/tmp/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11_v2.mat b/src/FlexSensor/MeasurementData/tests/tmp/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11_v2.mat
new file mode 100644
index 0000000000000000000000000000000000000000..473d79a9bb81268364028c942632ce50b113c153
Binary files /dev/null and b/src/FlexSensor/MeasurementData/tests/tmp/measurement_die_22_struct_mzi2_2_20220306_1908_rep_11_v2.mat differ
diff --git a/src/FlexSensor/MeasurementData/tests/tmp/measurement_v2.mat b/src/FlexSensor/MeasurementData/tests/tmp/measurement_v2.mat
new file mode 100644
index 0000000000000000000000000000000000000000..8203321366c3ffb60ee771c18c3590fd34b3b80e
Binary files /dev/null and b/src/FlexSensor/MeasurementData/tests/tmp/measurement_v2.mat differ
diff --git a/src/FlexSensor/MeasurementEvaluation/__init__.py b/src/FlexSensor/MeasurementEvaluation/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MeasurementEvaluation/controller/MeasurementDataController.py b/src/FlexSensor/MeasurementEvaluation/controller/MeasurementDataController.py
new file mode 100644
index 0000000000000000000000000000000000000000..73305f7e40f55557c8e46576c25139ebb344bfe7
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/controller/MeasurementDataController.py
@@ -0,0 +1,60 @@
+import logging
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader
+from MeasurementEvaluation.model.MeasurementDataModel import MeasurementDataModel
+
+
+class MeasurementDataController:
+
+    def __init__(self, model: MeasurementDataModel, path):
+        self.logger = logging.getLogger("MeasurementDataController")
+        self._model = model
+
+        self._model.path = path
+        self._md_loader = MeasurementDataLoader.from_folder(self._model.path)
+
+        self._model.selected_measurements = []
+        self._model.measurement_list = self._md_loader.sorted_files
+
+
+    @property
+    def consolidated_measurements(self):
+        return self._consolidated_measurements
+
+    @consolidated_measurements.setter
+    def consolidated_measurements(self, value):
+        self._consolidated_measurements = value
+
+    @property
+    def all_measurements(self):
+        return self._model.measurement_list
+
+    @property
+    def list_of_measurements(self) -> list[SingleMeasuredData]:
+        return self._model.selected_measurements
+
+    @property
+    def selected_measurement(self) -> SingleMeasuredData:
+        return self._model.display_measurement
+
+    def select_measurement(self, selected_measurement: MeasuredData):
+        self._model.display_measurement = selected_measurement
+
+    def consolidate_measurements(self, measurement_selection):
+        self._model.consolidated_measurement = MultiMeasuredData(measurement_selection)
+        self._model.selected_measurements = measurement_selection
+        self.select_measurement(self._model.consolidated_measurement)
+
+    def recalculate_measurements(self, measurement_selection):
+        self.logger.info("Recalculating all measurements")
+        for md in measurement_selection:
+            md.calulate_all()
+
+    def load_from_folder(self):
+        raise NotImplementedError
+
+    def add_measurement(self):
+        pass
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluation/model/MeasurementDataModel.py b/src/FlexSensor/MeasurementEvaluation/model/MeasurementDataModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e55e292e0343f0eb2bda1a50bca42cff13b8950
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/model/MeasurementDataModel.py
@@ -0,0 +1,85 @@
+from pathlib import Path
+
+from PySide6.QtCore import Signal, QObject
+
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MeasuredDataSignals(QObject):
+    path_changed = Signal(Path)
+
+    list_of_measurements_changed = Signal(list)
+    all_measurements_changed = Signal(dict)
+
+    num_of_measurements = Signal(int)
+    selected_measurement_changed = Signal(SingleMeasuredData)
+    consolidated_measurements_changed = Signal(MultiMeasuredData)
+
+
+class MeasurementDataModel:
+    def __init__(self):
+        self.signals = MeasuredDataSignals()
+
+        self._path: Path = None
+        self._measurement_list: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = None
+
+        self._consolidated_measurement: MultiMeasuredData = None
+        self._display_measurement: SingleMeasuredData = None
+        self._selected_measurements: list[SingleMeasuredData] = []
+
+        self._num_of_measurements: int = 0
+
+    @property
+    def consolidated_measurement(self):
+        return self._consolidated_measurement
+
+    @consolidated_measurement.setter
+    def consolidated_measurement(self, value):
+        self._consolidated_measurement = value
+
+    @property
+    def path(self):
+        return self._path
+
+    @path.setter
+    def path(self, value):
+        self._path = value
+        self.signals.path_changed.emit(self.path)
+
+    @property
+    def measurement_list(self) -> dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]:
+        return self._measurement_list
+
+    @measurement_list.setter
+    def measurement_list(self, value: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]) -> None:
+        self._measurement_list = value
+        self.signals.all_measurements_changed.emit(self.measurement_list)
+
+    @property
+    def selected_measurements(self) -> list[SingleMeasuredData]:
+        return self._selected_measurements
+
+    @selected_measurements.setter
+    def selected_measurements(self, value: list[SingleMeasuredData]) -> None:
+        self._selected_measurements = value
+        self.num_of_measurements = len(self.selected_measurements)
+        self.signals.list_of_measurements_changed.emit(self.selected_measurements)
+
+    @property
+    def num_of_measurements(self) -> int:
+        return self._num_of_measurements
+
+    @num_of_measurements.setter
+    def num_of_measurements(self, value: list[SingleMeasuredData]) -> None:
+        self._num_of_measurements = value
+        self.signals.num_of_measurements.emit(self.num_of_measurements)
+
+    @property
+    def display_measurement(self) -> SingleMeasuredData:
+        return self._display_measurement
+
+    @display_measurement.setter
+    def display_measurement(self, value: SingleMeasuredData) -> None:
+        self._display_measurement = value
+        self.signals.selected_measurement_changed.emit(self.display_measurement)
diff --git a/src/FlexSensor/MeasurementEvaluation/model/PandasTableModel.py b/src/FlexSensor/MeasurementEvaluation/model/PandasTableModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c199832356abb7b39b9e08cf59a4ab742535720
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/model/PandasTableModel.py
@@ -0,0 +1,30 @@
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QMenu
+
+
+class PandasTableModel(QAbstractTableModel):
+    def __init__(self, df):
+        super().__init__()
+        self.df = df
+
+    def rowCount(self, parent=None):
+        return self.df.shape[0]
+
+    def columnCount(self, parent=None):
+
+        return self.df.shape[1]
+
+    def data(self, index, role=Qt.DisplayRole):
+        if role == Qt.DisplayRole:
+            row = index.row()
+            col = index.column()
+            return str(self.df.iloc[row, col])
+        return None
+
+    def headerData(self, section, orientation, role=Qt.DisplayRole):
+        if role == Qt.DisplayRole:
+            if orientation == Qt.Horizontal:
+                return str(self.df.columns[section])
+            elif orientation == Qt.Vertical:
+                return str(self.df.index[section])
+        return None
diff --git a/src/FlexSensor/MeasurementEvaluation/view/MeasurementDataView.py b/src/FlexSensor/MeasurementEvaluation/view/MeasurementDataView.py
new file mode 100644
index 0000000000000000000000000000000000000000..940431b847253567a469bca7de5931bc8539e0d7
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/MeasurementDataView.py
@@ -0,0 +1,159 @@
+import sys
+
+import numpy as np
+from PySide6.QtWidgets import QApplication, QWidget, QTableView, \
+    QComboBox, QPushButton, QGridLayout
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementEvaluation.controller.MeasurementDataController import MeasurementDataController
+from MeasurementEvaluation.model.MeasurementDataModel import MeasurementDataModel
+from MeasurementEvaluation.model.PandasTableModel import PandasTableModel
+from MeasurementData.MeasuredData.SupportClasses.MatplotlibPlottingHelpers import MPLPlottingHelper
+from MeasurementEvaluation.view.ParameterAdjustmentView import ParameterAdjustmentWindow
+from MeasurementEvaluation.view.widgets.MeasurementSelectionWidget import MeasurementSelectionWidget
+from MeasurementEvaluation.view.widgets.PlotViewWidget import PlotViewWidget
+from generics.logger import setup_logging
+
+
+class MeasurementDataView(QWidget):
+    def __init__(self, model: MeasurementDataModel, controller: MeasurementDataController):
+        super().__init__()
+        self._model = model
+        self._controller = controller
+        self.layout = QGridLayout()
+
+        self._model.signals.selected_measurement_changed.connect(self._on_selected_measurement_changed)
+
+        self._init_ui()
+
+    def _init_ui(self):
+        self.find_peaks_view = ParameterAdjustmentWindow()
+
+        # Add a view for selecting the measurement
+        self.measurement_selection = MeasurementSelectionWidget(self._controller.all_measurements)
+
+        self.measurement_selection.signals.open_find_peaks_window.connect(self._on_adapt_parameters_clicked)
+        self.measurement_selection.signals.on_consolidate_measurement_clicked.connect(self._on_consolidate_clicked)
+        self.measurement_selection.signals.on_recalculation_clicked.connect(self._on_recalculate_clicked)
+        self.measurement_selection.signals.on_show_item_click.connect(self._on_show_item_clicked)
+
+        # self.measurement_selection.selection.selected_data_changed.connect(self._on_selection_changed)
+        self.layout.addWidget(self.measurement_selection, 0, 0, 2, 1)
+
+        self.plot_widget = PlotViewWidget()  # pg.PlotWidget()
+        self.layout.addWidget(self.plot_widget, 0, 1, 1, 1)
+
+        # Display the data in an QTableWidget
+        self.table_view = QTableView()
+        self.layout.addWidget(self.table_view, 1, 1, 1, 1)
+
+        # Add a dropdown
+        self.btn_consolidate = QPushButton('Consolidate all')
+        self.btn_consolidate.clicked.connect(self._on_consolidate_clicked)
+        self.layout.addWidget(self.btn_consolidate, 2, 0, 1, 1)
+
+        self.dd_select_measurement_table = QComboBox()
+        self.dd_select_measurement_table.currentIndexChanged.connect(self._on_data_table_changed)
+        self.layout.addWidget(self.dd_select_measurement_table, 2, 1, 1, 1)
+
+        self.setLayout(self.layout)
+        # self._controller.select_measurement(0)
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def _on_show_item_clicked(self, measurement_selection: SingleMeasuredData):
+        measurement_selection.calulate_all()
+        self._controller.select_measurement(measurement_selection)
+
+    def _on_consolidate_clicked(self, measurement_selection):
+        self._controller.recalculate_measurements(measurement_selection)
+        self._controller.consolidate_measurements(measurement_selection)
+        # self._current_measurement = self._controller.consolidated_measurements
+
+    def _on_recalculate_clicked(self, measurement_selection):
+        self._controller.recalculate_measurements(measurement_selection)
+
+    def _on_adapt_parameters_clicked(self, measurement_selection):
+        self.find_peaks_view.measured_data_list = measurement_selection
+        self.find_peaks_view.show()
+
+    def _on_selection_changed(self, it: int):
+        # self._controller.select_measurement(it)
+        self.measurement_selection.set_selected_data(self._controller.selected_measurement)
+
+    def _on_data_table_changed(self, idx):
+        table_name = self.dd_select_measurement_table.itemData(idx)
+        print(f"{table_name} - {type(table_name)}")
+        # print(self._current_measurement.tables.get(table_name))
+        table = self._controller.selected_measurement.tables.get(table_name)
+        # Define plt function here
+        self.table_view_model = PandasTableModel(table)
+        self.table_view.setModel(self.table_view_model)
+
+        # This will be removed later and is only for quick and dirty hardcoded plotting
+        if table_name == "_measured_data":
+            pass
+        #    self._plot_measurement_table(table_name)
+        elif table_name == "_wg_param":
+            self._controller.selected_measurement.tables.get_plot_function('ng (FSR)')(self.plot_widget)
+
+            #self._plot_ng_table(table_name)
+
+    def _on_selected_measurement_changed(self, measurement: MeasurementData):
+        self._current_measurement = measurement
+        # Populate the measurement ment selection
+        self.dd_select_measurement_table.clear()
+        for table in measurement.tables.to_list():
+            # id in table -> table[2] = 'Friendly name', table[1] = 'table name'
+            self.dd_select_measurement_table.addItem(table[2], table[1])
+        #self.dd_select_measurement_table.addItem( measurement.tables.to_list()[2][2], table[2][1])
+
+    # ==================================================================================================================
+    #
+    # =============================================================================================================
+    def _plot_measurement_table(self, table_name, x_axis="wavelength", y_axis="detrend"):
+        self.plot_widget.ax.clear()
+        data = self._controller.selected_measurement.tables.get(table_name)
+        self.plot_widget.ax.plot(data[x_axis], data[y_axis], 'b-')[0]
+        self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+        self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+        # Scatter plot of the peaks
+        df_peaks = self._current_measurement.peaks
+        self.plot_widget.ax.scatter(df_peaks[x_axis], df_peaks[y_axis], marker='x', color='red')
+        self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+        self.plot_widget.ax.set_ylabel('Amplitude [1]')
+        self.plot_widget.ax.set_title('Measured data')
+        self.plot_widget.ax.grid(True)
+        self.plot_widget.ax.legend([y_axis, 'Peaks'])
+
+        self.plot_widget.canvas.draw()
+
+    def _plot_ng_table(self, table_name, x_axis="lambda", y_axis="FSR"):
+        self.plot_widget.ax.clear()
+        data = self._controller.selected_measurement.tables.get(table_name)
+        self.plot_widget.ax.plot(data[x_axis], data[y_axis])
+        self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+        self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+        # Scatter plot of the peaks
+        self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+        self.plot_widget.ax.set_ylabel(f'{y_axis} [1]')
+        self.plot_widget.ax.grid(True)
+
+        self.plot_widget.canvas.draw()
+
+
+if __name__ == "__main__":
+    app = QApplication()
+    setup_logging()
+
+    mypath = (
+        r'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement')
+
+    model = MeasurementDataModel()
+    controller = MeasurementDataController(model, mypath)
+    window = MeasurementDataView(model, controller)
+    window.show()
+
+    sys.exit(app.exec())
diff --git a/src/FlexSensor/MeasurementEvaluation/view/ParameterAdjustmentView.py b/src/FlexSensor/MeasurementEvaluation/view/ParameterAdjustmentView.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef897e8942be25b5fd3f0eabbf37ca931e3071b7
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/ParameterAdjustmentView.py
@@ -0,0 +1,167 @@
+from PySide6.QtWidgets import QLineEdit, QPushButton
+from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
+                               QWidget, QLabel, QSlider, QComboBox)
+from PySide6.QtCore import Qt, Signal
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+import pyqtgraph as pg
+
+from MeasurementEvaluation.view.widgets.MeasuredDataInformationWidget import MeasuredDataInformationWidget
+
+
+class ParameterAdjustmentWindow(QMainWindow):
+
+    def __init__(self):
+        super().__init__()
+        self._current_measurement = None
+        self._measured_data_list = None
+
+        self.setWindowTitle("Find Peaks Demo")
+
+        layout = QVBoxLayout()
+        self.measurement_selection = QComboBox()
+        layout.addWidget(self.measurement_selection)
+
+        self._find_peaks_wdg = ParameterAdjustmentWidget()
+        self._find_peaks_wdg.apply_fp_param_to_all_clicked.connect(self._on_apply_to_all)
+
+        layout.addWidget(self._find_peaks_wdg)
+        widget = QWidget()
+        widget.setLayout(layout)
+
+        self.setCentralWidget(widget)
+
+    @property
+    def current_measurement(self):
+        return self._current_measurement
+
+    @current_measurement.setter
+    def current_measurement(self, value):
+        self._current_measurement = value
+        self._find_peaks_wdg.measured_data = self.current_measurement
+
+    @property
+    def measured_data_list(self):
+        return self._measured_data_list
+
+    @measured_data_list.setter
+    def measured_data_list(self, value):
+        self._measured_data_list = value
+        self.current_measurement = self._measured_data_list[0]
+        for i, md in enumerate(self._measured_data_list):
+            self.measurement_selection.addItem(str(md))
+        self.measurement_selection.currentIndexChanged.connect(self._on_measurement_changed)
+
+    def _on_apply_to_all(self, prominence, distance):
+        for md in self._measured_data_list:
+            md.measurement_properties.find_peaks.set_properties(prominence,distance,None)
+
+    def _on_measurement_changed(self, index):
+        self.current_measurement = self._measured_data_list[index]
+
+
+class ParameterAdjustmentWidget(QWidget):
+    apply_fp_param_to_all_clicked = Signal(float, float)
+
+    def __init__(self):
+        super().__init__()
+        self._measured_data: SingleMeasuredData = None
+        # Create the numpy array
+        self._init_ui()
+
+    @property
+    def measured_data(self):
+        return self._measured_data
+
+    @measured_data.setter
+    def measured_data(self, value):
+        self._measured_data = value
+        self.x = self._measured_data.tables.get('_measured_data')['wavelength']
+        self.y = self._measured_data.tables.get('_measured_data')['amplitude']
+        self.prom_slider.setValue(
+            self._measured_data.measurement_properties.find_peaks.prominence * 100)
+        self.dist_slider.setValue(
+            int(self._measured_data.measurement_properties.find_peaks.distance/10))
+
+        self.dist_slider.setRange(1, len(self.x))
+        self.update_plot()
+
+    def _init_ui(self):
+        # Create the plot widget
+        self.plot_widget = pg.PlotWidget()
+
+        # Create the sliders
+        self.prom_slider = QSlider(Qt.Horizontal)
+        self.prom_slider.setRange(0, 100)
+        #
+        self.prom_slider.setTickInterval(5)
+        self.prom_slider.setTickPosition(QSlider.TicksBelow)
+        self.prom_slider.sliderMoved.connect(self.update_plot)
+        self.edit_prom = QLineEdit(str(self.prom_slider.value()))
+
+        self.dist_slider = QSlider(Qt.Horizontal)
+
+        #
+        self.dist_slider.setTickInterval(100)
+        self.dist_slider.setTickPosition(QSlider.TicksBelow)
+        self.dist_slider.sliderMoved.connect(self.update_plot)
+        self.edit_dist = QLineEdit(str(self.dist_slider.value()))
+
+        self.btn_apply_to_all = QPushButton('Apply to all')
+        self.btn_apply_to_all.clicked.connect(
+            lambda: self.apply_fp_param_to_all_clicked.emit(
+                self.prom_slider.value() / 100,
+                self.dist_slider.value()
+            )
+        )
+        # Create the layout
+        prom_layout = QHBoxLayout()
+        prom_layout.addWidget(QLabel("Prominence:"))
+        prom_layout.addWidget(self.prom_slider)
+        prom_layout.addWidget(self.edit_prom)
+
+        dist_layout = QHBoxLayout()
+        dist_layout.addWidget(QLabel("Distance:"))
+        dist_layout.addWidget(self.dist_slider)
+        dist_layout.addWidget(self.edit_dist)
+
+        layout = QVBoxLayout()
+        layout.addWidget(self.plot_widget)
+        self.wdg_measured_information = MeasuredDataInformationWidget(self._measured_data)
+        layout.addWidget(self.wdg_measured_information)
+        layout.addLayout(prom_layout)
+        layout.addLayout(dist_layout)
+        layout.addWidget(self.btn_apply_to_all)
+        self.setLayout(layout)
+
+    def update_plot(self):
+        # Update the prominence and distance values
+        prom = self.prom_slider.value() / 100
+        dist = self.dist_slider.value()
+        self.wdg_measured_information.measurement_data = self.measured_data
+        # Update the peaks
+        self._measured_data.measurement_properties.find_peaks.prominence = prom
+        self._measured_data.measurement_properties.find_peaks.distance = dist
+
+        peaks_wl = self._measured_data.tables.get('_peaks')['wavelength']
+        peaks_amplitude = self._measured_data.tables.get('_peaks')['amplitude']
+        self.edit_dist.setText(str(dist))
+        self.edit_prom.setText(str(prom))
+
+        self.plot_widget.clear()
+        self.plot_widget.plot(self.x.to_list(), self.y.to_list())
+        self.plot_widget.plot(peaks_wl.to_list(), peaks_amplitude.to_list(), pen=None, symbol="o")
+
+
+if __name__ == "__main__":
+    app = QApplication([])
+
+    mypath = r'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement_small'
+    mm_data = MeasurementDataLoader.from_folder(mypath)
+    # matfile = mm_data.get_measurement(repetition=1, structure_name='mzi2-2')
+    matfiles = mm_data.get_measurement_series(structure_name='mzi2-2')
+    # matfile = SingleMeasuredData.from_mat(Path(f"{mypath}\measurement_die_22_struct_mzi2_2_20220306_1908_rep_2.mat"))
+    window = ParameterAdjustmentWindow(matfiles)
+    window.show()
+    app.exec_()
diff --git a/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasuredDataInformationWidget.py b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasuredDataInformationWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..00e6ff908e2558e810e25810dc2b031a024c2bb1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasuredDataInformationWidget.py
@@ -0,0 +1,63 @@
+import numpy as np
+from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QGroupBox, QHBoxLayout, QGridLayout
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+
+
+class MeasuredDataInformationWidget(QGroupBox):
+    def __init__(self, measured_data: MeasuredData):
+        super().__init__()
+
+        self._wafer_number = "unknown"
+        self._die_number = "unknown"
+        self._structure_name = "unknown"
+        self._repetition = "unknown"
+        self._timestamp = "unknown"
+        self._measurement_time = 0
+        self._init_ui()
+        self.measurement_data = measured_data
+
+    def _init_ui(self):
+        # Create QLabel widgets to display the information
+        layout = QGridLayout()
+        self.wafer_label = QLabel()
+        self.die_label = QLabel()
+        self.structure_label = QLabel()
+        layout.addWidget(self.wafer_label, 0, 0)
+        layout.addWidget(self.die_label, 0, 1)
+        layout.addWidget(self.structure_label, 0, 2)
+
+        self.repetition_label = QLabel()
+        self.timestamp_label = QLabel()
+        self.measurement_time_label = QLabel()
+        layout.addWidget(self.repetition_label, 1, 0)
+        layout.addWidget(self.timestamp_label, 1, 1)
+        layout.addWidget(self.measurement_time_label, 1, 2)
+
+        # Create a vertical layout to arrange the QLabel widgets
+
+        # Set the layout for the group box
+        self.setLayout(layout)
+
+    @property
+    def measurement_data(self):
+        return self._measurement_data
+
+    @measurement_data.setter
+    def measurement_data(self, value):
+        if value is not None:
+            self._measurement_data = value
+            self._wafer_number = self._measurement_data.wafer_properties.wafer_number
+            self._die_number = self._measurement_data.wafer_properties.die_number
+            self._structure_name = self._measurement_data.wafer_properties.structure_name
+            self._repetition = self._measurement_data.wafer_properties.repetition
+            self._timestamp = "none"
+            self._measurement_time = self._measurement_data.ad2_properties.measurement_time
+
+        self.wafer_label.setText(f'Wafer Number: {self._wafer_number}')
+        self.die_label.setText(f'Die Number: {self._die_number}')
+        self.structure_label.setText(f'Structure Name: {self._structure_name}')
+        self.repetition_label.setText(f'Repetition: {self._repetition}')
+        self.timestamp_label.setText(f'Timestamp: {self._timestamp}')
+        self.measurement_time_label.setText(f'Measurement Time: {np.round(self._measurement_time, 3)}')
+
diff --git a/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasurementSelectionWidget.py b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasurementSelectionWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab8b2fa889ed7bb1f34ae5a6048fdd5da72fafd1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/widgets/MeasurementSelectionWidget.py
@@ -0,0 +1,132 @@
+from PySide6.QtCore import Signal, Qt, QObject
+from PySide6.QtGui import QStandardItem, QStandardItemModel, QAction
+from PySide6.QtWidgets import (QTreeView, QVBoxLayout, QWidget, QTableView, QTableWidgetItem, QTableWidget, QMainWindow,
+                               QAbstractItemView, QMenu)
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MultipleMeasurementItem(QStandardItem):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def type(self, *args, **kwargs):
+        return 'Multi'
+
+
+class SingleMeasurementItem(QStandardItem):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def type(self):
+        return 'Single'
+
+
+class MeasurementSelectionWidgetSignals(QObject):
+    open_find_peaks_window = Signal(list)
+    on_consolidate_measurement_clicked = Signal(list)
+    on_recalculation_clicked = Signal(list)
+    on_show_item_click = Signal(SingleMeasuredData)
+
+
+class MeasurementSelectionWidget(QMainWindow):
+    consolidate_data = Signal(SingleMeasuredData)
+
+    def __init__(self, data):
+        super().__init__()
+        self.data: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = data
+
+        self.signals = MeasurementSelectionWidgetSignals()
+
+        self.tree_view = QTreeView(self)
+        self.model = QStandardItemModel()
+        self.tree_view.setModel(self.model)
+
+        self.setup_model()
+        self.tree_view.setSelectionMode(QAbstractItemView.SingleSelection)
+        self.tree_view.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
+        self.tree_view.customContextMenuRequested.connect(self.show_context_menu)
+        self.setCentralWidget(self.tree_view)
+
+    def setup_model(self):
+        for k1, v1 in self.data.items():
+            parent_item = QStandardItem(k1)
+            self.model.appendRow(parent_item)
+            for k2, v2 in v1.items():
+                child_item = QStandardItem(str(k2))
+                parent_item.appendRow(child_item)
+                for k3, v3 in v2.items():
+                    sub_child_item = MultipleMeasurementItem(k3)
+                    child_item.appendRow(sub_child_item)
+                    sub_child_item.setData(list(v2.values())[0])
+                    for measured_data in v3:
+                        data_item = SingleMeasurementItem(str(measured_data))
+                        sub_child_item.appendRow(data_item)
+                        data_item.setData(measured_data)
+
+    def multi_selection_menu(self, pos):
+        menu = QMenu(self)
+
+        action = QAction("Recalculate", self)
+        action.triggered.connect(self._on_recalculation_clicked)
+        menu.addAction(action)
+
+        action = QAction("Consolidate Data", self)
+        action.triggered.connect(self._on_consolidate_data_clicked)
+        menu.addAction(action)
+
+        action = QAction("Adapt 'FindPeaks' parameters", self)
+        action.triggered.connect(self._on_adapt_parameters_clicked)
+        menu.addAction(action)
+
+
+        menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+    def single_selection_menu(self, pos):
+        menu = QMenu(self)
+        action = QAction("Add to view", self)
+        action.triggered.connect(self._on_show_item_clicked)
+        menu.addAction(action)
+        menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+    def show_context_menu(self, pos):
+        selection = self.tree_view.selectionModel()
+        index = selection.currentIndex()
+        if index.isValid():
+            item = self.model.itemFromIndex(index)
+            if item is not None:
+                if isinstance(item, SingleMeasurementItem):
+                    self.single_selection_menu(pos)
+                elif isinstance(item, MultipleMeasurementItem):
+                    self.multi_selection_menu(pos)
+
+    def _on_show_item_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.on_show_item_click.emit(data)
+
+    def _on_recalculation_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.on_recalculation_clicked.emit(data)
+
+    def _on_adapt_parameters_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.open_find_peaks_window.emit(data)
+
+    def _on_consolidate_data_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.on_consolidate_measurement_clicked.emit(data)
+
+    def on_clicked_acquire_item_data(self, selection):
+        index = selection.currentIndex()
+        if index.isValid():
+            item = self.model.itemFromIndex(index)
+            if item.parent() is not None:
+                return item.data()
+        return None
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluation/view/widgets/PlotViewWidget.py b/src/FlexSensor/MeasurementEvaluation/view/widgets/PlotViewWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..b40970ba56970d5f9a1d0f24346fcad1a400fb33
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluation/view/widgets/PlotViewWidget.py
@@ -0,0 +1,31 @@
+import numpy as np
+import pandas as pd
+
+import matplotlib
+import matplotlib.pyplot as plt
+from matplotlib.backends.backend_qt5agg  import FigureCanvasQTAgg as FigureCanvas
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QComboBox
+
+matplotlib.use('QT5Agg')
+
+class PlotViewWidget(QWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent)
+
+        # Create a Matplotlib figure and axes
+        self.figure = plt.figure()
+        self.canvas = FigureCanvas(self.figure)
+        self.ax = self.figure.add_subplot(111)
+
+        self.plot_selection = ""
+
+        # Add the canvas to this PySide6 widget
+        layout = QVBoxLayout(self)
+        layout.addWidget(self.canvas)
+
+        # Set up the initial graph with no data
+        self.ax.set_xlabel('Wavelength')
+        self.ax.set_ylabel('Amplitude')
+        self.ax.set_xlim(0, 1)
+        self.ax.set_ylim(0, 1)
+        self.ax.grid(True)
diff --git a/src/FlexSensor/MeasurementEvaluationTool/__init__.py b/src/FlexSensor/MeasurementEvaluationTool/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..2f81a7ff401d6760f956df11385f3c7032a57c2c
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/__init__.py
@@ -0,0 +1,6 @@
+from MeasurementEvaluationTool.view.MeasurementDataView import MeasurementDataView as View
+from MeasurementEvaluationTool.model.MeasurementDataModel import MeasurementDataModel as Model
+from MeasurementEvaluationTool.controller.MeasurementDataController import MeasurementDataController as Controller
+from MeasurementEvaluationTool.controller.MeasurementDatabase import MeasurementDatabase as Database
+
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader as Loader
diff --git a/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDataController.py b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDataController.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c0f2523e2240bfa97107c51bb57b68063f769e2
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDataController.py
@@ -0,0 +1,70 @@
+import logging
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementData.MeasuredData.SupportClasses.MeasurementDataLoader import MeasurementDataLoader
+from MeasurementEvaluationTool.controller.MeasurementDatabase import MeasurementDatabase
+from MeasurementEvaluationTool.model.MeasurementDataModel import MeasurementDataModel
+
+
+class MeasurementDataController:
+
+    def __init__(self, model: MeasurementDataModel, path=None):
+        self.logger = logging.getLogger("MeasurementDataController")
+        self._model = model
+
+        self._model.path = path
+
+
+        self._model.selected_measurements = []
+
+        if path is not None:
+            # Use the loader to load the data
+            self.db = MeasurementDatabase('data.db')
+            MeasurementDataLoader.from_folder(self._model.path, self.db)
+            #self._model.measurement_list = self._md_loader.sorted_files
+        else:
+
+            self._model.measurement_list = {}
+
+
+
+    @property
+    def consolidated_measurements(self):
+        return self._consolidated_measurements
+
+    @consolidated_measurements.setter
+    def consolidated_measurements(self, value):
+        self._consolidated_measurements = value
+
+    @property
+    def all_measurements(self):
+        return self._model.measurement_list
+
+    @property
+    def list_of_measurements(self) -> list[SingleMeasuredData]:
+        return self._model.selected_measurements
+
+    @property
+    def selected_measurement(self) -> SingleMeasuredData:
+        return self._model.display_measurement
+
+    def select_measurement(self, selected_measurement: MeasuredData):
+        self._model.display_measurement = selected_measurement
+
+    def consolidate_measurements(self, measurement_selection):
+        self._model.consolidated_measurement = MultiMeasuredData(measurement_selection)
+        self._model.selected_measurements = measurement_selection
+        self.select_measurement(self._model.consolidated_measurement)
+
+    def recalculate_measurements(self, measurement_selection):
+        self.logger.info("Recalculating all measurements")
+        for md in measurement_selection:
+            md.calulate_all()
+
+    def load_from_folder(self):
+        raise NotImplementedError
+
+    def add_measurement(self):
+        pass
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDatabase.py b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDatabase.py
new file mode 100644
index 0000000000000000000000000000000000000000..b5c0d6e66f07c7f3d6726c96d8125b8f50e8aac3
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/controller/MeasurementDatabase.py
@@ -0,0 +1,95 @@
+import pickle
+import sqlite3
+
+from PySide6.QtWidgets import QApplication
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from generics.logger import setup_logging
+
+
+class MeasurementDatabase:
+    def __init__(self, db_name):
+        self.db_name = db_name
+        self.conn = sqlite3.connect(db_name)
+        self.cursor = self.conn.cursor()
+        self.create_table()
+
+    def create_table(self):
+        self.cursor.execute('''
+            CREATE TABLE IF NOT EXISTS single_measured_data (
+                wafer_number INTEGER,
+                die_number INTEGER,
+                structure_name TEXT,
+                rep INTEGER,
+                amplitude TEXT,
+                wavelength TEXT
+            )
+        ''')
+        self.conn.commit()
+
+    def add_data(self, data: SingleMeasuredData):
+        query = '''
+            INSERT INTO single_measured_data (
+                wafer_number,
+                die_number,
+                structure_name,
+                rep,
+                data_instance
+            ) VALUES (?, ?, ?, ?, ?)
+        '''
+        values = (
+            data.wafer_properties.wafer_number,
+            data.wafer_properties.die_number,
+            data.wafer_properties.structure_name,
+            data.wafer_properties.repetition,
+            pickle.dumps(data)
+        )
+        self.cursor.execute(query, values)
+        self.conn.commit()
+
+    def get_data(self, wafer_number, die_number):
+        query = '''
+            SELECT * FROM single_measured_data
+            WHERE wafer_number = ? AND die_number = ?
+        '''
+        values = (wafer_number, die_number)
+        self.cursor.execute(query, values)
+        rows = self.cursor.fetchall()
+        data_list = []
+        for row in rows:
+            amplitude = list(map(float, row[4].split()))
+            wavelength = list(map(float, row[5].split()))
+            data = SingleMeasuredData(row[0], row[1], row[2], row[3], amplitude, wavelength)
+            data_list.append(data)
+        return data_list
+
+    def delete_data(self, wafer_number, die_number):
+        query = '''
+            DELETE FROM single_measured_data
+            WHERE wafer_number = ? AND die_number = ?
+        '''
+        values = (wafer_number, die_number)
+        self.cursor.execute(query, values)
+        self.conn.commit()
+
+    def close_connection(self):
+        self.conn.close()
+
+
+if __name__ == "__main__":
+    app = QApplication()
+    setup_logging()
+
+    db = MeasurementDatabase("data.db")
+    # Load a measurement data
+    file = (r'F:\measurements_v2_06032022\measurements_v2_06032022\mea_mrr1_1_2022_03_04\T40741W177G0\MaskARY1_Jakob\measurement\measurement_die_22_struct_mrr1_1_20220304_2249_rep_2_v2.mat')
+
+
+    data = SingleMeasuredData.from_mat_v2(file)
+    db.add_data(data)
+    data_list = db.get_data(1, 2)
+    print(data_list)
+    db.delete_data(1, 2)
+    data_list = db.get_data(1, 2)
+    print(data_list)
+    db.close_connection()
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluationTool/controller/data.db b/src/FlexSensor/MeasurementEvaluationTool/controller/data.db
new file mode 100644
index 0000000000000000000000000000000000000000..70224a870b586f87c9dde89cee46921be7177ea0
Binary files /dev/null and b/src/FlexSensor/MeasurementEvaluationTool/controller/data.db differ
diff --git a/src/FlexSensor/MeasurementEvaluationTool/model/MeasurementDataModel.py b/src/FlexSensor/MeasurementEvaluationTool/model/MeasurementDataModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e55e292e0343f0eb2bda1a50bca42cff13b8950
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/model/MeasurementDataModel.py
@@ -0,0 +1,85 @@
+from pathlib import Path
+
+from PySide6.QtCore import Signal, QObject
+
+from MeasurementData.MeasuredData.MultiMeasuredData import MultiMeasuredData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MeasuredDataSignals(QObject):
+    path_changed = Signal(Path)
+
+    list_of_measurements_changed = Signal(list)
+    all_measurements_changed = Signal(dict)
+
+    num_of_measurements = Signal(int)
+    selected_measurement_changed = Signal(SingleMeasuredData)
+    consolidated_measurements_changed = Signal(MultiMeasuredData)
+
+
+class MeasurementDataModel:
+    def __init__(self):
+        self.signals = MeasuredDataSignals()
+
+        self._path: Path = None
+        self._measurement_list: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = None
+
+        self._consolidated_measurement: MultiMeasuredData = None
+        self._display_measurement: SingleMeasuredData = None
+        self._selected_measurements: list[SingleMeasuredData] = []
+
+        self._num_of_measurements: int = 0
+
+    @property
+    def consolidated_measurement(self):
+        return self._consolidated_measurement
+
+    @consolidated_measurement.setter
+    def consolidated_measurement(self, value):
+        self._consolidated_measurement = value
+
+    @property
+    def path(self):
+        return self._path
+
+    @path.setter
+    def path(self, value):
+        self._path = value
+        self.signals.path_changed.emit(self.path)
+
+    @property
+    def measurement_list(self) -> dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]:
+        return self._measurement_list
+
+    @measurement_list.setter
+    def measurement_list(self, value: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]]) -> None:
+        self._measurement_list = value
+        self.signals.all_measurements_changed.emit(self.measurement_list)
+
+    @property
+    def selected_measurements(self) -> list[SingleMeasuredData]:
+        return self._selected_measurements
+
+    @selected_measurements.setter
+    def selected_measurements(self, value: list[SingleMeasuredData]) -> None:
+        self._selected_measurements = value
+        self.num_of_measurements = len(self.selected_measurements)
+        self.signals.list_of_measurements_changed.emit(self.selected_measurements)
+
+    @property
+    def num_of_measurements(self) -> int:
+        return self._num_of_measurements
+
+    @num_of_measurements.setter
+    def num_of_measurements(self, value: list[SingleMeasuredData]) -> None:
+        self._num_of_measurements = value
+        self.signals.num_of_measurements.emit(self.num_of_measurements)
+
+    @property
+    def display_measurement(self) -> SingleMeasuredData:
+        return self._display_measurement
+
+    @display_measurement.setter
+    def display_measurement(self, value: SingleMeasuredData) -> None:
+        self._display_measurement = value
+        self.signals.selected_measurement_changed.emit(self.display_measurement)
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/MeasurementDataView.py b/src/FlexSensor/MeasurementEvaluationTool/view/MeasurementDataView.py
new file mode 100644
index 0000000000000000000000000000000000000000..167996fda6b44efdc6e6879d1f0f82b028482aaa
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/MeasurementDataView.py
@@ -0,0 +1,171 @@
+import sys
+
+import numpy as np
+from PySide6.QtWidgets import QApplication, QWidget, QTableView, \
+    QComboBox, QPushButton, QGridLayout
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementEvaluationTool.controller.MeasurementDataController import MeasurementDataController
+from MeasurementEvaluationTool.model.MeasurementDataModel import MeasurementDataModel
+from generics.PandasTableModel import PandasTableModel
+from MeasurementEvaluationTool.view.ParameterAdjustmentView import ParameterAdjustmentWindow
+from MeasurementEvaluationTool.view.widgets.MeasurementSelectionWidget import MeasurementSelectionWidget
+from MeasurementEvaluationTool.view.widgets.PlotViewWidget import PlotViewWidget
+from generics.logger import setup_logging
+
+
+class MeasurementDataView(QWidget):
+    def __init__(self, model: MeasurementDataModel, controller: MeasurementDataController):
+        super().__init__()
+        self._model = model
+        self._controller = controller
+        self.layout = QGridLayout()
+
+        self._model.signals.selected_measurement_changed.connect(self._on_selected_measurement_changed)
+
+        self._init_ui()
+
+    def _init_ui(self):
+        self.find_peaks_view = ParameterAdjustmentWindow()
+
+        # Add a view for selecting the measurement
+        self.measurement_selection = MeasurementSelectionWidget(self._controller.all_measurements)
+
+        self.measurement_selection.signals.open_find_peaks_window.connect(self._on_adapt_parameters_clicked)
+        self.measurement_selection.signals.on_consolidate_measurement_clicked.connect(self._on_consolidate_clicked)
+        self.measurement_selection.signals.on_recalculation_clicked.connect(self._on_recalculate_clicked)
+        self.measurement_selection.signals.on_show_item_click.connect(self._on_show_item_clicked)
+
+        # self.measurement_selection.selection.selected_data_changed.connect(self._on_selection_changed)
+        self.layout.addWidget(self.measurement_selection, 0, 0, 2, 1)
+
+        self.plot_widget = PlotViewWidget()  # pg.PlotWidget()
+        self.layout.addWidget(self.plot_widget, 0, 1, 1, 1)
+
+        # Display the data in an QTableWidget
+        self.table_view = QTableView()
+        self.layout.addWidget(self.table_view, 1, 1, 1, 1)
+
+        # Add a dropdown
+        self.btn_consolidate = QPushButton('Consolidate all')
+        self.btn_consolidate.clicked.connect(self._on_consolidate_clicked)
+        self.layout.addWidget(self.btn_consolidate, 2, 0, 1, 1)
+
+        self.dd_select_measurement_table = QComboBox()
+        self.dd_select_measurement_table.currentIndexChanged.connect(self._on_data_table_changed)
+        self.layout.addWidget(self.dd_select_measurement_table, 2, 1, 1, 1)
+
+        self.setLayout(self.layout)
+        # self._controller.select_measurement(0)
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def _on_show_item_clicked(self, measurement_selection: SingleMeasuredData):
+        measurement_selection.calulate_all()
+        self._controller.select_measurement(measurement_selection)
+
+    def _on_consolidate_clicked(self, measurement_selection):
+        self._controller.recalculate_measurements(measurement_selection)
+        self._controller.consolidate_measurements(measurement_selection)
+        # self._current_measurement = self._controller.consolidated_measurements
+
+    def _on_recalculate_clicked(self, measurement_selection):
+        self._controller.recalculate_measurements(measurement_selection)
+
+    def _on_adapt_parameters_clicked(self, measurement_selection):
+        self.find_peaks_view.measured_data_list = measurement_selection
+        self.find_peaks_view.show()
+
+    def _on_selection_changed(self, it: int):
+        # self._controller.select_measurement(it)
+        self.measurement_selection.set_selected_data(self._controller.selected_measurement)
+
+    def _on_data_table_changed(self, idx):
+        table_name = self.dd_select_measurement_table.itemData(idx)
+        print(f"{table_name} - {type(table_name)}")
+        # print(self._current_measurement.tables.get(table_name))
+        table = self._controller.selected_measurement.tables.get(table_name)
+        # Define plt function here
+        self.table_view_model = PandasTableModel(table)
+        self.table_view.setModel(self.table_view_model)
+
+        # This will be removed later and is only for quick and dirty hardcoded plotting
+        if table_name == "_measured_data":
+            pass
+        #    self._plot_measurement_table(table_name)
+        elif table_name == "_wg_param":
+            self._controller.selected_measurement.tables.get_plot_function('ng (FSR)')(self.plot_widget)
+
+            #self._plot_ng_table(table_name)
+
+    def _on_selected_measurement_changed(self, measurement: MeasurementData):
+        self._current_measurement = measurement
+        # Populate the measurement ment selection
+        self.dd_select_measurement_table.clear()
+        for table in measurement.tables.to_list():
+            # id in table -> table[2] = 'Friendly name', table[1] = 'table name'
+            self.dd_select_measurement_table.addItem(table[2], table[1])
+        #self.dd_select_measurement_table.addItem( measurement.tables.to_list()[2][2], table[2][1])
+
+    # ==================================================================================================================
+    #
+    # =============================================================================================================
+    def _plot_measurement_table(self, table_name, x_axis="wavelength", y_axis="detrend"):
+        self.plot_widget.ax.clear()
+        data = self._controller.selected_measurement.tables.get(table_name)
+        self.plot_widget.ax.plot(data[x_axis], data[y_axis], 'b-')[0]
+        self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+        self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+        # Scatter plot of the peaks
+        df_peaks = self._current_measurement.peaks
+        self.plot_widget.ax.scatter(df_peaks[x_axis], df_peaks[y_axis], marker='x', color='red')
+        self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+        self.plot_widget.ax.set_ylabel('Amplitude [1]')
+        self.plot_widget.ax.set_title('Measured data')
+        self.plot_widget.ax.grid(True)
+        self.plot_widget.ax.legend([y_axis, 'Peaks'])
+
+        self.plot_widget.canvas.draw()
+
+    def _plot_ng_table(self, table_name, x_axis="lambda", y_axis="FSR"):
+        self.plot_widget.ax.clear()
+        data = self._controller.selected_measurement.tables.get(table_name)
+        self.plot_widget.ax.plot(data[x_axis], data[y_axis])
+        self.plot_widget.ax.set_xlim(np.min(data[x_axis]), np.max(data[x_axis]))
+        self.plot_widget.ax.set_ylim(np.min(data[y_axis]), np.max(data[y_axis]))
+        # Scatter plot of the peaks
+        self.plot_widget.ax.set_xlabel('Wavelength [nm]')
+        self.plot_widget.ax.set_ylabel(f'{y_axis} [1]')
+        self.plot_widget.ax.grid(True)
+
+        self.plot_widget.canvas.draw()
+
+def convert_mat(mypath):
+    #mypath = (r'F:\measurements_06032022')
+    md_loader = MeasurementDataLoader.glob_files(mypath, '*.mat')
+    #measurement_list = md_loader.sorted_files
+
+    for measurement in md_loader:
+        SingleMeasuredData.convert(measurement)
+        print('done')
+
+
+if __name__ == "__main__":
+    app = QApplication()
+    setup_logging()
+
+    #mypath = (r'F:\measurements_06032022\measurements_06032022\mea_mzi1_2022_03_06\T40741W177G0')
+    #mypath = (r'F:\measurements_06032022')
+    #convert_mat(mypath)
+    #exit()
+
+    mypath = (r'F:\measurements_v2_06032022')
+
+    model = MeasurementDataModel()
+    controller = MeasurementDataController(model, mypath)
+    window = MeasurementDataView(model, controller)
+    window.show()
+
+    sys.exit(app.exec())
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/ParameterAdjustmentView.py b/src/FlexSensor/MeasurementEvaluationTool/view/ParameterAdjustmentView.py
new file mode 100644
index 0000000000000000000000000000000000000000..3848db134407336f072d3b9999cc194dbe8599bc
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/ParameterAdjustmentView.py
@@ -0,0 +1,169 @@
+from PySide6.QtWidgets import QLineEdit, QPushButton
+from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
+                               QWidget, QLabel, QSlider, QComboBox)
+from PySide6.QtCore import Qt, Signal
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+import pyqtgraph as pg
+
+from MeasurementEvaluationTool.view.widgets.MeasuredDataInformationWidget import MeasuredDataInformationWidget
+
+
+class ParameterAdjustmentWindow(QMainWindow):
+
+    def __init__(self):
+        super().__init__()
+        self._current_measurement = None
+        self._measured_data_list = None
+
+        self.setWindowTitle("Find Peaks Demo")
+
+        layout = QVBoxLayout()
+        self.measurement_selection = QComboBox()
+        layout.addWidget(self.measurement_selection)
+
+        self._find_peaks_wdg = ParameterAdjustmentWidget()
+        self._find_peaks_wdg.apply_fp_param_to_all_clicked.connect(self._on_apply_to_all)
+
+        layout.addWidget(self._find_peaks_wdg)
+        widget = QWidget()
+        widget.setLayout(layout)
+
+        self.setCentralWidget(widget)
+
+    @property
+    def current_measurement(self):
+        return self._current_measurement
+
+    @current_measurement.setter
+    def current_measurement(self, value):
+        self._current_measurement = value
+        self._find_peaks_wdg.measured_data = self.current_measurement
+
+    @property
+    def measured_data_list(self):
+        return self._measured_data_list
+
+    @measured_data_list.setter
+    def measured_data_list(self, value):
+        self._measured_data_list = value
+        self.current_measurement = self._measured_data_list[0]
+        for i, md in enumerate(self._measured_data_list):
+            self.measurement_selection.addItem(str(md))
+        self.measurement_selection.currentIndexChanged.connect(self._on_measurement_changed)
+
+    def _on_apply_to_all(self, prominence, distance):
+        for md in self._measured_data_list:
+            md.measurement_properties.find_peaks.set_properties(prominence,distance,None)
+
+    def _on_measurement_changed(self, index):
+        self.current_measurement = self._measured_data_list[index]
+
+
+class ParameterAdjustmentWidget(QWidget):
+    apply_fp_param_to_all_clicked = Signal(float, float)
+
+    def __init__(self):
+        super().__init__()
+        self._measured_data: SingleMeasuredData = None
+        # Create the numpy array
+        self._init_ui()
+
+    @property
+    def measured_data(self):
+        return self._measured_data
+
+    @measured_data.setter
+    def measured_data(self, value):
+        self._measured_data = value
+        self.x = self._measured_data.tables.get('_measured_data')['wavelength']
+        self.y = self._measured_data.tables.get('_measured_data')['amplitude']
+        self.prom_slider.setValue(
+            self._measured_data.measurement_properties.find_peaks.prominence * 100)
+        self.dist_slider.setValue(
+            int(self._measured_data.measurement_properties.find_peaks.distance/10))
+
+        self.dist_slider.setRange(1, len(self.x))
+        self.update_plot()
+
+    def _init_ui(self):
+        # Create the plot widget
+        self.plot_widget = pg.PlotWidget()
+
+        # Create the sliders
+        self.prom_slider = QSlider(Qt.Horizontal)
+        self.prom_slider.setRange(0, 100)
+        #
+        self.prom_slider.setTickInterval(5)
+        self.prom_slider.setTickPosition(QSlider.TicksBelow)
+        self.prom_slider.sliderMoved.connect(self.update_plot)
+        self.edit_prom = QLineEdit(str(self.prom_slider.value()))
+
+        self.dist_slider = QSlider(Qt.Horizontal)
+
+        #
+        self.dist_slider.setTickInterval(100)
+        self.dist_slider.setTickPosition(QSlider.TicksBelow)
+        self.dist_slider.sliderMoved.connect(self.update_plot)
+        self.edit_dist = QLineEdit(str(self.dist_slider.value()))
+
+        self.btn_apply_to_all = QPushButton('Apply to all')
+        self.btn_apply_to_all.clicked.connect(
+            lambda: self.apply_fp_param_to_all_clicked.emit(
+                self.prom_slider.value() / 100,
+                self.dist_slider.value()
+            )
+        )
+        # Create the layout
+        prom_layout = QHBoxLayout()
+        prom_layout.addWidget(QLabel("Prominence:"))
+        prom_layout.addWidget(self.prom_slider)
+        prom_layout.addWidget(self.edit_prom)
+
+        dist_layout = QHBoxLayout()
+        dist_layout.addWidget(QLabel("Distance:"))
+        dist_layout.addWidget(self.dist_slider)
+        dist_layout.addWidget(self.edit_dist)
+
+        layout = QVBoxLayout()
+        layout.addWidget(self.plot_widget)
+        self.wdg_measured_information = MeasuredDataInformationWidget(self._measured_data)
+        layout.addWidget(self.wdg_measured_information)
+        layout.addLayout(prom_layout)
+        layout.addLayout(dist_layout)
+        layout.addWidget(self.btn_apply_to_all)
+        self.setLayout(layout)
+
+    def update_plot(self):
+        # Update the prominence and distance values
+        prom = self.prom_slider.value() / 100
+        dist = self.dist_slider.value()
+        self.wdg_measured_information.measurement_data = self.measured_data
+        # Update the peaks
+        self._measured_data.measurement_properties.find_peaks.prominence = prom
+        self._measured_data.measurement_properties.find_peaks.distance = dist
+
+        peaks_wl = self._measured_data.tables.get('_peaks')['wavelength'].compute()
+        peaks_amplitude = self._measured_data.tables.get('_peaks')['amplitude'].compute()
+        self.edit_dist.setText(str(dist))
+        self.edit_prom.setText(str(prom))
+
+        self.plot_widget.clear()
+        x = self.x.compute()
+        y = self.y.compute()
+        self.plot_widget.plot(x.to_list(), y.to_list())
+        self.plot_widget.plot(peaks_wl.to_list(), peaks_amplitude.to_list(), pen=None, symbol="o")
+
+
+if __name__ == "__main__":
+    app = QApplication([])
+
+    mypath = r'E:\measurements_06032022\measurements_06032022\mea_mzi2_2_2022_03_06\T40741W177G0\MaskARY1_Jakob\measurement_small'
+    mm_data = MeasurementDataLoader.from_folder(mypath)
+    # matfile = mm_data.get_measurement(repetition=1, structure_name='mzi2-2')
+    matfiles = mm_data.get_measurement_series(structure_name='mzi2-2')
+    # matfile = SingleMeasuredData.from_mat(Path(f"{mypath}\measurement_die_22_struct_mzi2_2_20220306_1908_rep_2.mat"))
+    window = ParameterAdjustmentWindow(matfiles)
+    window.show()
+    app.exec_()
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasuredDataInformationWidget.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasuredDataInformationWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..00e6ff908e2558e810e25810dc2b031a024c2bb1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasuredDataInformationWidget.py
@@ -0,0 +1,63 @@
+import numpy as np
+from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QGroupBox, QHBoxLayout, QGridLayout
+
+from MeasurementData.MeasuredData.MeasuredData import MeasuredData
+
+
+class MeasuredDataInformationWidget(QGroupBox):
+    def __init__(self, measured_data: MeasuredData):
+        super().__init__()
+
+        self._wafer_number = "unknown"
+        self._die_number = "unknown"
+        self._structure_name = "unknown"
+        self._repetition = "unknown"
+        self._timestamp = "unknown"
+        self._measurement_time = 0
+        self._init_ui()
+        self.measurement_data = measured_data
+
+    def _init_ui(self):
+        # Create QLabel widgets to display the information
+        layout = QGridLayout()
+        self.wafer_label = QLabel()
+        self.die_label = QLabel()
+        self.structure_label = QLabel()
+        layout.addWidget(self.wafer_label, 0, 0)
+        layout.addWidget(self.die_label, 0, 1)
+        layout.addWidget(self.structure_label, 0, 2)
+
+        self.repetition_label = QLabel()
+        self.timestamp_label = QLabel()
+        self.measurement_time_label = QLabel()
+        layout.addWidget(self.repetition_label, 1, 0)
+        layout.addWidget(self.timestamp_label, 1, 1)
+        layout.addWidget(self.measurement_time_label, 1, 2)
+
+        # Create a vertical layout to arrange the QLabel widgets
+
+        # Set the layout for the group box
+        self.setLayout(layout)
+
+    @property
+    def measurement_data(self):
+        return self._measurement_data
+
+    @measurement_data.setter
+    def measurement_data(self, value):
+        if value is not None:
+            self._measurement_data = value
+            self._wafer_number = self._measurement_data.wafer_properties.wafer_number
+            self._die_number = self._measurement_data.wafer_properties.die_number
+            self._structure_name = self._measurement_data.wafer_properties.structure_name
+            self._repetition = self._measurement_data.wafer_properties.repetition
+            self._timestamp = "none"
+            self._measurement_time = self._measurement_data.ad2_properties.measurement_time
+
+        self.wafer_label.setText(f'Wafer Number: {self._wafer_number}')
+        self.die_label.setText(f'Die Number: {self._die_number}')
+        self.structure_label.setText(f'Structure Name: {self._structure_name}')
+        self.repetition_label.setText(f'Repetition: {self._repetition}')
+        self.timestamp_label.setText(f'Timestamp: {self._timestamp}')
+        self.measurement_time_label.setText(f'Measurement Time: {np.round(self._measurement_time, 3)}')
+
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasurementSelectionWidget.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasurementSelectionWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..ab8b2fa889ed7bb1f34ae5a6048fdd5da72fafd1
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MeasurementSelectionWidget.py
@@ -0,0 +1,132 @@
+from PySide6.QtCore import Signal, Qt, QObject
+from PySide6.QtGui import QStandardItem, QStandardItemModel, QAction
+from PySide6.QtWidgets import (QTreeView, QVBoxLayout, QWidget, QTableView, QTableWidgetItem, QTableWidget, QMainWindow,
+                               QAbstractItemView, QMenu)
+
+import MeasurementData
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class MultipleMeasurementItem(QStandardItem):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def type(self, *args, **kwargs):
+        return 'Multi'
+
+
+class SingleMeasurementItem(QStandardItem):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def type(self):
+        return 'Single'
+
+
+class MeasurementSelectionWidgetSignals(QObject):
+    open_find_peaks_window = Signal(list)
+    on_consolidate_measurement_clicked = Signal(list)
+    on_recalculation_clicked = Signal(list)
+    on_show_item_click = Signal(SingleMeasuredData)
+
+
+class MeasurementSelectionWidget(QMainWindow):
+    consolidate_data = Signal(SingleMeasuredData)
+
+    def __init__(self, data):
+        super().__init__()
+        self.data: dict[str, dict[int, dict[str, list[SingleMeasuredData]]]] = data
+
+        self.signals = MeasurementSelectionWidgetSignals()
+
+        self.tree_view = QTreeView(self)
+        self.model = QStandardItemModel()
+        self.tree_view.setModel(self.model)
+
+        self.setup_model()
+        self.tree_view.setSelectionMode(QAbstractItemView.SingleSelection)
+        self.tree_view.setSelectionBehavior(QAbstractItemView.SelectRows)
+        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
+        self.tree_view.customContextMenuRequested.connect(self.show_context_menu)
+        self.setCentralWidget(self.tree_view)
+
+    def setup_model(self):
+        for k1, v1 in self.data.items():
+            parent_item = QStandardItem(k1)
+            self.model.appendRow(parent_item)
+            for k2, v2 in v1.items():
+                child_item = QStandardItem(str(k2))
+                parent_item.appendRow(child_item)
+                for k3, v3 in v2.items():
+                    sub_child_item = MultipleMeasurementItem(k3)
+                    child_item.appendRow(sub_child_item)
+                    sub_child_item.setData(list(v2.values())[0])
+                    for measured_data in v3:
+                        data_item = SingleMeasurementItem(str(measured_data))
+                        sub_child_item.appendRow(data_item)
+                        data_item.setData(measured_data)
+
+    def multi_selection_menu(self, pos):
+        menu = QMenu(self)
+
+        action = QAction("Recalculate", self)
+        action.triggered.connect(self._on_recalculation_clicked)
+        menu.addAction(action)
+
+        action = QAction("Consolidate Data", self)
+        action.triggered.connect(self._on_consolidate_data_clicked)
+        menu.addAction(action)
+
+        action = QAction("Adapt 'FindPeaks' parameters", self)
+        action.triggered.connect(self._on_adapt_parameters_clicked)
+        menu.addAction(action)
+
+
+        menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+    def single_selection_menu(self, pos):
+        menu = QMenu(self)
+        action = QAction("Add to view", self)
+        action.triggered.connect(self._on_show_item_clicked)
+        menu.addAction(action)
+        menu.exec_(self.tree_view.viewport().mapToGlobal(pos))
+
+    def show_context_menu(self, pos):
+        selection = self.tree_view.selectionModel()
+        index = selection.currentIndex()
+        if index.isValid():
+            item = self.model.itemFromIndex(index)
+            if item is not None:
+                if isinstance(item, SingleMeasurementItem):
+                    self.single_selection_menu(pos)
+                elif isinstance(item, MultipleMeasurementItem):
+                    self.multi_selection_menu(pos)
+
+    def _on_show_item_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.on_show_item_click.emit(data)
+
+    def _on_recalculation_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.on_recalculation_clicked.emit(data)
+
+    def _on_adapt_parameters_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.open_find_peaks_window.emit(data)
+
+    def _on_consolidate_data_clicked(self):
+        selection = self.tree_view.selectionModel()
+        data = self.on_clicked_acquire_item_data(selection)
+        self.signals.on_consolidate_measurement_clicked.emit(data)
+
+    def on_clicked_acquire_item_data(self, selection):
+        index = selection.currentIndex()
+        if index.isValid():
+            item = self.model.itemFromIndex(index)
+            if item.parent() is not None:
+                return item.data()
+        return None
\ No newline at end of file
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MenuBarDefinition.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MenuBarDefinition.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ff8638994e2b9b0ee4ac9880aed97c31014e2be
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/MenuBarDefinition.py
@@ -0,0 +1,50 @@
+from PySide6.QtGui import QIcon, QAction
+from PySide6.QtWidgets import QGroupBox, QWidget
+
+from MainWindow.controller.MainThreadController import MainThreadController
+from MainWindow.view import MainThreadView
+from pathes import image_root
+
+
+class MenuBarDefinition(QWidget):
+
+    def __init__(self, view: MainThreadView):
+        super().__init__()
+        self._view = view
+
+        # self.menubar = self.menuBar()
+        self.init_menu_file()
+        self.init_menu_edit()
+        self.init_menu_run()
+        # help_menu = menubar.addMenu("Help")
+        # help_menu.addAction("About", self.on_about_clicked)
+
+
+
+    def init_menu_file(self):
+        exit_action = QAction(QIcon('exit.png'), '&Exit     ', self)
+        exit_action.setShortcut('Ctrl+Q')
+        exit_action.setStatusTip('Exit application')
+        exit_action.triggered.connect(lambda: exit())
+        self._view._ui.menu_file.addAction(exit_action)
+
+    def init_menu_edit(self):
+        pass
+
+    def init_menu_run(self):
+        # self.menu_run = self.menubar.addMenu("Run")
+        self.open_step_trough = QAction('Open &Step Through Window', self)
+        self.open_step_trough.setShortcut('Ctrl+W')
+        self.open_step_trough.setStatusTip('Open Step Through Window')
+        self.open_step_trough.triggered.connect(self._view._on_open_step_through)
+        self._view._ui.menu_run.addAction(self.open_step_trough)
+
+        self.open_train_home_wizard = QAction('&Initial Setup Wizard', self)
+        self.open_train_home_wizard.setShortcut('Ctrl+I')
+        self.open_train_home_wizard.setStatusTip('Open Initial Setup Wizard')
+        self.open_train_home_wizard.setIcon(QIcon(f"{image_root}/icons/setup_wizard.png"))
+        self.open_train_home_wizard.triggered.connect(self._view._on_open_initial_setup_wizard)
+        self._view._ui.menu_run.addAction(self.open_train_home_wizard)
+
+
+
diff --git a/src/FlexSensor/MeasurementEvaluationTool/view/widgets/PlotViewWidget.py b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/PlotViewWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..b40970ba56970d5f9a1d0f24346fcad1a400fb33
--- /dev/null
+++ b/src/FlexSensor/MeasurementEvaluationTool/view/widgets/PlotViewWidget.py
@@ -0,0 +1,31 @@
+import numpy as np
+import pandas as pd
+
+import matplotlib
+import matplotlib.pyplot as plt
+from matplotlib.backends.backend_qt5agg  import FigureCanvasQTAgg as FigureCanvas
+from PySide6.QtWidgets import QWidget, QVBoxLayout, QComboBox
+
+matplotlib.use('QT5Agg')
+
+class PlotViewWidget(QWidget):
+    def __init__(self, parent=None):
+        super().__init__(parent)
+
+        # Create a Matplotlib figure and axes
+        self.figure = plt.figure()
+        self.canvas = FigureCanvas(self.figure)
+        self.ax = self.figure.add_subplot(111)
+
+        self.plot_selection = ""
+
+        # Add the canvas to this PySide6 widget
+        layout = QVBoxLayout(self)
+        layout.addWidget(self.canvas)
+
+        # Set up the initial graph with no data
+        self.ax.set_xlabel('Wavelength')
+        self.ax.set_ylabel('Amplitude')
+        self.ax.set_xlim(0, 1)
+        self.ax.set_ylim(0, 1)
+        self.ax.grid(True)
diff --git a/src/FlexSensor/MeasurementRoutines/BasemeasurementRoutine.py b/src/FlexSensor/MeasurementRoutines/BasemeasurementRoutine.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b7bba703a6d25f20070acad74b4ac0e9bf3ca1b
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/BasemeasurementRoutine.py
@@ -0,0 +1,108 @@
+import logging
+
+from PySide6.QtCore import QObject, QThread, Slot
+
+from AD2CaptDevice.controller.AD2CaptDeviceController import AD2CaptDeviceController
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from Laser.LaserControl.controller import BaseLaserController
+from Prober.controller.ProberController import ProberController
+from MeasurementRoutines.WorkerSignals import WorkerSignals
+
+
+class BaseMeasurementRoutine(QObject):
+
+    def __init__(self, laser: BaseLaserController, ad2device: AD2CaptDeviceController, prober: ProberController,
+                 vaut_config: VAutomatorConfig):
+        super().__init__()
+        self.logger = logging.getLogger("Base Measurement Routine")
+        self.vaut_config = vaut_config
+
+        self.ad2device: AD2CaptDeviceController = ad2device
+        self.laser: BaseLaserController = laser
+        self.prober: ProberController = prober
+        self.logger.debug(f"{self.prober.report_kernel_version()}")
+        print(self.prober)
+        
+        self.prober_thread = QThread()
+
+        self.signals = WorkerSignals()
+
+    @Slot()
+    def run(self):
+        raise NotImplementedError()
+
+    def _routine(self):
+        raise NotImplementedError()
+
+    def _init_prober_signals(self):
+        '''
+            Connect the signals and disable that a new log is printed (in order to prevent double occuring lines
+        '''
+        self.prober.signals.log_debug.connect(lambda title, desc, details: self._write_debug(desc, print_log=False))
+        self.prober.signals.log_info.connect(lambda title, desc, details: self._write_info(desc, print_log=False))
+        self.prober.signals.log_warning.connect(lambda title, desc, details: self._write_warning(desc, print_log=False))
+        self.prober.signals.log_error.connect(
+            lambda title, desc, details: self._write_error(title, desc, details, print_log=False))
+
+    def _write_debug(self, *msg, print_log=True, **kwargs):
+        if print_log:
+            self.logger.debug(*msg)
+        self.signals.write_log.emit("debug", *msg)
+
+    def _write_info(self, *msg, print_log=True, **kwargs):
+        if print_log:
+            self.logger.info(*msg)
+        self.signals.write_log.emit("info", *msg)
+
+    def _write_warning(self, title, msg, desc, err=None, tb=None, print_log=True, *args, **kwargs):
+        if err is None and tb is None:
+            logmsg_short = f"{desc}."
+            logmsg_full = f"{logmsg_short}"
+        else:
+            logmsg_short = f"{desc}: {err}."
+            logmsg_traceback = f"=== TRACEBACK ===\n{tb.format_exc()}"
+            logmsg_full = f"{logmsg_short}\n\n{logmsg_traceback}"
+        if print_log:
+            self.logger.warning(logmsg_full)
+        self.signals.warning.emit((title, logmsg_short, logmsg_full))
+
+    def _write_error(self, title, desc, e=None, tb=None, print_log=True, *args, **kwargs):
+        if e is None and tb is None:
+            logmsg_short = f"{desc}."
+            logmsg_full = f"{logmsg_short}"
+        else:
+            logmsg_short = f"{desc}: {e}."
+            logmsg_traceback = f"=== TRACEBACK ===\n{tb.format_exc()}"
+            logmsg_full = f"{logmsg_short}\n\n{logmsg_traceback}"
+            if print_log:
+                self.logger.error(logmsg_full)
+            self.signals.error.emit((title, logmsg_short, logmsg_full))
+
+    def write_log(self, msg_type, *args, **kwargs):
+        if msg_type == "debug":
+            self.logger.debug(*args)
+        elif msg_type == "warning":
+            self.logger.warning(*args)
+        elif msg_type == "error":
+            self.logger.error(*args)
+        elif msg_type == "fatal":
+            self.logger.fatal(*args)
+        else:
+            self.logger.info(*args)
+
+        self.signals.write_log.emit(msg_type, *args)
+
+    def register_step(*args, **kwargs):
+        step_name = "Step"
+        if 'step_name' in kwargs:
+            step_name = kwargs['step_name']
+
+        def inner(func):
+            '''
+               do operations with func
+            '''
+            print(f"Registering step for function {func} - {step_name}")
+            return func
+
+        return inner  # this is the fun_obj mentioned in the above content
+
diff --git a/src/FlexSensor/MeasurementRoutines/MeasurementRoutine.py b/src/FlexSensor/MeasurementRoutines/MeasurementRoutine.py
new file mode 100644
index 0000000000000000000000000000000000000000..ea4d3d963f407a4cfdbccc1a2bc5004e284a6ac2
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/MeasurementRoutine.py
@@ -0,0 +1,389 @@
+import logging
+import time
+import traceback
+from datetime import datetime
+
+import pandas as pd
+from PySide6.QtCore import Slot
+
+import mcpy
+from AD2CaptDevice.controller.AD2CaptDeviceController import AD2CaptDeviceController
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.controller.VFSObject import VFSObject
+from ConfigHandler.controller.VASInputFileParser import VASInputFileParser, Structure
+from Laser.LaserControl.controller import BaseLaserController
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+from MeasurementData.Properties.MeasurementProperties import MPropertiesFindPeaks, \
+    MeasurementProperties, WaveguidePropertiesMZI
+from MeasurementRoutines.BasemeasurementRoutine import BaseMeasurementRoutine
+from Prober.controller.ProberController import ProberController
+from MeasurementData.Properties.WaferProperties import WaferProperties
+from constants.FlexsensorConstants import Probe
+from generics.generics import pch
+
+
+class MeasurementRoutine(BaseMeasurementRoutine):
+
+    def __init__(self, laser: BaseLaserController, ad2device: AD2CaptDeviceController, prober: ProberController,
+                 vaut_config: VAutomatorConfig):
+        super().__init__(laser, ad2device, prober, vaut_config)
+
+        self.logger = logging.getLogger("Measurement Routine")
+        # The signals for connecting to the UI
+
+        self.parsed_file = VASInputFileParser()
+
+        self.grouped_structures, self.bookmarks = self.parsed_file.read_file(
+            input_file=self.vaut_config.wafer_config.get_structure_file().absolute
+        )
+        self.number_of_structures = self.parsed_file.num_of_structs
+        self.number_of_runs = self.parsed_file.num_of_runs
+
+        # We need to connect two signals:
+        # Connect the signal if a wavelength sweep starts (from the laser) to a signal that tells our oscilloscope
+        # to start capturing!
+        # self.laser.signals.wavelength_sweep_running.connect(self.ad2device.on_ad2_set_acquisition_changed)
+
+        # Some intermediate Data
+        self.columns = ["wafer_nr", "die_nr", "chuck_col", "chuck_row", "timestamp", "structure_name",
+                        "reps", "structure_x_in", "structure_y_in", "structure_x_out",
+                        "structure_y_out", "measure_time", "timestamps", "captured_values"]
+        self.siph_data = pd.DataFrame(columns=self.columns)
+        self.siph_data['captured_values'] = self.siph_data['captured_values'].astype(object)
+
+        self.initialization()
+
+    def initialization(self):
+        self.probe_height = 80
+
+        self.logger.info(
+            f"Init Prober Class. Number of runs per die: {self.number_of_runs}, dies {self.vaut_config.wafer_config.dies}\n"
+            f"Measurement CVS File = {self.vaut_config.wafer_config.measurement_output}\n"
+            f"Measurement Mat File = {self.vaut_config.wafer_config.measurement_mat_file}")
+
+    @Slot()
+    def run(self):
+        self.logger.info(f"<< Input file {self.vaut_config.wafer_config.get_structure_file().relative}")
+        self.logger.info(f">> Working directory {self.vaut_config.get_output_directory().relative}")
+        self.logger.info(f">> Log File {self.vaut_config.wafer_config.get_log_file().relative}")
+        self.logger.info(f">> Measurments CVS File {self.vaut_config.wafer_config.get_measurement_output().relative}")
+        self.logger.info(f">> Measurments Mat File {self.vaut_config.wafer_config.get_measurement_mat_file().relative}")
+        self.logger.info(f">> KLayout Bookmark file {self.vaut_config.wafer_config.get_bookmark_file().relative}")
+        self.logger.info(f">> Scope Image File {self.vaut_config.wafer_config.get_scope_image_file().relative}")
+
+        # as long as the connection was successful, we can send some commands.
+        # if it was not successful, an exception is thrown.
+
+        self.logger.warning("*** Check safe height. Contact height must be set.***")
+        # SCI commands return a namedtuple if multiple values are returned.
+        # ReportKernelVersion returns a version number and a description.
+        # You can acess the return values by name or by indexing the tuple.
+        self.logger.info("Everything is set up, starting measuring.")
+
+        self._routine()
+
+    def _routine(self):
+        try:
+            # Initialize the devices
+            self._init_prober_signals()
+            # self._init_laser_signals()
+            # self._init_ad2device_signals()
+
+            self._write_info(
+                f"{pch('=', 50)} Starting measurement {pch('=', 50)}")
+
+            # === Check contact height
+            print(self.prober)
+            contact, overtravel, align_dist, sep_dis, search_gap = self.prober.check_contact_height_set()
+
+            for die_idx, die_no in enumerate(self.vaut_config.wafer_config.dies):
+                # Move to die
+                self.write_log("info", f"Processing die {die_no} (#{die_idx})")
+                self.die_no, self.chuck_col, self.chuck_row = self.prober.move_to_die(die_no)
+
+                if self.die_no is not None and self.chuck_col is not None and self.chuck_row is not None:
+                    self.write_log("info", f"Chuck moved to home position. Die {self.die_no} "
+                                           f"(Col: {self.chuck_col}, Row: {self.chuck_row})")
+                else:
+                    # STOP SiPh-Tools
+                    self.write_log("fatal", "Chuck could not be moved to home position. Script will be stopped!")
+                    raise Exception("Chuck could not be moved to home position. Script will be stopped!")
+
+                # Go to the home position
+                self.write_log("info", "Move chuck to home position (0, 0)")
+                self.prober.move_chuck(0, 0)
+
+                # Iterate through the list of structures
+                for idx_groups, self.groups in enumerate(self.grouped_structures):
+
+                    structures: dict = self.grouped_structures[self.groups]
+                    idx_struct = 0
+                    self.write_log("info", f"New structure group ({idx_groups}): "
+                                           f"{self.groups}. {len(structures)} structures in group.")
+
+                    while idx_struct < len(structures):
+                        structure = list(structures.values())[idx_struct]
+                        self._measure_structure(die_no, structure, idx_struct)
+                        idx_struct += 1
+                        continue
+
+
+        except Exception as e:
+            self._write_error(title="Prober initialization error", desc="Could not connect or initialize prober",
+                              e=e, tb=traceback)
+
+    # ==================================================================================================================
+    # The individual steps for the Measurement Routine
+    # If implementing multiple routines, and the steps may occure multiple times, move them to
+    # the base class instead of reimplementing/copying!
+    # ==================================================================================================================
+    def _step_place_input_probe(self, structure: Structure, fmt):
+        """
+            Places the chuck, thus the input probe, such that the probe is on the correct position.
+            Move the chuck to the given position. Since the input probe stays on the same position,
+            the probe is therefore on the correct input position.
+        """
+        x, y = (structure.x_in, structure.y_in)
+        self.write_log("info", f"{fmt} Move input probe/chuck to X: {x}, Y: {y}.")
+        self.prober.move_chuck(x, y)
+        chuck_x, chuck_y, chuck_z = self.prober.read_chuck_position(unit="Microns", pos_ref="Home")
+        self.write_log("info", f"{fmt} Input probe/chuck at position X: {chuck_x}, Y: {chuck_y}, Z: {chuck_z}.")
+        return chuck_x, chuck_y, chuck_z
+
+    def _step_place_output_probe(self, structure, fmt, safe_dist: float = 50):
+        x, y = (structure.x_out, structure.y_out)
+        diff_x, diff_y = (structure.in_out_diff_x, structure.in_out_diff_y)
+        self.write_log("info", f"{fmt} Move second probe to x: {x}, y: {y}) - Difference x: {diff_x}, y: {diff_y}")
+
+        # TODO: CHeck if the structure require a reposition of the probe
+        move_probe2 = True
+
+        if self.structure.in_out_diff_x > safe_dist and move_probe2:
+            self.write_log("debug",
+                           f"{fmt} Optical probes in safe distance {x > safe_dist}. Moving output probe x:{diff_x}, y: {diff_y}.")
+            self.prober.opt_if.move_optical_probe(Probe.OUTPUT, diff_x, diff_y)
+        elif self.structure.in_out_diff_x < safe_dist:
+            raise Exception(f"Optical Probe Home not safe! Difference in x-direction < {safe_dist} um.")
+        else:
+            self.write_log("warning", f"Optical Probe not moved. Movement for probe disabled: {move_probe2}")
+
+    def _step_set_probes_to_measurement_height(self, height, fmt):
+        try:
+            self.write_log("info", f"{fmt} Setting probe heights to {height} um")
+            self.prober.opt_if.set_probe_height(Probe.INPUT, height)
+            self.prober.opt_if.set_probe_height(Probe.OUTPUT, height)
+            # self.msg_server.sendSciCommand("FindOpticalProbeHeight",
+            #                               rparams='0 %s' % self.probe_height)
+            # self.msg_server.sendSciCommand("FindOpticalProbeHeight",
+            #                               rparams='1 %s' % self.probe_height)
+        except Exception as e:
+            self.write_log("error",
+                           f"{fmt} Cannot set probe height to {height}. {e}")
+            self.signals.error.emit((
+                type(e), f"Cannot set probe height to {height}. {e}",
+                traceback.format_exc()
+            ))
+            raise e
+
+    def _step_snap_image(self, scope_file: VFSObject, fmt):
+        # Here we adapt filename of the scope by passing the correct keywords
+        try:
+            self.write_log("info", f"{fmt} Saving scope image to {scope_file.relative}")
+            self.prober.snap_image("eVue2", scope_file.absolute, 2)
+        except Exception as e:
+            self.logger.warning(f"{fmt} Cannot save scope image to {scope_file.relative}: {e}\n\n"
+                                f"{traceback.format_exc()}")
+
+            self.signals.warning.emit(type(e),
+                                      f"Cannot save scope image to {scope_file.relative}. {e}",
+                                      traceback.format_exc())
+
+    def _step_search_for_light(self, fmt):
+        # TODO: Handle if we cannot find the light
+        self.logger.info(f"{fmt} Searching for light.")
+        self.signals.write_log.emit("info", "Searching for light.")
+        input_power, output_power = self.prober.opt_if.search_for_light()
+        if input_power is None or output_power is None:
+            self.logger.warning(f"{fmt} Cannot find light. Something went wrong.")
+            self.signals.warning.emit("warning", "Cannot find light. Something went wrong.", "")
+            raise Exception('Cannot find light.')
+        else:
+            self.logger.info(f"{fmt} Light found. Input Power: {input_power} dBm. Output Power: {output_power} dBm")
+            self.logger.info(f"{fmt} Light found. Input Power: {input_power} dBm. Output Power: {output_power} dBm")
+            self.signals.write_log.emit("info",
+                                        "Light found. Input Power: {input_power} dBm. Output Power: {output_power} dBm")
+
+    def _step_capture_transmission(self, rep, fmt):
+        self.logger.info(f"{fmt} Setting up AD2. This may take a while, please wait...")
+        self.signals.write_log.emit("info", "Setting up oscilloscope.")
+
+        #if not self.ad2device.connect_device(0):
+        #    self.logger.error(f"{fmt} Could not setup ad2 device.")
+        #    self.signals.error.emit("error", "Could not setup ad2 device.", "")
+        #    raise Exception("Could not setup ad2 device. Script will be stopped!")
+
+        # *******************
+        # Start the measurement
+        #self.laser.start_wavelength_sweep()
+        #time.sleep(1)
+        #while self.ad2device.model.capturing_finished == False:
+        #    print(f"awaiting: {self.ad2device.model.capturing_finished}")
+        #    time.sleep(1)
+
+        #captured_values = self.ad2device.model.recorded_samples  # Just starts an endless loop
+        #print(len(captured_values))
+        #measure_time = self.ad2device.model.recording_time
+        captured_values, measure_time = self.laser.sweep_and_measure()
+
+        self.write_log("info", f"{self.formatter} Finished data acquisition: {len(captured_values)}. Took {round(measure_time, 5)} seconds.")
+        return measure_time, captured_values
+
+    def _step_create_MeasuredSignal(self, data: pd.DataFrame, data_raw: list, wafer_properties: WaferProperties):
+        # timestamp, measure_time, time_stamps, amplitude
+      
+        try:
+            cur_measured_signal = SingleMeasuredData(
+                laser_properties=self.laser.model.laser_properties,
+                ad2_properties=self.ad2device.model.ad2_properties,
+                wafer_properties=wafer_properties,
+                waveguide_properties=WaveguidePropertiesMZI(
+                    length1=mcpy.Rectangular(10e6, 20, unit='nm'),
+                    length2=mcpy.Rectangular(10.38e6, 20, unit='nm'),
+                    width=mcpy.Rectangular(550, 20, unit='nm'),
+                    height=mcpy.Rectangular(625, 2.405, unit='nm')),
+                measurement_properties=MeasurementProperties(
+                    MPropertiesFindPeaks(0.1, 10000, None)
+                ),
+                timestamp=data['timestamp'],
+                measurement_data=data_raw
+            )
+
+            # cur_measured_signal.set_prober_properties(
+            #     self.vaut_config.wafer_nr,
+            #     self.die_no,
+            #     self.chuck_col,
+            #     self.chuck_row
+            # )
+            # cur_measured_signal.set_structure_properties(self.structure)
+            # cur_measured_signal.set_ad2_properties(
+            #     self.vaut_config.ad2_device_config.get_sample_rate(),
+            #     self.vaut_config.ad2_device_config.get_total_samples())
+            #
+            # cur_measured_signal.set_laser_properties(
+            #     self.vaut_config.laser_config.get_wavelength_range(),
+            #     self.vaut_config.laser_config.get_velocity(),
+            #     self.vaut_config.laser_config.get_acceleration())
+
+            return cur_measured_signal
+
+        except Exception as e:
+            self.write_log("error", f"Could not create MeasuredSignal instance from data: {e}")
+            self.signals.error.emit((type(e),
+                                     f"Could not create MeasuredSignal instance from data: {e}",
+                                     traceback.format_exc()))
+            raise e
+
+    # Routine for measuring one structure
+    def _measure_structure(self, die_no: int, structure: Structure, structure_idx: int):
+        """Routine for measuring one structure
+
+        """
+        self.structure: Structure = structure
+        self.formatter = f"[Measurement. Die {die_no}]: {self.structure.name} |"
+        timestamp = datetime.now().strftime('%d/%m/%Y %H:%M:%S.%f')
+
+        if not self.structure.enabled:
+            self.write_log("info", f"Structure {self.structure.name} is disabled, skipping!")
+            return
+
+        self.write_log("info", f"{self.formatter} Processing structure {self.structure.name}.")
+        # Report the current structure information to the frontend
+        self.signals.report_info.emit({
+            "die_no": self.die_no, "chuck_col": self.chuck_col,
+            "chuck_row": self.chuck_row, "structure": self.structure.name,
+            "repetition": self.structure.repetitions
+        })
+        self.write_log("info", f"{self.formatter} "
+                               f"die_no: {self.die_no}, chuck_col: {self.chuck_col}, "
+                               f"chuck_row: {self.chuck_row}, structure: {self.structure.name}, "
+                               f"repetition: {self.structure.repetitions}"
+                       )
+
+        # 1. Move the first probe/chuck
+        self._step_place_input_probe(self.structure, self.formatter)
+
+        # 2. Move the second probe
+        self._step_place_output_probe(self.structure, self.formatter)
+
+        # 3. Setting the probe height to 80 um
+        self._step_set_probes_to_measurement_height(80, self.formatter)
+
+        # 4. Snap an image
+        # Create the correct file for the scope image
+        # self.vaut_config.wafer_config.get_scope_image_file().set_obj(
+        #    keywords={"{die}": self.die_no, "{structure}": self.structure.name, "{it}": 1})
+        self._step_snap_image(self.vaut_config.wafer_config.get_scope_image_file(
+            keywords={"{die}": self.die_no, "{structure}": self.structure.name}), self.formatter)
+
+        # Search for the light
+        self._step_search_for_light(self.formatter)
+
+        amplitude = []
+        time_stamps = []
+        rep = 1
+
+        while rep <= self.structure.repetitions:
+            # *******************
+            # Stop the measurement
+            # For displaying the data in the GUI
+            measure_time, captured_values = self._step_capture_transmission(rep, self.formatter)
+            data = [[
+                self.vaut_config.wafer_nr, self.die_no, self.chuck_col,
+                self.chuck_row, timestamp, str(self.structure), rep,
+                self.structure.x_in, self.structure.y_in,
+                self.structure.x_out, self.structure.y_out,
+                measure_time, str(time_stamps), captured_values
+            ]]
+            self.siph_data = pd.concat([self.siph_data, pd.DataFrame(data, columns=self.columns)])
+
+            try:
+                self.siph_data.to_csv(str(self.vaut_config.wafer_config.get_measurement_output()))
+                self.siph_data.to_excel(
+                    str(self.vaut_config.wafer_config.get_measurement_output()).replace('csv', 'xlsx'))
+            except Exception as e:
+                self._write_error("Write SiPh", f"Could not write sphi data to file "
+                                                f"{self.vaut_config.wafer_config.get_measurement_output()}", e,
+                                  traceback)
+                self.signals.error.emit((type(e),
+                                         f"Could not write sphi data to file "
+                                         f"{self.vaut_config.wafer_config.get_measurement_output()}: {e}",
+                                         traceback.format_exc()))
+
+            wafer_properties = WaferProperties(
+                wafer_number=self.vaut_config.wafer_nr,
+                structure_name=self.structure.name,
+                die_nr=self.die_no,
+                chuck_col=self.chuck_col,
+                chuck_row=self.chuck_row,
+                structure_in=(self.structure.x_in, self.structure.y_in),
+                structure_out=(self.structure.x_out, self.structure.y_out),
+                repetitions=rep)
+           
+            cur_measured_signal = self._step_create_MeasuredSignal(
+                self.siph_data, 
+                captured_values,
+                wafer_properties)
+
+            cur_measured_signal._save_mat_file(
+                filename=self.vaut_config.wafer_config.get_measurement_mat_file(keywords={"{die}": self.die_no,
+                                                                                          "{structure}": self.structure.name,
+                                                                                          "{it}": f"rep_{rep + 1}"}).absolute
+            )
+
+
+            rep += 1
+            self.logger.info(f"Repetition {rep}/{self.structure.repetitions} measured successfully!")
+            self.signals.routine_iteration_finished.emit(cur_measured_signal, rep)
+            # Report the progress to the frontend
+        self.write_log("info", "[OK] Continuing with next structure.")
+        # idx_struct = idx_struct + 1
diff --git a/src/FlexSensor/MeasurementRoutines/WorkerSignals.py b/src/FlexSensor/MeasurementRoutines/WorkerSignals.py
new file mode 100644
index 0000000000000000000000000000000000000000..50eda1e84b4859872c1b22f55582d5a0642f22b6
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/WorkerSignals.py
@@ -0,0 +1,23 @@
+from PySide6.QtCore import QObject, Signal
+
+from MeasurementData.MeasuredData.SingleMeasuredData import SingleMeasuredData
+
+
+class WorkerSignals(QObject):
+
+    finished = Signal()
+
+    error = Signal(tuple)
+
+    warning = Signal(tuple)
+
+    result = Signal(object)
+
+    progress = Signal(float)
+
+    # Reports the measured data and the iteration number
+    routine_iteration_finished = Signal(SingleMeasuredData, int)
+
+    write_log = Signal(str, str)
+
+    report_info = Signal(dict)
diff --git a/src/FlexSensor/MeasurementRoutines/__init__.py b/src/FlexSensor/MeasurementRoutines/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/MeasurementRoutines/ressources/MeasurementControlFlow.ui b/src/FlexSensor/MeasurementRoutines/ressources/MeasurementControlFlow.ui
new file mode 100644
index 0000000000000000000000000000000000000000..8cae92507faa3ed421f4ea9019cfe5552ca16be0
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/ressources/MeasurementControlFlow.ui
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MeasurementControlFlow</class>
+ <widget class="QWidget" name="MeasurementControlFlow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_2">
+   <item row="0" column="0">
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <widget class="QListView" name="listView_control_flow"/>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/FlexSensor/MeasurementRoutines/ressources/convert.sh b/src/FlexSensor/MeasurementRoutines/ressources/convert.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c317f21e29daef33cbd1dba83f08f1e10c242004
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/ressources/convert.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# Convert .ui files to .py files
+for ui in *.ui; do
+    pyside6-uic $ui > ../view/Ui_${ui%.*}.py
+done
+ pyside6-rcc ../../resources.qrc -o ../../resources_rc.py
diff --git a/src/FlexSensor/MeasurementRoutines/view/MeasurementControlFlow.py b/src/FlexSensor/MeasurementRoutines/view/MeasurementControlFlow.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ec6b4ba0aae77f186b423b109b20db74583d0fa
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/view/MeasurementControlFlow.py
@@ -0,0 +1,9 @@
+from MeasurementRoutines.view.Ui_MeasurementControlFlow import Ui_MeasurementControlFlow
+
+
+class MeasurementControlFlow():
+    def __init__(self, measurementRoutine: BaseMeasurementRoutine):
+        # Init the UI file
+        self._ui = Ui_MeasurementControlFlow()
+        self._ui.setupUi(self)
+
diff --git a/src/FlexSensor/MeasurementRoutines/view/Ui_MeasurementControlFlow.py b/src/FlexSensor/MeasurementRoutines/view/Ui_MeasurementControlFlow.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb1b0e958f3426e2f913b70b87cb3e284891723b
--- /dev/null
+++ b/src/FlexSensor/MeasurementRoutines/view/Ui_MeasurementControlFlow.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'MeasurementControlFlow.ui'
+##
+## Created by: Qt User Interface Compiler version 6.5.2
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
+    QMetaObject, QObject, QPoint, QRect,
+    QSize, QTime, QUrl, Qt)
+from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
+    QFont, QFontDatabase, QGradient, QIcon,
+    QImage, QKeySequence, QLinearGradient, QPainter,
+    QPalette, QPixmap, QRadialGradient, QTransform)
+from PySide6.QtWidgets import (QApplication, QGridLayout, QListView, QSizePolicy,
+    QWidget)
+
+class Ui_MeasurementControlFlow(object):
+    def setupUi(self, MeasurementControlFlow):
+        if not MeasurementControlFlow.objectName():
+            MeasurementControlFlow.setObjectName(u"MeasurementControlFlow")
+        MeasurementControlFlow.resize(400, 300)
+        self.gridLayout_2 = QGridLayout(MeasurementControlFlow)
+        self.gridLayout_2.setObjectName(u"gridLayout_2")
+        self.gridLayout = QGridLayout()
+        self.gridLayout.setObjectName(u"gridLayout")
+        self.listView_control_flow = QListView(MeasurementControlFlow)
+        self.listView_control_flow.setObjectName(u"listView_control_flow")
+
+        self.gridLayout.addWidget(self.listView_control_flow, 0, 0, 1, 1)
+
+
+        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
+
+
+        self.retranslateUi(MeasurementControlFlow)
+
+        QMetaObject.connectSlotsByName(MeasurementControlFlow)
+    # setupUi
+
+    def retranslateUi(self, MeasurementControlFlow):
+        MeasurementControlFlow.setWindowTitle(QCoreApplication.translate("MeasurementControlFlow", u"Form", None))
+    # retranslateUi
+
diff --git a/src/FlexSensor/Prober/__init__.py b/src/FlexSensor/Prober/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9885c767677d0fc7299511b1dfe724dd43e186d
--- /dev/null
+++ b/src/FlexSensor/Prober/__init__.py
@@ -0,0 +1,20 @@
+import os
+
+if os.environ.get('VELOX_SIM') is not None:
+    print("Velox Simulator")
+    from Prober.velox_api.simulator import VeloxSimulator as velox_api
+    from Prober.velox_api.simulator.VeloxSimulator import (MessageServerInterface, SetChuckHome, SetMapHome,
+                                                           ReadChuckPosition, ReadChuckHeights, MoveChuck,
+                                                           SnapImage, GetDieDataAsColRow, StepToDie, ReportKernelVersion)
+else:
+    import Prober.velox_api.velox as velox_api
+    from Prober.velox_api.velox import (MessageServerInterface, SetChuckHome, SetMapHome,
+                                        ReadChuckPosition, ReadChuckHeights, MoveChuck,
+                                        SnapImage, GetDieDataAsColRow, StepToDie, ReportKernelVersion)
+
+from Prober.model.ProberModel import ProberModel as Model
+from Prober.view.ProberControlWindow import ProberControlWindow as ControlWindow
+from Prober.model.ProberModel import ProberSignals as Signals
+from Prober.controller.ProberController import ProberController as Controller
+from Prober.controller.ProberController import Probe as Probe
+from Prober.controller.OpticalProbesPosition import OpticalProbesPosition as ProbePosition
diff --git a/src/FlexSensor/Prober/controller/MapFileParser.py b/src/FlexSensor/Prober/controller/MapFileParser.py
new file mode 100644
index 0000000000000000000000000000000000000000..570944889faa3228452576403bfa3f93a8857ddf
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/MapFileParser.py
@@ -0,0 +1,33 @@
+from pathlib import Path
+
+
+class MapFileParser:
+
+    def __init__(self, path: str):
+        print(path)
+        self._map_path = Path(path)
+        with open(self._map_path, 'r') as file:
+            self.result = self.parse_content(file.read())
+
+    def parse_content(self, content):
+        result = {}
+        current_section = None
+
+        lines = content.split("\n")
+        for line in lines:
+            line = line.strip()
+            if line.startswith("[") and line.endswith("]"):
+                current_section = line[1:-1]
+            elif "=" in line and current_section is not None:
+                key, value = line.split("=", 1)
+                result.setdefault(current_section, {})
+                result[current_section][key] = value
+
+        return result
+
+
+if __name__ == "__main__":
+    parsed_map = MapFileParser("../Wafermapary1_48dies.map")
+    print(parsed_map.result["Header"]["Description"])  # Output: Wafer Map File
+    print(parsed_map.result["Wafer"]["Diameter"])  # Output: 200
+    print(parsed_map.result["Bin"]["0"])  # Output: 1,a0,00C000,1,0,0,0,0
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/controller/OpticalInterface.py b/src/FlexSensor/Prober/controller/OpticalInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d1cb934953988128ad9365d85a7de13305083b2
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/OpticalInterface.py
@@ -0,0 +1,277 @@
+import logging
+
+from Prober.model.OpticalInterfaceModel import OpticalInterfaceModel
+from Prober.model.OpticalInterfaceStoredData import OpticalInterfaceStoredData
+from constants.FlexsensorConstants import Probe
+from generics.generics import pch
+
+
+
+
+
+
+
+
+
+
+
+
+
+class OpticalInterface(object):
+
+    def __init__(self, prober_signals, msg_server):
+        self.stored = OpticalInterfaceStoredData()
+        self.signals = prober_signals
+        self.msg_server = msg_server
+        self.logger = logging.getLogger("Optical Interface")
+        self.logger.info("Optical Interface initialized")
+
+    # ==================================================================================================================
+    # pythonized api calls
+    # ==================================================================================================================
+
+    def enable_flight_height_control(self, enable_in=True, enable_out=True):
+        # Disable Flight Height Control
+        for probe_num, val in enumerate((int(enable_in), int(enable_out))):
+            cmd = 'TrackOpticalProbeHeight'
+            rparams = f"{probe_num} {val}"
+
+            enable = bool(val)
+            enable_desc = 'Enable' if enable else 'Disable'
+            probe_desc = 'first probe/input probe' if probe_num == 0 else 'second probe/output probe'
+            command_desc = f'{cmd}({rparams})'
+            self.logger.info(f"[OptIF Task] - {enable_desc} `Flight Height Control` "
+                             f"for {probe_desc}. Issuing command '{command_desc}'")
+            self.signals.log_info.emit("OptIF", f" {enable_desc} 'Flight Height Control' "
+                                                f"for {probe_desc}.", None)
+            self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+    def set_probe_height(self, probe: int, height):
+        cmd = 'FindOpticalProbeHeight'
+        rparams = f"{probe} {height}"
+
+        probe_desc = 'first probe/input probe' if probe == 0 else 'second probe/output probe'
+        command_desc = f'{cmd}({rparams})'
+
+        self.logger.info(f"[OptIF  Task] - Move {probe_desc} height to {height} um. "
+                         f"Issuing command '{command_desc}'")
+        self.signals.log_info.emit("OptIF  Task", f" Move {probe_desc} height to {height} um.", None)
+        self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+    def move_optical_probe(self, probe: int, x, y, pos_ref='H'):
+        """
+        Move selected probe motor in XY.
+        :param probe 0=Input, 1=Output (I)
+        :param x motor command [um] (D)
+        :param y motor command [um] (D)
+        :param pos_ref R=Relative, H=Home, Z=Zero (C)
+        """
+        cmd = 'MoveOpticalProbe'
+        rparams = f"{probe} {x} {y} {pos_ref}"
+        command_desc = f'{cmd}({rparams})'
+        self.logger.info(f"[OptIF  Task] - Move selected probe motor. "
+                         f"Issuing command '{command_desc}'")
+        self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+    def move_pzt(self, probe: int, x, y, z, pos_ref='H'):
+        """
+        Pythonized command for SiP Remote Interface 'MovePZT'
+        Move selected PZT.
+        :param probe: 0=Input, 1=Output (I)
+        :param x: x PZT command [um] (D)
+        :param y: y PZT command [um] (D)
+        :param z: z PZT command [um] (D)
+        :param pos_ref: PosRef R=Relative, H=Home, Z=Zero (C)
+        """
+        cmd = "MovePZT"
+        rparams = f"{probe} {x} {y} {z} {pos_ref}"
+        self.logger.info(f"[OptIF  Task] - Move selected PZT.")
+        return self._send_command(cmd, rparams=rparams,
+                                  desc=f"{cmd}(probe={probe}, x={x}, y={y}, z={z}, posref={pos_ref})")
+
+    def recenter_optical_probe(self, probe: int):
+        cmd = 'RecenterOpticalProbe'
+        rparams = f"{probe}"
+
+        probe_desc = 'first probe/input probe' if probe == 0 else 'second probe/output probe'
+        command_desc = f'{cmd}({rparams})'
+
+        self.logger.info(f"[OptIF  Task] - Recenter {probe_desc}. "
+                         f"Issuing command '{command_desc}'")
+        self.signals.log_info.emit("OptIF  Task", f"Recenter {probe_desc}.", None)
+
+        self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+    def area_scan(self, probe_in: bool = True, probe_out: bool = True):
+        cmd = 'AreaScan'
+        probe_in, probe_out = (int(probe_in), int(probe_out))
+        rparams = f"{probe_in} {probe_out}"
+
+        if probe_in == 1 and probe_out == 1:
+            probe_desc = 'input and output probe'
+        elif probe_in == 1 and probe_out == 0:
+            probe_desc = 'first probe/input probe'
+        elif probe_in == 0 and probe_out == 1:
+            probe_desc = 'second probe/output probe'
+        else:
+            raise ValueError("area_scan requires at least one probe to be selected.")
+
+        command_desc = f'{cmd}({rparams})'
+
+        self.logger.info(f"[OptIF  Task] - Performing area scan on {probe_desc}. "
+                         f"Issuing command '{command_desc}'")
+        self.signals.log_info.emit("OptIF  Task", f"Performing area scan on {probe_desc}", None)
+
+        x_1, x_2, y_1, y_2, input_power, output_power = self.msg_server.sendSciCommand(cmd, rparams=rparams)
+        return x_1, x_2, y_1, y_2, self.conv_pwr(input_power), self.conv_pwr(output_power)
+
+    def set_optical_probe_home(self, probe: int) -> (int, int, int, int, int, int):
+        cmd = 'SetOpticalProbeHome'
+        rparams = f"{probe}"
+        return self.msg_server.sendSciCommand(cmd, rparams=rparams)
+
+    def read_optical_probe_pos(self, probe, pos_ref='H') -> (float, float, float, float, float, float):
+        """
+        Pythonized command for SiP Remote Interface 'ReadOpticalProbePos'
+        Read optical probe position.
+        :param probe: 0=Input, 1=Output (I)
+        :param pos_ref: H=Home, Z=Zero (C)
+        :return:
+        x1: x motor position [um]
+        y1: y motor position [um]
+        z1: z motor position [um]
+        x2: x motor PZT [um]
+        y2: y PZT position [um]
+        z2: x PZT position [um]
+        """
+        cmd = "ReadOpticalProbePos"
+        rparams = f"{probe} {pos_ref}"
+        self.logger.info(f"[OptIF  Task] - Reading optical probe position. ")
+        return self._send_command(cmd, rparams=rparams, desc=f"{cmd}(probe={probe}, posref={pos_ref})")
+
+
+    # ==================================================================================================================
+    # Custom implementations I
+    # ==================================================================================================================
+    def _send_command(self, cmd: str, rparams: str = None, desc: str = None):
+
+        issuing_command = f'{cmd}({rparams})'
+        if desc is not None:
+            self.logger.debug(f"Issuing command {desc} -> '{issuing_command}'")
+        else:
+            self.logger.debug(f"Issuing command '{issuing_command}'")
+
+        self.signals.log_info.emit("OptIF  Task", f"Issuing command '{issuing_command}'", None)
+        r = self.msg_server.sendSciCommand(cmd, rparams=rparams)
+        self.logger.debug(f"Command returned '{r}'")
+        return r
+
+    # ==================================================================================================================
+    # Custom implementations II
+    # ==================================================================================================================
+    def conv_pwr(self, power: list | str | float | int) -> float:
+            """
+                Area scan return different types for the power values, this function can convert it.
+            """
+            try:
+                if isinstance(power, list):
+                    power = float(power[0])
+                elif isinstance(power, str):
+                    if "na" == power.lower:
+                        power = -80
+                    else:
+                        power = float(power)
+                else:
+                    power = float(power)
+            except Exception as e:
+                power = -80
+                print(f"Cant convert <{power}>: {e}")
+            return float(power)
+
+    def _recenter_and_scan(self) -> (float, float, float, float, float, float):
+        self.recenter_optical_probe(Probe.INPUT)
+        self.recenter_optical_probe(Probe.OUTPUT)
+        x_1, x_2, y_1, y_2, input_power, output_power = self.area_scan(True, True)
+        return float(x_1), float(x_2), float(y_1), float(y_2), self.conv_pwr(input_power), self.conv_pwr(
+            output_power)
+
+    def search_for_light(self, threshold: float = -70, threshold_areascan: float = -60, retries: float = 3):
+        self.logger.debug(f"[OptIF  Task] - {pch('*', 20)} Search for light {pch('*', 20)}")
+        self.signals.log_debug.emit("OptIF  Task", f"*** Search for light ***", None)
+
+        # Recenter the probes, perform an area scan, recenter again.
+        self.logger.info(f"[OptIF  Task] - Recenter optical probes and performing area scan (1/2).")
+        self.signals.log_info.emit("OptIF  Task", f"Recenter optical probes (1/2).", None)
+        self._recenter_and_scan()
+
+        self.logger.info(f"[OptIF  Task] - Recenter optical probes and performing area scan (2/2).")
+        self.signals.log_info.emit("OptIF  Task", f"Recenter optical probes (2/2).", None)
+        x_1, x_2, y_1, y_2, input_power, output_power = self._recenter_and_scan()
+
+        # Now we need to verify the power
+        self.logger.info(f"[OptIF  Task] - Verifying power. Probe input power: {input_power}. "
+                         f"Probe output power {output_power}. "
+                         f"Abortion criteria is {threshold}/{threshold_areascan} or {retries} retries.")
+        self.signals.log_info.emit("OptIF  Task", f"Probe input power: {input_power}. "
+                                                  f"Probe output power {output_power}.", None)
+        while (
+                ((input_power < threshold_areascan and output_power >= threshold) or
+                 (output_power < threshold_areascan and input_power >= threshold)) and
+                retries > 0
+        ):
+            self.logger.info(f"[OptIF  Task] - Input power ({input_power}) or output power ({output_power}) "
+                             f"too low but signal found. Trying area scan again ({retries - 1} "
+                             f"retrie(s) left). Threshold is {threshold_areascan}")
+            self.signals.log_info.emit("OptIF  Task",
+                                       f"Input power ({input_power}) or output power ({output_power}) "
+                                       f"too low but signal found. ", None)
+            x_1, x_2, y_1, y_2, input_power, output_power = self._recenter_and_scan()
+            retries -= 1
+
+        self.logger.debug(f"[OptIF  Task] - {pch('*', 20)} Search for light completed {pch('*', 20)}")
+        self.signals.log_debug.emit("OptIF  Task", f"*** Search for light completed***", None)
+        return input_power, output_power
+
+    # ==================================================================================================================
+    # Store and load functions
+    # ==================================================================================================================
+    def store_optical_probe_motor_pos(self) -> (float, float, float, float, float, float):
+        """
+        Stores the current motor position of the optical probe .
+        """
+        self.stored.motor_in_x, self.stored.motor_in_y, self.stored.motor_in_z, \
+            _, _, _ = self.read_optical_probe_pos(0)
+
+        self.stored.motor_out_x, self.stored.motor_out_y, self.stored.motor_out_z, \
+            _, _, _ = self.read_optical_probe_pos(1)
+
+    def store_optical_probe_pzt_pos(self) -> (float, float, float, float, float, float):
+        """
+        Stores the current PZT position of the optical probe .
+        """
+        _, _, _, self.stored.pzt_in_x, self.stored.pzt_in_y, self.stored.pzt_in_z = self.read_optical_probe_pos(0)
+
+        _, _, _, self.stored.pzt_out_x, self.stored.pzt_out_y, self.stored.pzt_out_z = self.read_optical_probe_pos(1)
+
+    def store_optical_probe_pos(self) -> (float, float, float, float, float, float):
+        """
+        Stores the current motor position of the optical probe .
+        """
+        self.stored.motor_in_x, self.stored.motor_in_y, self.stored.motor_in_z, \
+        self.stored.pzt_in_x, self.stored.pzt_in_y, self.stored.pzt_in_z = self.read_optical_probe_pos(0)
+
+        self.stored.motor_out_x, self.stored.motor_out_y, self.stored.motor_out_z, \
+        self.stored.pzt_out_x, self.stored.pzt_out_y, self.stored.pzt_out_z = self.read_optical_probe_pos(1)
+
+    def restore_optical_probe_motor_pos(self, probe: int) -> (float, float, float, float, float, float):
+        self.move_optical_probe(probe, self.stored.motor_in_x, self.stored.motor_in_y, pos_ref='H')
+        return self.read_optical_probe_pos(probe)
+
+    def restore_optical_probe_pzt_pos(self, probe: int) -> (float, float, float, float, float, float):
+        self.move_pzt(probe, self.stored.pzt_in_x, self.stored.pzt_in_y, self.stored.pzt_in_z, pos_ref='H')
+        return self.read_optical_probe_pos(probe)
+
+    # ==================================================================================================================
+    # Store and load functions
+    # ==================================================================================================================
+
diff --git a/src/FlexSensor/Prober/controller/OpticalProbesPosition.py b/src/FlexSensor/Prober/controller/OpticalProbesPosition.py
new file mode 100644
index 0000000000000000000000000000000000000000..19e061486ebbf6887f9f7ad90bfd226d4b8d5b34
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/OpticalProbesPosition.py
@@ -0,0 +1,27 @@
+import sys
+import logging
+
+
+class OpticalProbesPosition:
+
+    def __init__(self, input: tuple, output: tuple):
+        self.INPUT: ProbePosition = ProbePosition(input)
+        self.OUT: ProbePosition = ProbePosition(output)
+        self.logger = logging.getLogger('OpticalProbesPosition')
+
+
+    def __str__(self):
+        return f"INPUT: {self.INPUT} | OUT: {self.OUT}"
+
+
+class ProbePosition:
+
+    def __init__(self, position: tuple):
+        self.x, self.y, self.z = position
+
+    def __str__(self):
+        return f"x:{self.x} - y:{self.y} - z:{self.z}"
+    
+    def __substract__(self, other):
+        pass
+
diff --git a/src/FlexSensor/Prober/controller/ProberController.py b/src/FlexSensor/Prober/controller/ProberController.py
new file mode 100644
index 0000000000000000000000000000000000000000..7486b757787535dd513f8cdd5fdc2d9c975cb130
--- /dev/null
+++ b/src/FlexSensor/Prober/controller/ProberController.py
@@ -0,0 +1,411 @@
+import logging
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from Prober.controller.OpticalInterface import OpticalInterface
+import Prober
+from Prober.model.ProberModel import ProberModel
+from constants.FlexsensorConstants import Probe
+from generics.generics import pch
+
+
+class ProberController:
+    def __init__(self, model: ProberModel, vaut_config: VAutomatorConfig, *args, **kwargs):
+
+        self.vaut_config = vaut_config
+        self.model = model
+
+        self.model.wafer_map = self.vaut_config.wafer_config.wafermap_file
+
+        self.logger = logging.getLogger("Prober")
+        self.signals = Prober.Signals()
+        self.msg_server = Prober.MessageServerInterface()
+
+        # Optical Interface Control hexapods and piezos
+        self.opt_if = OpticalInterface(self.signals, self.msg_server)
+        self.logger.info("Prober initialized")
+
+        self.model.version = self.report_kernel_version()
+        self.get_die_as_col_row()
+        self.read_chuck_position()
+        self.model.connected = True
+
+    # ==================================================================================================================
+    # Velox API Calls.
+    # Some Wrappers to the official Velox API calls
+    # ==================================================================================================================
+    def set_chuck_home(self, mode: str = '0', unit: str = 'Y', x_value: float = 0, y_value: float = 0):
+        """ Velox API Call. Sets wafer and die home position, which can be used later as coordinate system
+        for movements.
+        Keyword arguments:
+            mode: str -- '0' use the current position or the given value otherwise. (default "0")
+            unit: str -- Sets the unit (Y: 'Microns' or I 'Mils'). Required if mode is not set to default (Y).
+                (default 'Microns')
+            x_value: float -- Required if mode is not set to V. (default 0)
+            y_value: float -- Required if mode is not set to V. (default 0)
+        Command Timeout: 5000
+        """
+        self.logger.info(f"[Prober Task] - Set Chuck home. Issuing command 'SetChuckHome({mode})'")
+        self.signals.log_info.emit("Prober Report", f"Set Chuck Home.", None)
+        Prober.SetChuckHome(str(mode), str(unit), x_value, y_value)
+
+    def set_map_home(self, col=0, row=0):
+        """ Velox API Call. If the command has no parameters it sets the current position as home position
+            both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+            home position using the given die coordinates.
+            Keyword arguments:
+                col: int -- Column (optional). (default 0)
+                row: int -- Row (optional). (default 0)
+            Command Timeout: 10000
+        """
+        self.logger.info(f"[Prober Task] - Set Map home to col {col} and row {row}. "
+                         f"Issuing command 'SetMapHome({col}, {row})'")
+        self.signals.log_info.emit("Prober Report", f"Map Home set to {col}, {row}.", None)
+        Prober.SetMapHome(col, row)
+
+    def read_chuck_position(self, unit: str = "Microns", pos_ref: str = "Home", comp: str = "Default") -> (float, float, float):
+        """ Velox API Call. Returns the current chuck stage position in X, Y and Z.
+        Args:
+            unit:str = "Microns"
+            pos_ref:str = "Home"
+            comp:str = "Default"
+        Returns:
+            X:float
+            Y:float
+            Z:float
+        Command Timeout: 5000
+        """
+        self.model._chuck_x, self.model._chuck_y, self.model._chuck_z = Prober.ReadChuckPosition(Unit=unit, PosRef=pos_ref)
+        self.logger.info(f"[Prober Report] - "
+                         f"Current Chuck position X:{self.model._chuck_x} Y:{ self.model._chuck_y} Z:{self.model._chuck_z}")
+        self.signals.log_info.emit("Prober Report",
+                                   f"Current Chuck position "
+                                   f"X:{self.model._chuck_x} "
+                                   f"Y:{ self.model._chuck_y} "
+                                   f"Z:{self.model._chuck_z}", None)
+        return float(self.model._chuck_x), float(self.model._chuck_y), float(self.model._chuck_z)
+
+    def check_contact_height_set(self) -> (float, float, float, float, float):
+        """ Velox API Call. Returns the current settings used for the chuck Z movement. `Contact` is the
+            contact-height from zero in default compensation. The other heights are relative
+            to this. If no contact is set, an error will be raised.
+            API Status: published
+            Args:
+                Unit:str = "Microns"
+            Returns:
+                Contact:Decimal
+                Overtravel:Decimal
+                AlignDist:Decimal
+                SepDist:Decimal
+                SearchGap:Decimal
+            Command Timeout: 5000
+        """
+        self.logger.debug("[Prober Task] - Check if contact height is set. Issuing command 'ReadChuckHeights'")
+        self.signals.log_debug.emit("Prober Task", "Check if contact height is set. Issuing command 'ReadChuckHeights'",
+                                    None)
+        contact, overtravel, align_dist, sep_dis, search_gap = Prober.ReadChuckHeights()
+
+        if contact == -1:
+            self.logger.error("[Prober Task] - Contact height not set, please set it before running this script. "
+                              "Script will be stopped.")
+            raise Exception("Contact height not set, please set it before running this script. Script will be stopped.")
+
+        self.logger.debug(f"[Prober Task] - Contact height set to {contact}")
+        self.signals.log_debug.emit("Prober Task", f"Contact height set to {contact}", None)
+
+        return float(contact), float(overtravel), float(align_dist), float(sep_dis), float(search_gap)
+
+    def move_chuck(self, x_value: float = 0, y_value: float = 0,
+                   pos_ref: str = "H", unit: str = "Y", velocity: float = 100, comp: str = "D"):
+        """ Velox API Call. Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+           height or higher, Interlock and Auto Z flags will be analyzed and stage will
+           behave correspondingly - can move to separation first or return an error:
+           Keyword arguments:
+               x_value:float -- X Value (optional). (default 0)
+               y_value:float -- Y Value (optional). (default 0)
+               pos_ref:str -- "H: Home", "Z: Zero", "C: Center", "R: Current Position". (default "H: Home")
+               unit:str -- "Y: Microns", "I: Mils", "X: Index", "J: Jog". (default "M: Microns")
+               velocity:float -- Velocity in percent. (default 100)
+               comp:str
+                    "D: Default": Use the default compensation. Uses "Technology" by default.
+                    "T: Technology": Use Prober, offset and Technology compensation. (default)
+                    "O: Offset": Use Prober and Offset compensation.
+                    "P: Prober" Use only Prober compensation.
+                    "N: None": Does not use compensation.
+                (default "D: Default")
+           Command Timeout: 30000
+           """
+        self.logger.debug(f"[Prober Task] - Move Chuck to x: {x_value} y: {y_value}. "
+                          f"Issuing command 'MoveChuck({x_value}, {y_value}, {pos_ref}, {unit}, {velocity}, {comp})'")
+        self.signals.log_debug.emit("Prober Task", f"Move Chuck to x: {x_value} y: {y_value}", None)
+        Prober.MoveChuck(x_value, y_value, pos_ref, unit, velocity, comp)
+
+    def snap_image(self, mount_pos: str = "eVue2", full_path: str = "./Image.bmp", snap_shot_mode: int = 2):
+        """
+            Velox API Call. Saves the currently displayed image to the specified file. The image is stored
+            in the requested file format (bmp, jpg or png). By default. it will save the raw
+            camera image and an image with the overlays that are currently visible on the
+            camera view. Using a parameter, one can decide to only save either raw image,
+            overlay image or both. By Specifying 'ALL' as the mount position, the captured
+            screenshot will consist of the currently selected camera layout without
+            providing the raw image. If MountPos and FullPath are empty then the current
+            camera view with overlays is copied to the clipboard.
+            API Status: published
+            Args:
+                mount_pos:str -- Mount position of camera from which the image will be taken:
+                    'Scope', 'eVue1', 'eVue2', 'eVue3', 'Chuck', 'Platen', 'ContactView', or 'All'.
+                    (default "eVue2")
+
+                    (If you use ‘Scope’ on a system with eVue, the image will be from eVue2).
+                    If set to ‘All’ the currently visible camera layout will be captured in the screenshot
+                    "eVue2".
+                full_path:str -- Path where the image will be stored. (default: "./Image.bmp")
+                snap_shot_mode:int -- Type of snapshot (default 2)
+                    0 – Raw Image from camera
+                    1 – Screenshot of camera window including overlays;
+                    2 – Both images
+            Example:SnapImage Scope C:/Temp/Image.bmp
+            """
+        self.logger.debug(f"[Prober Task] - Save scope image {mount_pos} to {full_path} (mode: {snap_shot_mode}). "
+                          f"Issuing command 'SnapImage({mount_pos}, {full_path}, {snap_shot_mode})'")
+        self.signals.log_debug.emit("Prober Task",
+                                    f"Save scope image {mount_pos} to {full_path} (mode: {snap_shot_mode}).", None)
+        Prober.SnapImage(mount_pos, full_path, snap_shot_mode)
+
+    def report_kernel_version(self):
+        v = Prober.ReportKernelVersion()
+        self.model.kernel_version = str(v.Version) + "." + str(v.Description)
+        return str(v.Version) + "." + str(v.Description)
+
+    def get_die_as_col_row(self):
+        # Read the die data: die number, col, row
+        self.model.die, self.model.die_col, self.model.die_row, bin, res = Prober.GetDieDataAsColRow()
+        self.logger.info(f"[Prober Report] - Current die number: {self.model.die} "
+                         f"(col: {self.model.die_col}, row: {self.model.die_row})")
+        self.signals.log_info.emit("Prober Report", f"Current die number: {self.model.die} "
+                                                    f"(col: {self.model.die_col}, row: {self.model.die_row})", None)
+        return self.model.die, self.model.die_col, self.model.die_row
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def move_to_die(self, die_num=0) -> (float, float, float):
+        '''
+        Move to the specified die and sets the home position accordingly
+        '''
+
+        # TODO: check if die is in the correct position and check if height is correct
+        self.logger.debug(f"[Prober Task] - {pch('*', 20)} Moving to die {die_num} {pch('*', 20)}")
+        self.signals.log_debug.emit("Prober Task", f"*** Moving to die {die_num} ***", None)
+
+        # We need to make sure that our fiber height is correct
+        # TODO: Check fiber height - this is important! IMPLEMENT HERE
+        # ...
+        # ...
+        # raise NotImplementedError("Check fiber hight not implemented yet")
+
+        # Move to die
+        # Disable the flight height control
+        self.opt_if.enable_flight_height_control(enable_in=False, enable_out=False)
+
+        # FindOpticalProbeHeight(0, 100)
+        # FindOpticalProbeHeight(1, 100)
+
+        # Step to the specified die
+        self.logger.info(f"[Prober Task] - Step to the specified die {die_num}. Issuing command 'StepToDie({die_num})'")
+        self.signals.log_info.emit("Prober Task", f"Step to the specified die {die_num}", None)
+        Prober.StepToDie(die_num)
+
+        # Move hexapod and nano to height 50 um
+        height = 80
+        self.opt_if.set_probe_height(Probe.INPUT, height)
+        self.opt_if.set_probe_height(Probe.OUTPUT, height)
+
+        # Read the die data: die number, col, row
+        self.model.die, self.model.die_col, self.model.die_row = self.get_die_as_col_row()
+
+        # Set the current chuck and map to home
+        self.set_chuck_home()
+        self.set_map_home(self.model.die_col, self.model.die_row)
+
+        # For reducing errors, read the chuck position
+        self.model._chuck_x, self.model._chuck_y, self.model._chuck_z = self.read_chuck_position(unit="Microns", pos_ref="Home")
+
+        self.logger.info(f"[Prober Task] - {pch('*', 20)} MOVING TO DIE COMPLETE {pch('*', 20)}")
+        self.signals.log_info.emit("Prober Report", f"MOVING TO DIE COMPLETE", None)
+        return self.model.die, self.model.die_col, self.model.die_row
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+
+    def try_finding_light(self, input_power, output_power, threshold=-70):
+        ran_in = [0, 5, -5, 10, -10, 15, -15, 20, -20, 25, 30, 35, 40, -25, -30, -35, -40]
+        ran_out = ran_in
+        # steps = 5
+
+        input_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='0')
+        input_power = self.conv_result_power(input_power)
+
+        output_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='1')
+        output_power = self.conv_result_power(output_power)
+
+        for x_pos_1 in ran_in:
+            for y_pos_1 in ran_in:
+                try:
+                    self.msg_server.sendSciCommand("MoveOpticalProbe",
+                                                   rparams='0 %s %s R' % ((float(x_pos_1)), (float(y_pos_1))))
+                except Exception as e:
+                    self.write_log("error", "Can't move probe to (%s, %s)" % (x_pos_1, y_pos_1))
+                    self.write_log("error", e)
+                    continue
+
+                for x_pos_2 in ran_out:
+                    for y_pos_2 in ran_out:
+                        self.write_log("debug",
+                                       f"{self.formatter} Moving realtivly: Probe 1 X({float(x_pos_1)}) Y({float(y_pos_1)}) "
+                                       f"| Probe 2  X({float(x_pos_2)}) Y({float(y_pos_2)}) | Power I:{input_power} O:{output_power}")
+
+                        self.msg_server.sendSciCommand("MoveOpticalProbe",
+                                                       rparams='1 %s %s R' % ((float(x_pos_2)), (float(y_pos_2))))
+
+                        input_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='0')
+                        output_power = self.msg_server.sendSciCommand("ReadOpticalProbePowerMeter", rparams='1')
+                        input_power = self.conv_result_power(input_power)
+                        output_power = self.conv_result_power(output_power)
+
+                        if (float(input_power) > -72) or (float(output_power) > -72):
+                            try:
+                                self.msg_server.sendSciCommand("AreaScan", rparams='1 1')
+                                self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='0')
+                                self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='1')
+                                self.msg_server.sendSciCommand("AreaScan", rparams='1 1')
+                                self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='0')
+                                self.msg_server.sendSciCommand("RecenterOpticalProbe", rparams='1')
+                                self.msg_server.sendSciCommand("AreaScan", rparams='1 1')
+                                if (float(input_power) > threshold) or (float(output_power) > threshold):
+                                    self.write_log("debug", f"Power I:{input_power} O:{output_power}. Continuing.")
+                                    return True
+                            except Exception as e:
+                                self.write_log(f"warning {e}")
+
+                        self.write_log("debug",
+                                       f"{self.formatter} Moving back: Probe 1 X({(-1) * float(x_pos_1)}) Y({(-1) * float(y_pos_1)}) "
+                                       f"| Probe 2  X({(-1) * float(x_pos_2)}) Y({(-1) * float(y_pos_2)}) | Power I:{input_power} O:{output_power}")
+                        self.msg_server.sendSciCommand("MoveOpticalProbe", rparams='0 %s %s R' % (
+                            ((-1) * float(x_pos_1)), ((-1) * float(y_pos_1))))
+                        self.msg_server.sendSciCommand("MoveOpticalProbe", rparams='1 %s %s R' % (
+                            ((-1) * float(x_pos_2)), ((-1) * float(y_pos_2))))
+
+        self.write_log("warning", "No light found.")
+        return False
+
+    def store_hexapod_position():
+        """
+            Stores the hexpods and nanocube position for later retrieval
+        """
+        pass
+
+
+    # msgServer.sendSciCommand("MoveOpticalProbe", rparams='0 %s %s R' % ( (-1)*(float(x_pos_1)), (-1)*(float(y_pos_1))))
+
+    def get_hexapod_values(self):
+        # before performing an area scan, store the current position
+        try:
+            motor_x_1, motor_y_1, motor_z_1, pzt_x_1, pzt_y_1, pzt_z_1 = self.msg_server.sendSciCommand(
+                "ReadOpticalProbePos", rparams='0 H')
+            motor_x_2, motor_y_2, motor_z_2, pzt_x_2, pzt_y_2, pzt_z_2 = self.msg_server.sendSciCommand(
+                "ReadOpticalProbePos", rparams='1 H')
+            self.write_log("info",
+                           "([%s]: %s): Storing reference values for motor 1 (%s, %s, %s) Storing values for PZT 1 (%s, %s, %s). "
+                           % (self.die_no, self.structure, motor_x_1, motor_y_1, motor_z_1, pzt_x_1, pzt_y_1, pzt_z_1)
+                           )
+            self.write_log("info",
+                           "([%s]: %s): Storing reference values for motor 2 (%s, %s, %s) Storing values for PZT 2 (%s, %s, %s). "
+                           % (self.die_no, self.structure, motor_x_2, motor_y_2, motor_z_2, pzt_x_2, pzt_y_2, pzt_z_2)
+                           )
+        except Exception as e:
+            self.write_log("warning", "([%s]: %s): Can't store reference values for motor 1 and 2." % (
+                self.die_no, self.structure))
+            self.write_log("warning", e)
+
+        motor_pos = {
+            'motor_1': {
+                'x': motor_x_1, 'y': motor_y_1, 'z': motor_z_1
+            },
+            'motor_2': {
+                'x': motor_x_2, 'y': motor_y_2, 'z': motor_z_2
+            }
+        }
+
+        pzt_pos = {
+            'pzt_1': {
+                'x': pzt_x_1, 'y': pzt_y_1, 'z': pzt_z_1
+            },
+            'pzt_2': {
+                'x': pzt_x_2, 'y': pzt_y_2, 'z': pzt_z_2
+            }
+        }
+
+        return motor_pos, pzt_pos
+
+    def _write_debug(self, description, title=None, details=None):
+        if details is None and title is None:
+            self.logger.debug(f"{description}.")
+            self.signals.log_debug.emit(None, description, None)
+        elif details is not None and title is None:
+            self.logger.debug(f"{description}: {details}")
+            self.signals.log_debug.emit(None, description, details)
+        elif details is None and title is not None:
+            self.logger.debug(f"[{title}] - {description}")
+            self.signals.log_debug.emit(None, description, None)
+        else:
+            self.logger.debug(f"[{title}] - {description}: {details}")
+            self.signals.log_debug.emit(title, description, details)
+
+    def _write_info(self, description, title=None, details=None):
+        if details is None and title is None:
+            self.logger.info(f"{description}.")
+            self.signals.log_info.emit(None, description, None)
+        elif details is not None and title is None:
+            self.logger.info(f"{description}: {details}")
+            self.signals.log_info.emit(None, description, details)
+        elif details is None and title is not None:
+            self.logger.info(f"[{title}] - {description}")
+            self.signals.log_info.emit(None, description, None)
+        else:
+            self.logger.info(f"[{title}] {description}: {details}")
+            self.signals.log_info.emit(title, description, details)
+
+    def _write_warning(self, description, title=None, details=None):
+        if details is None and title is None:
+            self.logger.warning(f"{description}.")
+            self.signals.log_warning.emit(None, description, None)
+        elif details is not None and title is None:
+            self.logger.warning(f"{description}: {details}")
+            self.signals.log_warning.emit(None, description, details)
+        elif details is None and title is not None:
+            self.logger.warning(f"[{title}] - {description}")
+            self.signals.log_warning.emit(None, description, None)
+        else:
+            self.logger.warning(f"[{title}] - {description}: {details}")
+            self.signals.log_warning.emit(title, description, details)
+
+    def _write_error(self, description, title=None, details=None):
+        if details is None and title is None:
+            self.logger.error(f"{description}.")
+            self.signals.log_error.emit(None, description, None)
+        elif details is not None and title is None:
+            self.logger.error(f"{description}: {details}")
+            self.signals.log_error.emit(None, description, details)
+        elif details is None and title is not None:
+            self.logger.error(f"[{title}] - {description}")
+            self.signals.log_error.emit(None, description, None)
+        else:
+            self.logger.error(f"{title}. {description}: {details}")
+            self.signals.log_error.emit(title, description, details)
+
+    # ==================================================================================================================
+    #
+    # ==================================================================================================================
+    def __del__(self):
+        self.msg_server.__exit__()
+        self.logger.info("Message Server closed!")
diff --git a/src/FlexSensor/Prober/model/OpticalInterfaceModel.py b/src/FlexSensor/Prober/model/OpticalInterfaceModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..ecd51bbe534740b116077af4914d21a76c25b512
--- /dev/null
+++ b/src/FlexSensor/Prober/model/OpticalInterfaceModel.py
@@ -0,0 +1,25 @@
+class OpticalInterfaceSignals():
+    pass
+
+
+
+class OpticalInterfaceModel():
+    def __init__(self):
+        # Motor position
+        self._motor_out_x: float = 0.0
+        self._motor_out_y: float = 0.0
+        self._motor_out_z: float = 0.0
+
+        self._motor_in_x: float = 0.0
+        self._motor_in_y: float = 0.0
+        self._motor_in_z: float = 0.0
+
+        # PZT position
+        self._pzt_out_x: float = 0.0
+        self._pzt_out_y: float = 0.0
+        self._pzt_out_z: float = 0.0
+
+        self._pzt_in_x: float = 0.0
+        self._pzt_in_y: float = 0.0
+        self._pzt_in_z: float = 0.0
+
diff --git a/src/FlexSensor/Prober/model/OpticalInterfaceStoredData.py b/src/FlexSensor/Prober/model/OpticalInterfaceStoredData.py
new file mode 100644
index 0000000000000000000000000000000000000000..6fd4b13302a1b614ac01368aebc4e164d76d4aa2
--- /dev/null
+++ b/src/FlexSensor/Prober/model/OpticalInterfaceStoredData.py
@@ -0,0 +1,116 @@
+class OpticalInterfaceStoredData:
+    def __init__(self):
+        self._motor_out_x: float = 0.0
+        self._motor_out_y: float = 0.0
+        self._motor_out_z: float = 0.0
+
+        self._motor_in_x: float = 0.0
+        self._motor_in_y: float = 0.0
+        self._motor_in_z: float = 0.0
+
+        # PZT position
+        self._pzt_out_x: float = 0.0
+        self._pzt_out_y: float = 0.0
+        self._pzt_out_z: float = 0.0
+
+        self._pzt_in_x: float = 0.0
+        self._pzt_in_y: float = 0.0
+        self._pzt_in_z: float = 0.0
+
+    @property
+    def motor_out_x(self):
+        return self._motor_out_x
+
+    @motor_out_x.setter
+    def motor_out_x(self, value):
+        self._motor_out_x = value
+
+    @property
+    def motor_out_y(self):
+        return self._motor_out_y
+
+    @motor_out_y.setter
+    def motor_out_y(self, value):
+        self._motor_out_y = value
+
+    @property
+    def motor_out_z(self):
+        return self._motor_out_z
+
+    @motor_out_z.setter
+    def motor_out_z(self, value):
+        self._motor_out_z = value
+
+    @property
+    def motor_in_x(self):
+        return self._motor_in_x
+
+    @motor_in_x.setter
+    def motor_in_x(self, value):
+        self._motor_in_x = value
+
+    @property
+    def motor_in_y(self):
+        return self._motor_in_y
+
+    @motor_in_y.setter
+    def motor_in_y(self, value):
+        self._motor_in_y = value
+
+    @property
+    def motor_in_z(self):
+        return self._motor_in_z
+
+    @motor_in_z.setter
+    def motor_in_z(self, value):
+        self._motor_in_z = value
+
+    @property
+    def pzt_out_x(self):
+        return self._pzt_out_x
+
+    @pzt_out_x.setter
+    def pzt_out_x(self, value):
+        self._pzt_out_x = value
+
+    @property
+    def pzt_out_y(self):
+        return self._pzt_out_y
+
+    @pzt_out_y.setter
+    def pzt_out_y(self, value):
+        self._pzt_out_y = value
+
+    @property
+    def pzt_out_z(self):
+        return self._pzt_out_z
+
+    @pzt_out_z.setter
+    def pzt_out_z(self, value):
+        self._pzt_out_z = value
+
+    @property
+    def pzt_in_x(self):
+        return self._pzt_in_x
+
+    @pzt_in_x.setter
+    def pzt_in_x(self, value):
+        self._pzt_in_x = value
+
+    @property
+    def pzt_in_y(self):
+        return self._pzt_in_y
+
+    @pzt_in_y.setter
+    def pzt_in_y(self, value):
+        self._pzt_in_y = value
+
+    @property
+    def pzt_in_z(self):
+        return self._pzt_in_z
+
+    @pzt_in_z.setter
+    def pzt_in_z(self, value):
+        self._pzt_in_z = value
+
+
diff --git a/src/FlexSensor/Prober/model/ProberModel.py b/src/FlexSensor/Prober/model/ProberModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..4552abbd0ae40a995bc1e89af7215d52dea2d836
--- /dev/null
+++ b/src/FlexSensor/Prober/model/ProberModel.py
@@ -0,0 +1,164 @@
+from pathlib import Path
+
+from PySide6.QtCore import QObject, Signal
+
+from MeasurementData.Properties.WaferProperties import WaferProperties
+
+
+class ProberSignals(QObject):
+    '''
+      Defines the signals available from a running prober thread.
+      The signals are always constructed for proagating it's status
+      to a Message Bix with
+      Signal(title, description, details)
+      '''
+
+    connected_changed = Signal(bool)
+    version_changed = Signal(str)
+    wafer_map_changed = Signal(Path)
+
+    die_changed = Signal(int)
+    curr_die_row_changed = Signal(int)
+    curr_die_col_changed = Signal(int)
+
+    chuck_x_changed = Signal(float)
+    chuck_z_changed = Signal(float)
+    chuck_y_changed = Signal(float)
+
+    errors_changed = Signal(list)
+    warnings_changed = Signal(list)
+
+
+
+
+    log_debug = Signal(str, str, str)
+    log_info = Signal(str, str, str)
+    log_warning = Signal(str, str, str)
+    log_error = Signal(str, str, str)
+
+
+class ProberModel:
+
+    def __init__(self):
+        self.signals = ProberSignals()
+
+        self._connected: bool = False
+        self._version: str = "Unknown Version"
+
+        self._die: int = 0
+        self._die_row: int = 0
+        self._die_col: int = 0
+
+        self._chuck_x: float = 0
+        self._chuck_y: float = 0
+        self._chuck_z: float = 0
+
+        self._errors: list = []
+        self._warnings: list = []
+
+        self._wafer_map = None
+
+    @property
+    def laser_properties(self) -> WaferProperties:
+        return WaferProperties(self.acceleration,
+                               self.deceleration,
+                               self.velocity,
+                               (self.sweep_start_wavelength, self.sweep_stop_wavelength))
+    @property
+    def connected(self) -> bool:
+        return self._connected
+
+    @connected.setter
+    def connected(self, value: bool):
+        self._connected = value
+        self.signals.connected_changed.emit(value)
+
+    @property
+    def version(self) -> str:
+        return self._version
+
+    @version.setter
+    def version(self, value: str):
+        self._version = value
+        self.signals.version_changed.emit(value)
+
+    @property
+    def wafer_map(self) -> Path:
+        return self._wafer_map
+
+    @wafer_map.setter
+    def wafer_map(self, value: Path):
+        self._wafer_map = value
+        self.signals.wafer_map_changed.emit(value)
+
+    @property
+    def die(self) -> int:
+        return self._die
+
+    @die.setter
+    def die(self, value: int):
+        self._die = value
+        self.signals.die_changed.emit(value)
+
+    @property
+    def die_row(self) -> int:
+        return self._die_row
+
+    @die_row.setter
+    def die_row(self, value: int):
+        self._die_row = value
+        self.signals.curr_die_row_changed.emit(value)
+
+    @property
+    def die_col(self) -> int:
+        return self._die_col
+
+    @die_col.setter
+    def die_col(self, value: int):
+        self._die_col = value
+        self.signals.curr_die_col_changed.emit(value)
+
+    @property
+    def chuck_x(self) -> float:
+        return self._chuck_x
+
+    @chuck_x.setter
+    def chuck_x(self, value: float):
+        self._chuck_x = float(value)
+        self.signals.chuck_x_changed.emit(self._chuck_x)
+
+    @property
+    def chuck_y(self) -> float:
+        return self._chuck_y
+
+    @chuck_y.setter
+    def chuck_y(self, value: float):
+        self._chuck_y = float(value)
+        self.signals.chuck_y_changed.emit(self._chuck_y)
+
+    @property
+    def chuck_z(self) -> float:
+        return self._chuck_z
+
+    @chuck_z.setter
+    def chuck_z(self, value: float):
+        self._chuck_z = float(value)
+        self.signals.chuck_z_changed.emit(self.chuck_z)
+
+    @property
+    def errors(self) -> list:
+        return self._errors
+
+    @errors.setter
+    def errors(self, value: list):
+        self._errors = value
+        self.signals.errors_changed.emit(value)
+
+    @property
+    def warnings(self) -> list:
+        return self._warnings
+
+    @warnings.setter
+    def warnings(self, value: list):
+        self._warnings = value
+        self.signals.warnings_changed.emit(value)
diff --git a/src/FlexSensor/Prober/model/WaferProperties.py b/src/FlexSensor/Prober/model/WaferProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..1038b55c5b3be60812bf4d418ba77517815ba0e0
--- /dev/null
+++ b/src/FlexSensor/Prober/model/WaferProperties.py
@@ -0,0 +1,94 @@
+import numpy as np
+from numpy import ndarray
+
+from generics.GenericProperties import GenericProperties
+
+
+class WaferProperties(GenericProperties):
+    def __init__(self,
+                 wafer_number: str, structure_name: str,
+                 die_nr: int, chuck_col: int, chuck_row: int,
+                 structure_in: tuple, structure_out: tuple,
+                 repetitions: int
+                 ):
+        super().__init__()
+        self._structure_name = self.to_str(structure_name)
+        self._wafer_number = self.to_str(wafer_number)
+
+        self._die_number = self.to_int(die_nr[0])
+        self._chuck_col = self.to_int(chuck_col[0])
+        self._chuck_row = self.to_int(chuck_row[0])
+
+        self._structure_in = self.to_tuple(structure_in)
+        self._structure_out = self.to_tuple(structure_out)
+        self._structure_x_in = int(self._structure_in[0])
+        self._structure_y_in = int(self._structure_in[1])
+        self._structure_x_out = int(self._structure_out[0])
+        self._structure_y_out = int(self._structure_out[1])
+
+        self._repetitions: int = self.to_int(repetitions)
+
+    @property
+    def repetition(self):
+        return int(self._repetitions)
+
+    @property
+    def chuck_col(self):
+        return int(self._chuck_col)
+
+    @property
+    def chuck_row(self):
+        return int(self._chuck_row)
+
+    @property
+    def wafer_number(self) -> str:
+        return str(self._wafer_number)
+
+    @property
+    def structure_x_in(self):
+        return int(self._structure_x_in)
+
+    @property
+    def structure_y_in(self):
+        return int(self._structure_y_in)
+
+    @property
+    def structure_x_out(self):
+        return int(self._structure_x_out)
+
+    @property
+    def structure_name(self):
+        return str(self._structure_name)
+
+    @property
+    def die_number(self) -> int:
+        return int(self._die_number)
+
+    @property
+    def structure_y_out(self):
+        return int(self._structure_y_out)
+
+    @property
+    def structure_in(self):
+        return tuple(self._structure_in)
+
+    @property
+    def structure_out(self):
+        return tuple(self._structure_out)
+
+    @property
+    def chuck_row(self):
+        return int(self._chuck_row)
+
+    def fields(self) -> dict:
+        return {
+            'wafer_number': self.wafer_number,
+            'die_number': self.die_number,
+            'structure_name': self.structure_name,
+            'repetition': self.repetition,
+            'structure_in': self.structure_in,
+            'structure_out': self.structure_out,
+            'chuck_col': self.chuck_col,
+            'chuck_row': self.chuck_row
+
+        }
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/velox_api/MANIFEST.in b/src/FlexSensor/Prober/velox_api/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..f592b1ce090a55402214a78fad5143a82491c31c
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/MANIFEST.in
@@ -0,0 +1,5 @@
+include README.rst
+include readme.txt
+include Velox Python Interface.rtf
+include velox/samples/*
+include velox/sci/*
diff --git a/src/FlexSensor/Prober/velox_api/PKG-INFO b/src/FlexSensor/Prober/velox_api/PKG-INFO
new file mode 100644
index 0000000000000000000000000000000000000000..93ab8ec31d442401d75ee1f3672a53e5c9359ab9
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/PKG-INFO
@@ -0,0 +1,10 @@
+Metadata-Version: 1.0
+Name: velox
+Version: 3.0.0.266
+Summary: Python 2.7+ and 3.5+ interface for Velox
+Home-page: UNKNOWN
+Author: Formfactor
+Author-email: UNKNOWN
+License: See Formfactor Velox Product License.
+Description: UNKNOWN
+Platform: UNKNOWN
diff --git a/src/FlexSensor/Prober/velox_api/README.rst b/src/FlexSensor/Prober/velox_api/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7e8b3f301ecfd8f8f8af7929f1953d1e74f4e672
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/README.rst
@@ -0,0 +1,29 @@
+Installation
+===============
+Copy the velox.tar.gz file to a convenient location and open a command prompt there.
+
+To install, use PIP:
+> python -m pip install velox.tar.gz
+
+NOTE: You must use the full file extension to avoid getting any modules named 
+Velox from the public Python repository.
+
+Usage Overview
+===============
+The velox folder contains the modules for interfacing with the Velox Message Server APIs
+via SCI Commands (see documentation for the Velox Integration Toolkit).
+
+This folder contains the ``__init__.py`` file that automatically imports the correct 
+module based on the version of Python running at the time. 
+
+Your code should:
+------------------
+
+``import velox``
+
+The __init__.py will load an SCI module appropriate for either Python 2.7+ or Python 3.5+ 
+based on the version of Python being executed.
+
+The ``velox.sci27.py`` or ``velox.sci35.py`` module will import the ``vxmessageserver.py``
+
+
diff --git a/src/FlexSensor/Prober/velox_api/readme.txt b/src/FlexSensor/Prober/velox_api/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ce665530c759145afb22d5f1bf29fd237d7d9e08
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/readme.txt
@@ -0,0 +1,31 @@
+Installation
+===============
+Copy the velox.zip file to a convenient location and open a command prompt there.
+
+To install, use PIP:
+> python -m pip install velox.tar.gz
+
+NOTE: You must use the full file extension to avoid getting any modules named 
+Velox from the public Python repository.
+
+Usage Overview
+===============
+The velox folder contains the modules for interfacing with the Velox Message Server APIs
+via SCI Commands (see documentation for the Velox Integration Toolkit).
+
+This folder contains the ``__init__.py`` file that automatically imports the correct
+module based on the version of Python running at the time.
+
+Your code should:
+------------------
+
+``import velox``
+
+The __init__.py will load an SCI module appropriate for either Python 2.7+ or Python 3.5+
+based on the version of Python being executed.
+
+The ``velox.sci27.py`` or ``velox.sci35.py`` module will import the ``vxmessageserver.py``
+
+
+
+
diff --git a/src/FlexSensor/Prober/velox_api/setup.cfg b/src/FlexSensor/Prober/velox_api/setup.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..8bfd5a12f85b8fbb6c058cf67dd23da690835ea0
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/setup.cfg
@@ -0,0 +1,4 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff --git a/src/FlexSensor/Prober/velox_api/setup.py b/src/FlexSensor/Prober/velox_api/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec20e5fcd8171c0593854e1a28e3270a187bb745
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/setup.py
@@ -0,0 +1,13 @@
+from setuptools import setup
+
+setup(
+    name='velox',
+    version='3.0.0.266',
+    packages=['velox'],
+    url='',
+    license='See Formfactor Velox Product License.',
+    author='Formfactor',
+    author_email='',
+    description='Python 2.7+ and 3.5+ interface for Velox',
+    include_package_data=True
+)
diff --git a/src/FlexSensor/Prober/velox_api/simulator/VeloxSimulator.py b/src/FlexSensor/Prober/velox_api/simulator/VeloxSimulator.py
new file mode 100644
index 0000000000000000000000000000000000000000..d847ac3a11b51549c03a6fb7fa4706c79a2f645a
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/simulator/VeloxSimulator.py
@@ -0,0 +1,12426 @@
+import random
+import time
+
+from decimal import Decimal
+from collections import namedtuple
+
+"""
+Velox SCI Commands
+This module provides a function interface to the Cascade Microtech Velox software suite. 
+The module was auto-generated from the commands.info.xml file on 2019-11-09.  
+737 SCI commands were found and included.
+
+To use this module, your code must import the veloxsci.py module.
+Create a connection to the Velox Message Server using the 'with MessageServerInterface():' 
+command as shown in the sample below.
+
+The Velox Message Server must be running prior to establishing a connection. 
+To start the Message Server, run Velox.
+
+The sample code to use this module is:
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+
+    # Your Code: try some SCI Commands - such as:
+    response = velox.ReportKernelVersion()
+    print ('The kernel version is', response.Version, 'and', response.Description)
+    
+"""
+def EchoData(TestCmd:str=""):
+    """
+    Test Command for the Kernel Communication. Like a ping command, the given text
+    string is returned unchanged.
+    API Status: published
+    Args:
+        TestCmd:str = "Test"
+    Returns:
+        TestRsp:str
+    Command Timeout: 5000
+    Example:EchoData Test
+    """
+    rsp = MessageServerInterface.sendSciCommand("EchoData",TestCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportKernelVersion(Module:str=""):
+    """
+    Returns the version information of the kernel or the control box code. The
+    "Version" value contains version number and revision level of the actual Kernel
+    implementation. The text string contains a code description, version number and
+    the revision date.
+    API Status: published
+    Args:
+        Module:str = "K"
+    Returns:
+        Version:Decimal
+        Description:str
+    Command Timeout: 5000
+    Example:ReportKernelVersion K
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReportKernelVersion",Module)
+    global ReportKernelVersion_Response
+    if not "ReportKernelVersion_Response" in globals(): ReportKernelVersion_Response = namedtuple("ReportKernelVersion_Response", "Version,Description")
+    return ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReadProberStatus():
+    """
+    Returns an actual status information of the prober.
+    API Status: published
+    Returns:
+        FlagsBusy:int
+        FlagsContact:int
+        Mode:str
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadProberStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProberStatus")
+    global ReadProberStatus_Response
+    if not "ReadProberStatus_Response" in globals(): ReadProberStatus_Response = namedtuple("ReadProberStatus_Response", "FlagsBusy,FlagsContact,Mode,IsQuiet")
+    return ReadProberStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]))
+
+def EnableMotorQuiet(WantQuietModeOn:int="", Stage:str=""):
+    """
+    Toggles the motor power for quiet probing. In most applications this feature is
+    not required. However, for special measurements it may be necessary to reduce
+    the noise of the system. Quiet on turns off the motor power for all stages (or
+    the one specified with the optional parameter). Quiet off will turn on the motor
+    power of all stages (or the one specified with the optional parameter) for
+    subsequent movements. A move command will also turn on the motor power of the
+    moved stage automatically. For automatical switching of the quiet mode refer to
+    Auto Quiet functionality.  Sending 'EnableMotorQuiet 1' will enable the quiet
+    mode for all stages. Sending 'EnableMotorQuiet 1 C' will only enable the quiet
+    mode for the chuck stage. Sending 'EnableMotorQuiet 1 1' will only enable the
+    quiet mode for the Positioner1 stage. Sending 'EnableMotorQuiet 0 S' will only
+    disable the quiet mode for the scope stage.
+    API Status: published
+    Args:
+        WantQuietModeOn:int = 0
+        Stage:str = "None"
+    Command Timeout: 10000
+    Example:EnableMotorQuiet 1
+    """
+    MessageServerInterface.sendSciCommand("EnableMotorQuiet",WantQuietModeOn,Stage)
+
+
+def SetChuckVacuum(WantChuckVacuumOn:int=""):
+    """
+    Toggles the chuck vacuum on (1) or off (0). Can return vacuum timeout error for
+    stations with wafer vacuum sensors in case no wafer was detected.
+    API Status: published
+    Args:
+        WantChuckVacuumOn:int = 0
+    Command Timeout: 10000
+    Example:SetChuckVacuum 1
+    """
+    MessageServerInterface.sendSciCommand("SetChuckVacuum",WantChuckVacuumOn)
+
+
+def SetMicroLight(WantIlluminatorOn:int=""):
+    """
+    Toggles the microscope light channel of the peripheral output board and all
+    cameras. Notifications: 7
+    API Status: published
+    Args:
+        WantIlluminatorOn:int = 2
+    Command Timeout: 5000
+    Example:SetMicroLight 1
+    """
+    MessageServerInterface.sendSciCommand("SetMicroLight",WantIlluminatorOn)
+
+
+def SetBeaconStatus(FlagsMode:int="", PulseWidthRed:int="", PulseWidthGreen:int="", PulseWidthYellow:int="", PulseWidthBlue:int="", PulseWidthWhite:int=""):
+    """
+    This command controls the beacon channel of the peripheral output board. All
+    lights can be switched on, off, or blinking. Setting an interval to zero means,
+    that the corresponding light will be statically on or off. The minimum blinking
+    interval is 50ms.
+    API Status: published
+    Args:
+        FlagsMode:int = 0
+        PulseWidthRed:int = 1000
+        PulseWidthGreen:int = 0
+        PulseWidthYellow:int = 0
+        PulseWidthBlue:int = 0
+        PulseWidthWhite:int = 0
+    Command Timeout: 5000
+    Example:SetBeaconStatus 1 1000
+    """
+    MessageServerInterface.sendSciCommand("SetBeaconStatus",FlagsMode,PulseWidthRed,PulseWidthGreen,PulseWidthYellow,PulseWidthBlue,PulseWidthWhite)
+
+
+def SetOutput(Channel:int="", WantOutputOn:int="", PulseTime:int=""):
+    """
+    Controls the Velox output channel signals. It can be used to activate/deactivate
+    outputs.
+    API Status: published
+    Args:
+        Channel:int = 1
+        WantOutputOn:int = 0
+        PulseTime:int = -1
+    Command Timeout: 5000
+    Example:SetOutput 4 0
+    """
+    MessageServerInterface.sendSciCommand("SetOutput",Channel,WantOutputOn,PulseTime)
+
+
+def StopAllMovements():
+    """
+    Stops all Prober movements immediately. The response status value of any pending
+    movement will signify that the stop command was executed.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopAllMovements
+    """
+    MessageServerInterface.sendSciCommand("StopAllMovements")
+
+
+def InkDevice(FlagsInker:int="", PulseWidth:int=""):
+    """
+    Inks the current device under test. The range of PulseWidth is 20ms to 2000ms.
+    For correct function, the inkers have to be linked to default outputs.
+    API Status: published
+    Args:
+        FlagsInker:int = 0
+        PulseWidth:int = 50
+    Command Timeout: 10000
+    Example:InkDevice 1 40
+    """
+    MessageServerInterface.sendSciCommand("InkDevice",FlagsInker,PulseWidth)
+
+
+def ReadProbeSetup():
+    """
+    Returns the current positioner configuration.  The output pattern is:  1. Type
+    Positioner 1 2. Type Positioner 2 3. Type Positioner 3 4. Type Positioner 4 5.
+    Type Positioner 5 6. Axis Positioner 1 (Bit 0: XY, Bit 1: Z) 7. Axis Positioner
+    2 (Bit 0: XY, Bit 1: Z) 8. Axis Positioner 3 (Bit 0: XY, Bit 1: Z) 9. Axis
+    Positioner 4 (Bit 0: XY, Bit 1: Z) 10. Axis Positioner 5 (Bit 0: XY, Bit 1: Z)
+    11. Type Positioner 6 12. Axis Positioner 6 (Bit 0: XY, Bit 1: Z)
+    API Status: published
+    Returns:
+        TypePositioner1:int
+        TypePositioner2:int
+        TypePositioner3:int
+        TypePositioner4:int
+        TypePositioner5:int
+        AxisPositioner1:int
+        AxisPositioner2:int
+        AxisPositioner3:int
+        AxisPositioner4:int
+        AxisPositioner5:int
+        TypePositioner6:int
+        AxisPositioner6:int
+    Command Timeout: 5000
+    Example:ReadProbeSetup
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeSetup")
+    global ReadProbeSetup_Response
+    if not "ReadProbeSetup_Response" in globals(): ReadProbeSetup_Response = namedtuple("ReadProbeSetup_Response", "TypePositioner1,TypePositioner2,TypePositioner3,TypePositioner4,TypePositioner5,AxisPositioner1,AxisPositioner2,AxisPositioner3,AxisPositioner4,AxisPositioner5,TypePositioner6,AxisPositioner6")
+    return ReadProbeSetup_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]))
+
+def ReadSystemStatus():
+    """
+    Returns the system options which are currently enabled at the prober.
+    API Status: published
+    Returns:
+        Name:str
+        System:str
+        ChuckXY:int
+        ChuckZ:int
+        ChuckTheta:int
+        ScopeXY:int
+        ScopeZ:int
+        EdgeSensor:int
+        OperationalMode:str
+        Turret:int
+        TemperatureChuck:int
+        AuxSiteCount:int
+        PlatenXY:int
+        PlatenZ:int
+        LoaderGateState:str
+        NucleusType:str
+    Command Timeout: 10000
+    Example:ReadSystemStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSystemStatus")
+    global ReadSystemStatus_Response
+    if not "ReadSystemStatus_Response" in globals(): ReadSystemStatus_Response = namedtuple("ReadSystemStatus_Response", "Name,System,ChuckXY,ChuckZ,ChuckTheta,ScopeXY,ScopeZ,EdgeSensor,OperationalMode,Turret,TemperatureChuck,AuxSiteCount,PlatenXY,PlatenZ,LoaderGateState,NucleusType")
+    return ReadSystemStatus_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),str(rsp[14]),str("" if len(rsp) < 16 else ' '.join(rsp[15:])))
+
+def SetExternalMode(Mode:str=""):
+    """
+    If 'R' is sent, it sets the external mode of the kernel. This disables most of
+    the control box functions (except the LOCAL function key). Otherwise, this
+    command re-enables all functions of the control box.
+    API Status: published
+    Args:
+        Mode:str = "L"
+    Command Timeout: 5000
+    Example:SetExternalMode L
+    """
+    MessageServerInterface.sendSciCommand("SetExternalMode",Mode)
+
+
+def SetStageLock(Stage:str="", WantStageLock:int="", Application:str=""):
+    """
+    Enables or disables the stage lock functionality. Stages which are locked can't
+    be moved in any way. If the joystick controller is locked, the display and the
+    keys are deactivated. The name of the application can be stored by using the
+    Application Name parameter and is shown in lock-caused error messages.
+    API Status: published
+    Args:
+        Stage:str = "0"
+        WantStageLock:int = 1
+        Application:str = ""
+    Command Timeout: 10000
+    Example:SetStageLock C 0 WaferMap
+    """
+    MessageServerInterface.sendSciCommand("SetStageLock",Stage,WantStageLock,Application)
+
+
+def ReadSensor(Channel:int="", Type:str=""):
+    """
+    Returns the actual status of the specified input channel, output channel or edge
+    sensor. The signal table is described in the Hardware Manual. Each used IO-board
+    has 16 channels (max. 4 IO-boards are supported), what results in a domain of 64
+    channel numbers. Beyond this range there are pseudo channels, which are used for
+    special purposes. Pseudo channels:
+    API Status: published
+    Args:
+        Channel:int = 1
+        Type:str = "Input"
+    Returns:
+        IsSensorOn:int
+    Command Timeout: 10000
+    Example:ReadSensor 11 I
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSensor",Channel,Type)
+    return int(rsp[0])
+
+def GetStageLock(Stage:str=""):
+    """
+    Reads whether stages or joystick controller are locked.
+    API Status: published
+    Args:
+        Stage:str = "0"
+    Returns:
+        Locks:int
+        Application:str
+    Command Timeout: 10000
+    Example:GetStageLock C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetStageLock",Stage)
+    global GetStageLock_Response
+    if not "GetStageLock_Response" in globals(): GetStageLock_Response = namedtuple("GetStageLock_Response", "Locks,Application")
+    return GetStageLock_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetBackSideMode(WantBackSideMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets bottomside mode. In this mode the Z axis is reverse and the
+    command MoveChuckLoad is not allowed.
+    API Status: internal
+    Args:
+        WantBackSideMode:int = 0
+    Command Timeout: 5000
+    Example:SetBackSideMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetBackSideMode",WantBackSideMode)
+
+
+def GetBackSideMode():
+    """
+    Returns the current side mode.
+    API Status: published
+    Returns:
+        IsBackSideModeOn:int
+    Command Timeout: 5000
+    Example:GetBackSideMode
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBackSideMode")
+    return int(rsp[0])
+
+def SetDarkMode(WantSetDarkMode:int=""):
+    """
+    Switches off all LEDs on the Control Box, on the positioners, and on the screen
+    of the Control Box and also the light of the cameras.
+    API Status: published
+    Args:
+        WantSetDarkMode:int = 0
+    Command Timeout: 5000
+    Example:SetDarkMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetDarkMode",WantSetDarkMode)
+
+
+def GetDarkMode():
+    """
+    Returns the current mode of the light sources.
+    API Status: published
+    Returns:
+        IsDarkMode:int
+    Command Timeout: 5000
+    Example:GetDarkMode
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDarkMode")
+    return int(rsp[0])
+
+def DockChuckCamera(ConnectCamera:str="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Connect or disconnect the chuck camera to the chuck stage. The command is only
+    available for the Prober type PA300BEP.
+    API Status: internal
+    Args:
+        ConnectCamera:str = "ParkPos"
+        Velocity:Decimal = 100
+    Command Timeout: 300000
+    Example:DockChuckCamera P 75
+    """
+    MessageServerInterface.sendSciCommand("DockChuckCamera",ConnectCamera,Velocity)
+
+
+def ReadCBoxStage():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current selected stage of the joystick controller.
+    API Status: internal
+    Returns:
+        Stage:str
+    Command Timeout: 5000
+    Example:ReadCBoxStage
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxStage")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxStage(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current stage of the joystick controller.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Command Timeout: 5000
+    Example:SetCBoxStage C
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxStage",Stage)
+
+
+def ReadCBoxPosMonConf(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current setting of the joystick controllers position monitor for the
+    secified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        PosRef:str
+        Unit:str
+    Command Timeout: 5000
+    Example:ReadCBoxPosMonConf C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxPosMonConf",Stage)
+    global ReadCBoxPosMonConf_Response
+    if not "ReadCBoxPosMonConf_Response" in globals(): ReadCBoxPosMonConf_Response = namedtuple("ReadCBoxPosMonConf_Response", "PosRef,Unit")
+    return ReadCBoxPosMonConf_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetCBoxPosMonConf(Stage:str="", PosRef:str="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Configures the joystick controller position monitor for the secified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetCBoxPosMonConf C Z Y
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxPosMonConf",Stage,PosRef,Unit)
+
+
+def ReadCBoxCurrSpeed(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current speed of the joystick controller for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        CBoxSpeed:str
+    Command Timeout: 5000
+    Example:ReadCBoxCurrSpeed C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxCurrSpeed",Stage)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxCurrSpeed(Stage:str="", CBoxSpeed:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current speed of the joystick controller for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CBoxSpeed:str = "Speed4"
+    Command Timeout: 5000
+    Example:SetCBoxCurrSpeed C 3
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxCurrSpeed",Stage,CBoxSpeed)
+
+
+def MoveChuckAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck stage to the specified X,Y position without waiting for the move
+    to be finished If chuck Z is in contact height or higher, the chuck will drop to
+    separation.
+    API Status: internal
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 5000
+    Example:MoveChuckAsync 5000. 5000. R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the scope stage to the specified X,Y position without waiting for the move
+    to be finished.
+    API Status: internal
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 5000
+    Example:MoveScopeAsync 5000 5000 R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveProbeAsync(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the probe stage to the specified X,Y position without waiting for the move
+    to be finished.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeAsync",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def ReadChuckStatus():
+    """
+    Returns the current chuck status. Every bit in the bit fields works like a
+    boolean value: One &lt;1&gt; means true/on and zero &lt;0&gt; means false/off.
+    Its counted from LSB to MSB.   - _FlagsInit_: X, Y, Z, Theta - _FlagsMode_:
+    HasOvertravel, HasAutoZ, HasInterlock, ContactSearch, IsContactSet,
+    EdgeInterlock, QuietContact, IsLocked - _FlagsLimit_: XHigh, XLow, YHigh, YLow,
+    ZHigh, ZLow, ThetaHigh, ThetaLow - _FlagsMoving_: X, Y, Z, Theta  All parameters
+    are provided as indirect access (e.g. first bit of M_pvecFlagsInit can be
+    accessed by M_pbIsInitX).
+    API Status: published
+    Returns:
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        IsVacuumOn:int
+        PresetHeight:str
+        LoadPos:str
+        IsLiftDown:int
+        CameraConnection:str
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadChuckStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckStatus")
+    global ReadChuckStatus_Response
+    if not "ReadChuckStatus_Response" in globals(): ReadChuckStatus_Response = namedtuple("ReadChuckStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,IsVacuumOn,PresetHeight,LoadPos,IsLiftDown,CameraConnection,IsQuiet")
+    return ReadChuckStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),int(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),str(rsp[9]),int(rsp[10]))
+
+def ReadChuckPosition(Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the current chuck stage position in X, Y and Z.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckPosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckPosition",Unit,PosRef,Comp)
+    global ReadChuckPosition_Response
+    if not "ReadChuckPosition_Response" in globals(): ReadChuckPosition_Response = namedtuple("ReadChuckPosition_Response", "X,Y,Z")
+    return ReadChuckPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadChuckHeights(Unit:str=""):
+    """
+    Returns the current settings used for the chuck Z movement. `Contact` is the
+    contact-height from zero in default compensation. The other heights are relative
+    to this. If no contact is set, the value will be -1.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+        SearchGap:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckHeights",Unit)
+    global ReadChuckHeights_Response
+    if not "ReadChuckHeights_Response" in globals(): ReadChuckHeights_Response = namedtuple("ReadChuckHeights_Response", "Contact,Overtravel,AlignDist,SepDist,SearchGap")
+    return ReadChuckHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def InitChuck(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+    """
+    Machine Coordinate System: Chuck X Y Z Theta  - _FlagsInit_: X, Y, Z, Theta -
+    _FlagsDirection_: X, Y, Z, Theta (true means plus direction) - _FlagsMoveRange_:
+    X, Y, Z, Theta   All flags can be accessed by indirect members.  Initializes the
+    chuck stage and resets current coordinate system. Should be used only in cases
+    when the reported coordinates do not correspond to real position of mechanics.
+    Find Move Range starts the initialization in the defined direction and then
+    moves to the other limit and finds the whole range of the axes.
+    API Status: published
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 150000
+    Example:InitChuck 7 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitChuck",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveChuck(XValue:float="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+    height or higher, Interlock and Auto Z flags will be analyzed and stage will
+    behave correspondingly - can move to separation first or return an error:
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 30000
+    Example:MoveChuck 5000. 5000. R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuck",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveChuckIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck stage in index steps. This command modifies Die Home Position.
+    API Status: published
+    Args:
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckIndex 1 1 R 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveChuckSubsite(XValue:Decimal="", YValue:Decimal="", Unit:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck stage to the specified X, Y sub-site position. Die home position
+    is defined by destination position of last successful MoveChuck or
+    MoveChuckIndex commands. MoveChuckVelocity does not touch die home position. If
+    you have moved chuck with MoveChuckVelocity, "MoveChuckSubsite 0 0" will move it
+    back to die home position.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckSubsite 200 200 Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckSubsite",XValue,YValue,Unit,Velocity)
+
+
+def MoveChuckContact(Velocity:Decimal=""):
+    """
+    Performs a movement of chuck Z axis to preset contact height or will return
+    error if no contact height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckContact 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckContact",Velocity)
+
+
+def MoveChuckAlign(Velocity:Decimal=""):
+    """
+    Moves the chuck Z axis to the align height. If no Contact height is set will
+    return an error.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckAlign",Velocity)
+
+
+def MoveChuckSeparation(Velocity:Decimal=""):
+    """
+    Moves the chuck Z axis to the separation height. Returns error if no Contact
+    height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckSeparation",Velocity)
+
+
+def MoveChuckLoad(LoadPosition:str=""):
+    """
+    Moves the Chuck stage in X, Y, Z and Theta to the load position.
+    API Status: published
+    Args:
+        LoadPosition:str = "First"
+    Command Timeout: 60000
+    Example:MoveChuckLoad 0
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckLoad",LoadPosition)
+
+
+def MoveChuckZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the chuck Z axis to the specified height. If contact is set, only moves up
+    to contact height will be allowed. If overtravel is enabled - up to overtravel
+    height.
+    API Status: published
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 60000
+    Example:MoveChuckZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SearchChuckContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the chuck Z axis to the specified height and sets contact. The move stops
+    immediately if the Contact Sensor ( Edge Sensor) is triggered. If no contact has
+    been found and an old one was set before the old contact will not get lost, it
+    will be reset.
+    API Status: published
+    Args:
+        Height:Decimal = 100
+        PosRef:str = "Relative"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ContactHeight:Decimal
+    Command Timeout: 60000
+    Example:SearchChuckContact 1000 R Y 10
+    """
+    rsp = MessageServerInterface.sendSciCommand("SearchChuckContact",Height,PosRef,Unit,Velocity,Comp)
+    return Decimal(rsp[0])
+
+def MoveChuckVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    Moves the chuck stage in velocity mode. The motion continues until the
+    StopChuckMovement command is received, or the end limit is reached.
+    API Status: published
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 30000
+    Example:MoveChuckVelocity + + 0 100 30 0
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopChuckMovement(FlagsStop:int=""):
+    """
+    Stops chuck movement for the given axis. Notifications: 31 / 32 / 5
+    API Status: published
+    Args:
+        FlagsStop:int = 15
+    Command Timeout: 5000
+    Example:StopChuckMovement 7
+    """
+    MessageServerInterface.sendSciCommand("StopChuckMovement",FlagsStop)
+
+
+def SetChuckMode(Overtravel:int="", AutoZ:int="", Interlock:int="", ContactSearch:int="", EdgeInterlock:int="", QuietContact:int=""):
+    """
+    Mode manages the way the chuck behaves when it is in contact height. Chuck mode
+    is made from 6 flags and you can control all of them using this command. Every
+    flag can be turned on by using value 1 or turned off by using value 0. If you do
+    not want to change a flag - use value of 2.
+    API Status: published
+    Args:
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        ContactSearch:int = 2
+        EdgeInterlock:int = 2
+        QuietContact:int = 2
+    Command Timeout: 5000
+    Example:SetChuckMode 2 2 2 2 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetChuckMode",Overtravel,AutoZ,Interlock,ContactSearch,EdgeInterlock,QuietContact)
+
+
+def SetChuckHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets wafer and die home position, which can be used later as coordinate system
+    for movements.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckHome 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetChuckHome",Mode,Unit,XValue,YValue)
+
+
+def SetChuckIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the wafer index size. Normally the size of one die.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetChuckIndex 5000. 5000. Y
+    """
+    MessageServerInterface.sendSciCommand("SetChuckIndex",XValue,YValue,Unit)
+
+
+def SetChuckHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align and separation. A predefined contact search gap is able to write. No data
+    in the optional parameters sets contact height at current position. If Mode is
+    '0', contact height can be set at current position. The levels O, A, S and T
+    support no Mode '0'. If Mode is 'V' and no value for height is specified -
+    default 0 will be used, what potentially can be not what you expect. If Mode is
+    'R', contact height can be invalidated. The levels O, A, S and T support no Mode
+    'R'.
+    API Status: published
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckHeight C V Y 5000.
+    """
+    MessageServerInterface.sendSciCommand("SetChuckHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadChuckIndex(Unit:str=""):
+    """
+    The command gets the current die size which is stored in the kernel.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckIndex Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckIndex",Unit)
+    global ReadChuckIndex_Response
+    if not "ReadChuckIndex_Response" in globals(): ReadChuckIndex_Response = namedtuple("ReadChuckIndex_Response", "IndexX,IndexY")
+    return ReadChuckIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveChuckTransfer():
+    """
+    Moves the Chuck to the Transfer Position. If the movement starts in Load
+    Position (where it's possible to pull out the chuck) the handling of the Add On
+    Platen or the Pin Chuck is integrated.
+    API Status: published
+    Command Timeout: 90000
+    Example:MoveChuckTransfer
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckTransfer")
+
+
+def MoveChuckLift(SetLift:int=""):
+    """
+    Moves the chuck to the upper (0) or lower = lifted (1) position. This initiates
+    motion only, the actual movement may take some seconds.
+    API Status: published
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MoveChuckLift 1
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckLift",SetLift)
+
+
+def SetChuckThermoScale(ScaleX:Decimal="", ScaleY:Decimal=""):
+    """
+    Thermo drifts of the wafer will be compensated. The compensation is not
+    persistent, (power off - this compensation is deleted). The algorithm works as
+    an additional one.  This is for an iterative usage, so:  1. `ResetProber H` 2.
+    `SetChuckThermoScale 1.5 1.5` 3. `SetChuckThermoScale 1.5 1.5`  will result in a
+    scale of 2.25 in both directions. The thermal scale can also be reset using the
+    command 'SetChcukThermoValue 20 C'
+    API Status: published
+    Args:
+        ScaleX:Decimal = 1
+        ScaleY:Decimal = 1
+    Command Timeout: 5000
+    Example:SetChuckThermoScale 1.000005 1.0000045
+    """
+    MessageServerInterface.sendSciCommand("SetChuckThermoScale",ScaleX,ScaleY)
+
+
+def ReadChuckThermoScale():
+    """
+    Read the linear scaling value of the chuck.
+    API Status: published
+    Returns:
+        ScaleX:Decimal
+        ScaleY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckThermoScale
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoScale")
+    global ReadChuckThermoScale_Response
+    if not "ReadChuckThermoScale_Response" in globals(): ReadChuckThermoScale_Response = namedtuple("ReadChuckThermoScale_Response", "ScaleX,ScaleY")
+    return ReadChuckThermoScale_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetChuckThermoValue(Temperature:Decimal="", Unit:str="", ExpCoeffX:Decimal="", ExpCoeffY:Decimal=""):
+    """
+    Set a temperature and optional the expansion coefficient. The temperature for
+    normal level is 20 degree. The scaling factor at this temperature is 1.0. If you
+    set the temperature directly the controller calculates the stage difference in
+    the coordinate system. For the calculation use the set coefficient of expansion
+    from the controller. The default coefficient of expansion is based on silicon:
+    2.33E-06 1/K.
+    API Status: published
+    Args:
+        Temperature:Decimal = 0
+        Unit:str = "Celsius"
+        ExpCoeffX:Decimal = 0
+        ExpCoeffY:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckThermoValue 250 C 2.43 2.32
+    """
+    MessageServerInterface.sendSciCommand("SetChuckThermoValue",Temperature,Unit,ExpCoeffX,ExpCoeffY)
+
+
+def ReadChuckThermoValue(Unit:str=""):
+    """
+    Read the current temperature (either set or calculated) for the thermal scaling.
+    With SetChuckThermoScale in use, the value will be calculated by the current
+    scale and the expansion factor of silicium. The temperature that is read with
+    this command is not identical to the current chuck temperature.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        Temperature:Decimal
+        ExpCoeffX:Decimal
+        ExpCoeffY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckThermoValue C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoValue",Unit)
+    global ReadChuckThermoValue_Response
+    if not "ReadChuckThermoValue_Response" in globals(): ReadChuckThermoValue_Response = namedtuple("ReadChuckThermoValue_Response", "Temperature,ExpCoeffX,ExpCoeffY")
+    return ReadChuckThermoValue_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetChuckTableID(TableName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return the TableID Number of the stored chuck table or create a new table. The
+    ID Number is unique for the name and the chuck. The table itself has a string
+    name, this name is not case sensitive. This command has to be used before all
+    other table commands can be used. Accesses to the table is possible only with an
+    ID Number (name dependet).
+    API Status: internal
+    Args:
+        TableName:str = "ChuckTable"
+    Returns:
+        TableID:int
+    Command Timeout: 5000
+    Example:GetChuckTableID ChuckTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetChuckTableID",TableName)
+    return int(rsp[0])
+
+def MoveChuckTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move the chuck to the next stored table site.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckTablePoint 3 10 67
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckTablePoint",TableID,PointID,Velocity)
+
+
+def ReadChuckTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read back the table site information for this point from the Kernel.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadChuckTablePoint 10 250 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckTablePoint",TableID,PointID,Unit)
+    global ReadChuckTablePoint_Response
+    if not "ReadChuckTablePoint_Response" in globals(): ReadChuckTablePoint_Response = namedtuple("ReadChuckTablePoint_Response", "CoordX,CoordY,CoordSystem")
+    return ReadChuckTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetChuckTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set one point of the chuck table inside of the Kernel. If there is still a point
+    with this index loaded, the Kernel returns an error. Number of positions and
+    number of tables are dependet on the internal memory. All positions are stored
+    persistent, that means after switching power on or off the positions are still
+    available. The table starts with point number 1 and ends with the ID 16. The
+    table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetChuckTablePoint 10 12000.0 2344.0 Y F
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetChuckTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    return int(rsp[0])
+
+def ClearChuckTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of chuck table site points in the in the Kernel. If Start
+    Point is -1 or negative the whole table will be deleted.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearChuckTablePoint 5 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearChuckTablePoint",TableID,StartPoint,EndPoint)
+    global ClearChuckTablePoint_Response
+    if not "ClearChuckTablePoint_Response" in globals(): ClearChuckTablePoint_Response = namedtuple("ClearChuckTablePoint_Response", "ClearNumber,ValidNumber")
+    return ClearChuckTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def AttachAmbientWafer(MoveTimeMs:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is moved to slowly attach a wafer that is at ambient temperature while
+    the chuck is hot.     The command acts similar to MoveChuckTransfer when moving
+    out of Load 2 but will use a much slower Z velocity.     This is only supported
+    for BnR-machines (CM300 and Summit200) at the moment.
+    API Status: internal
+    Args:
+        MoveTimeMs:Decimal = 30000
+    Command Timeout: 300000
+    Example:AttachAmbientWafer
+    """
+    MessageServerInterface.sendSciCommand("AttachAmbientWafer",MoveTimeMs)
+
+
+def ReadThetaStatus():
+    """
+    Returns the actual status of the chuck Theta axis.
+    API Status: published
+    Returns:
+        IsInit:int
+        FlagsLimit:int
+        IsMoving:int
+    Command Timeout: 5000
+    Example:ReadThetaStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadThetaStatus")
+    global ReadThetaStatus_Response
+    if not "ReadThetaStatus_Response" in globals(): ReadThetaStatus_Response = namedtuple("ReadThetaStatus_Response", "IsInit,FlagsLimit,IsMoving")
+    return ReadThetaStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadThetaPosition(Unit:str="", PosRef:str=""):
+    """
+    Returns the actual Theta position.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+        PosRef:str = "Home"
+    Returns:
+        Position:Decimal
+    Command Timeout: 5000
+    Example:ReadThetaPosition D Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadThetaPosition",Unit,PosRef)
+    return Decimal(rsp[0])
+
+def InitTheta(FlagsDoPlus:int="", FlagsMoveRange:int=""):
+    """
+    Performs an initialization move and resets the coordinate system of the Theta
+    axis.
+    API Status: published
+    Args:
+        FlagsDoPlus:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 120000
+    Example:InitTheta 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitTheta",FlagsDoPlus,FlagsMoveRange)
+
+
+def MoveTheta(Position:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck Theta axis to the specified position. The positive direction is
+    counter-clockwise.
+    API Status: published
+    Args:
+        Position:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Degrees"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveTheta 1000. R E
+    """
+    MessageServerInterface.sendSciCommand("MoveTheta",Position,PosRef,Unit,Velocity)
+
+
+def MoveThetaVelocity(Polarity:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck Theta axis in velocity mode. The positive direction is counter-
+    clockwise. The motion continues until the StopThetaMovement command is received,
+    or the end limit (error condition) is reached. This command is mostly used for
+    joystick movements that do not have a target destination.
+    API Status: published
+    Args:
+        Polarity:str = "Fixed"
+        Velocity:Decimal = 0
+    Command Timeout: 240000
+    Example:MoveThetaVelocity + 67
+    """
+    MessageServerInterface.sendSciCommand("MoveThetaVelocity",Polarity,Velocity)
+
+
+def StopThetaMovement():
+    """
+    Stops any type (velocity, position etc.) of chuck Theta axis movement. This is
+    treated as a smooth stop rather than an emergency stop.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopThetaMovement
+    """
+    MessageServerInterface.sendSciCommand("StopThetaMovement")
+
+
+def SetThetaHome(Mode:str="", Unit:str="", Position:Decimal=""):
+    """
+    Sets the chuck Theta position to home. This position is usable as reference
+    position for other commands.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Degrees"
+        Position:Decimal = 0
+    Command Timeout: 5000
+    Example:SetThetaHome 0
+    """
+    MessageServerInterface.sendSciCommand("SetThetaHome",Mode,Unit,Position)
+
+
+def ScanChuckZ(ZDistance:Decimal="", TriggerEveryNthCycle:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts moving the chuck from the current position with Velocity [%] over
+    ZDistance (sign is important, as a negative sign will move chuck down during
+    scan) - Predefined camera trigger pulses (TTL active high for at least 5us) will
+    be sent during the scan every passed number of BnR cyclics (800us per cyclic)
+    until the ZDistance has been reached.  Command returns number of positions and
+    all compensated Z Positions from Zero, where the trigger was sent.
+    API Status: internal
+    Args:
+        ZDistance:Decimal = 1000
+        TriggerEveryNthCycle:int = 3
+        Velocity:Decimal = 10
+    Returns:
+        NumberOfPositions:int
+        TriggerPositions:str
+    Command Timeout: 60000
+    Example:ScanChuckZ 300 3 1.5
+    """
+    rsp = MessageServerInterface.sendSciCommand("ScanChuckZ",ZDistance,TriggerEveryNthCycle,Velocity)
+    global ScanChuckZ_Response
+    if not "ScanChuckZ_Response" in globals(): ScanChuckZ_Response = namedtuple("ScanChuckZ_Response", "NumberOfPositions,TriggerPositions")
+    return ScanChuckZ_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def MoveChuckZSafe():
+    """
+    Moves the chuck Z axis to a z height considered safe. This is either the lower
+    Z-Fence or the kernel setup item Chuck:SafeTransferHeight (which ever is larger)
+    API Status: published
+    Command Timeout: 60000
+    Example:MoveChuckZSafe
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckZSafe")
+
+
+def SetPlatenMode(Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The mode manages the way the platen behaves when it is in contact height. Platen
+    mode is made up from 5 flags and the user can control all of them by using this
+    command. Every flag can be turned on by setting value 1 or turned off by setting
+    value 0. If no change for a flag is wanted, use the value of 2.
+    API Status: internal
+    Args:
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        AutoZFollow:int = 2
+        AutoQuiet:int = 2
+    Command Timeout: 5000
+    Example:SetPlatenMode 2 2 2 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetPlatenMode",Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+
+
+def MovePlatenLift(SetLift:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen to the high (0) or low = lifted (1) position. This initiates
+    motion; the actual movement may take some seconds.
+    API Status: internal
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MovePlatenLift 1
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenLift",SetLift)
+
+
+def SearchPlatenContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", CompLayer:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Searches contact height using the edge sensor using a z movement of the platen
+    stage
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        CompLayer:str = "Default"
+    Returns:
+        ContactHeight:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SearchPlatenContact",Height,PosRef,Unit,Velocity,CompLayer)
+    return Decimal(rsp[0])
+
+def ReadPlatenStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current platen status.
+    API Status: internal
+    Returns:
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        PresetHeight:str
+        IsLiftDown:int
+    Command Timeout: 10000
+    Example:ReadPlatenStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenStatus")
+    global ReadPlatenStatus_Response
+    if not "ReadPlatenStatus_Response" in globals(): ReadPlatenStatus_Response = namedtuple("ReadPlatenStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,PresetHeight,IsLiftDown")
+    return ReadPlatenStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ReadPlatenPosition(Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the platens X, Y and Z axes. The default
+    compensation is the currently selected compensation for the stage.
+    API Status: internal
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 10000
+    Example:ReadPlatenPosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenPosition",Unit,PosRef,Comp)
+    global ReadPlatenPosition_Response
+    if not "ReadPlatenPosition_Response" in globals(): ReadPlatenPosition_Response = namedtuple("ReadPlatenPosition_Response", "X,Y,Z")
+    return ReadPlatenPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadPlatenHeights(Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual settings for the probe Z movement.
+    API Status: internal
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 10000
+    Example:ReadPlatenHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenHeights",Unit)
+    global ReadPlatenHeights_Response
+    if not "ReadPlatenHeights_Response" in globals(): ReadPlatenHeights_Response = namedtuple("ReadPlatenHeights_Response", "Contact,Overtravel,AlignDist,SepDist")
+    return ReadPlatenHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def InitPlaten(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initializes the platens X, Y and Z axes. Currently the initialization in
+    negative direction and the move range scan are not supported.
+    API Status: internal
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 120000
+    Example:InitPlaten 4
+    """
+    MessageServerInterface.sendSciCommand("InitPlaten",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MovePlatenZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the specified height. If contact is set, only moves
+    up to contact height will be allowed. If overtravel is enabled - up to
+    overtravel height.
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 30000
+    Example:MovePlatenZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def MovePlatenContact(Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a movement of platen Z axis to preset contact height or returns an
+    error, if no contact height is set.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenContact 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenContact",Velocity)
+
+
+def MovePlatenAlign(Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the align height. If no contact height is set, the
+    command will return an error.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenAlign",Velocity)
+
+
+def MovePlatenSeparation(Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the separation height. If no contact height is set,
+    the command will return an error.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenSeparation",Velocity)
+
+
+def MovePlatenVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen stage in velocity mode. The motion continues until the
+    StopPlatenMovement command is received, or the software fence is reached.
+    API Status: internal
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 240000
+    Example:MovePlatenVelocity + + 0 67 50 0
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopPlatenMovement(FlagsStop:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the movement of a set of platen axes immediately.
+    API Status: internal
+    Args:
+        FlagsStop:int = 7
+    Command Timeout: 10000
+    Example:StopPlatenMovement 4
+    """
+    MessageServerInterface.sendSciCommand("StopPlatenMovement",FlagsStop)
+
+
+def SetPlatenHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align and separation height. A command without data sets contact height at
+    current position.
+    API Status: internal
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 10000
+    Example:SetPlatenHeight C V Y 5000
+    """
+    MessageServerInterface.sendSciCommand("SetPlatenHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadManualPlatenState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads the current status of the manual platen. THis is only supported for
+    Nucleus and Summit200.
+    API Status: internal
+    Returns:
+        IsUp:int
+        IsDown:int
+        IsSafe:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadManualPlatenState")
+    global ReadManualPlatenState_Response
+    if not "ReadManualPlatenState_Response" in globals(): ReadManualPlatenState_Response = namedtuple("ReadManualPlatenState_Response", "IsUp,IsDown,IsSafe")
+    return ReadManualPlatenState_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadScopeStatus():
+    """
+    Returns the current scope status.
+    API Status: published
+    Returns:
+        FlagsInit:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        IsScopeLiftUp:int
+        PresetHeight:str
+        IsScopeLight:int
+        FlagsMode:int
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadScopeStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeStatus")
+    global ReadScopeStatus_Response
+    if not "ReadScopeStatus_Response" in globals(): ReadScopeStatus_Response = namedtuple("ReadScopeStatus_Response", "FlagsInit,FlagsLimit,FlagsMoving,Comp,IsScopeLiftUp,PresetHeight,IsScopeLight,FlagsMode,IsQuiet")
+    return ReadScopeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),str(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def ReadScopePosition(Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the actual scope stage position in X, Y and Z. The default Compensation
+    Mode is the currently activated compensation mode of the kernel.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadScopePosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopePosition",Unit,PosRef,Comp)
+    global ReadScopePosition_Response
+    if not "ReadScopePosition_Response" in globals(): ReadScopePosition_Response = namedtuple("ReadScopePosition_Response", "X,Y,Z")
+    return ReadScopePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeHeights(Unit:str=""):
+    """
+    Returns the actual settings of the focus height, align gap, and separation gap
+    for the scope Z axis.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        FocusHeight:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeHeights",Unit)
+    global ReadScopeHeights_Response
+    if not "ReadScopeHeights_Response" in globals(): ReadScopeHeights_Response = namedtuple("ReadScopeHeights_Response", "FocusHeight,AlignDist,SepDist")
+    return ReadScopeHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def InitScope(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+    """
+    Initializes the microscope stage in X, Y and Z. The Axis default is all axes and
+    the Direction default is XY in minus and Z in plus. Should be used only in cases
+    when the reported coordinates do not correspond to real position of mechanics.
+    Find Move Range starts the initialization in the defined direction and then
+    moves to the other limit and finds the whole range of the axes.
+    API Status: published
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 240000
+    Example:InitScope 3 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitScope",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveScope(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 70000
+    Example:MoveScope 5000 5000 R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScope",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+    """
+    Moves the microscope stage in index steps. If no PositionReference byte is
+    passed the scope will step relative to the wafer home position. ('R' means the
+    step relative to current position).
+    API Status: published
+    Args:
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveScopeIndex 1 1 R 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveScopeZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the microscope Z axis to the specified height. Default velocity is 100%.
+    API Status: published
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 120000
+    Example:MoveScopeZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SetScopeMode(QuietMode:int="", FollowMode:int=""):
+    """
+    Scope mode is made up of two flags which can be controlled using this command.
+    Each flag can be turned on by using value 1 or turned off by using value 0. If
+    you do not want to change a flag, use value of 2.
+    API Status: published
+    Args:
+        QuietMode:int = 2
+        FollowMode:int = 2
+    Command Timeout: 5000
+    Example:SetScopeMode 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetScopeMode",QuietMode,FollowMode)
+
+
+def MoveScopeVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    Moves the microscope stage in velocity mode. The motion continues until the
+    StopScopeMovement command is received, or the end limit (error condition) is
+    reached. Axes parameter: '+' move this axis in plus direction '-' move this axis
+    in minus direction '0' Do not change this axis
+    API Status: published
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 30000
+    Example:MoveScopeVelocity + + 0 67 100 0
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopScopeMovement(FlagsStop:int=""):
+    """
+    Stops scope movement for the given axis. A smooth stop is executed, no emergency
+    stop.
+    API Status: published
+    Args:
+        FlagsStop:int = 7
+    Command Timeout: 5000
+    Example:StopScopeMovement 7
+    """
+    MessageServerInterface.sendSciCommand("StopScopeMovement",FlagsStop)
+
+
+def SetScopeHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets the scope Home position in X and Y. It identifies the scope coordinate
+    system for later movements. Usually this position is identical to the die home
+    location.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeHome 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeHome",Mode,Unit,XValue,YValue)
+
+
+def SetScopeIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the microscope index size. Normally set in relation to the wafer index
+    size.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetScopeIndex 5000. 5000. Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeIndex",XValue,YValue,Unit)
+
+
+def SetScopeHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    This command defines scope focus height and the corresponding gaps for alignment
+    or separation. No data sets focus height at current position.
+    API Status: published
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeHeight F 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadScopeIndex(Unit:str=""):
+    """
+    Returns the actual scope stage index values in X and Y.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeIndex Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeIndex",Unit)
+    global ReadScopeIndex_Response
+    if not "ReadScopeIndex_Response" in globals(): ReadScopeIndex_Response = namedtuple("ReadScopeIndex_Response", "IndexX,IndexY")
+    return ReadScopeIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveScopeFocus(Velocity:Decimal=""):
+    """
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 25000
+    Example:MoveScopeFocus 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeFocus",Velocity)
+
+
+def MoveScopeAlign(Velocity:Decimal=""):
+    """
+    Moves the Scope Z axis to the alignment height. If no focus height is set an
+    error will bereturned.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 10000
+    Example:MoveScopeAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeAlign",Velocity)
+
+
+def MoveScopeSeparation(Velocity:Decimal=""):
+    """
+    Moves the scope Z axis to the separation height. Returns an error if no focus
+    height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveScopeSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeSeparation",Velocity)
+
+
+def MoveScopeLift(SetLift:int=""):
+    """
+    Moves the microscope lift to the lower (0) or upper = lifted (1) position. This
+    initiates the motion only, the actual movement may take some seconds.
+    API Status: published
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MoveScopeLift 1
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeLift",SetLift)
+
+
+def ReadTurretStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current status of the motorized turret.
+    API Status: internal
+    Returns:
+        IsMoving:int
+    Command Timeout: 5000
+    Example:ReadTurretStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTurretStatus")
+    return int(rsp[0])
+
+def SelectLens(Lens:int=""):
+    """
+    Parfocality and para-centricity are adjusted according to the stored values.
+    This can be used with manual turrets to compensate for XYZ differences between
+    lenses.
+    API Status: published
+    Args:
+        Lens:int = 1
+    Command Timeout: 30000
+    Example:SelectLens 1
+    """
+    MessageServerInterface.sendSciCommand("SelectLens",Lens)
+
+
+def GetScopeTable(TableName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return the TableID Number of the stored chuck table or create a new table. The
+    ID Number is unique for the name and the chuck. The table itself has a string
+    name, this name is not case sensitive. This command has to be used before all
+    other table commands can be used. Accesses to the table is possible only with an
+    ID Number (name dependet).
+    API Status: internal
+    Args:
+        TableName:str = "ScopeTable"
+    Returns:
+        TableID:int
+    Command Timeout: 5000
+    Example:GetScopeTable ScopeTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetScopeTable",TableName)
+    return int(rsp[0])
+
+def MoveScopeTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveScopeTablePoint 10 5 67
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeTablePoint",TableID,PointID,Velocity)
+
+
+def ReadScopeTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read back the scope table site Information for this point from the Kernel.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadScopeTablePoint 2 10 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeTablePoint",TableID,PointID,Unit)
+    global ReadScopeTablePoint_Response
+    if not "ReadScopeTablePoint_Response" in globals(): ReadScopeTablePoint_Response = namedtuple("ReadScopeTablePoint_Response", "CoordX,CoordY,CoordSystem")
+    return ReadScopeTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def ReadCurrentLens():
+    """
+    Returns the number of the current microscope lens.
+    API Status: published
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    Example:ReadCurrentLens
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCurrentLens")
+    return int(rsp[0])
+
+def SetScopeTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set one point of the scope table inside of the Kernel. If there is still a point
+    with this index loaded, the Kernel returns an error. Number of positions and
+    number of tables are dependet on the internal memory. All positions are stored
+    persistent, that means after switching power on or off the positions are still
+    available. The table starts with point number 1 and ends with the ID 16. The
+    table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetScopeTablePoint 10 10 8992.5 7883.0 Y H
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetScopeTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    return int(rsp[0])
+
+def ClearScopeTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of scope table site points in the Kernel. If Start Point is
+    -1 or negative the whole table will be deleted.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearScopeTablePoint 2 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearScopeTablePoint",TableID,StartPoint,EndPoint)
+    global ClearScopeTablePoint_Response
+    if not "ClearScopeTablePoint_Response" in globals(): ClearScopeTablePoint_Response = namedtuple("ClearScopeTablePoint_Response", "ClearNumber,ValidNumber")
+    return ClearScopeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadScopeSiloCount():
+    """
+    Returns the number of silos in the scope fence. Will be zero if no silos are
+    configured.
+    API Status: published
+    Returns:
+        Count:int
+    Command Timeout: 5000
+    Example:ReadScopeSiloCount
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSiloCount")
+    return int(rsp[0])
+
+def ReadProbeStatus(Probe:int=""):
+    """
+    Returns the current positioner's status.
+    API Status: published
+    Args:
+        Probe:int = 1
+    Returns:
+        ProbeEcho:int
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        Side:str
+        PresetHeight:str
+        IsLiftUp:int
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadProbeStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeStatus",Probe)
+    global ReadProbeStatus_Response
+    if not "ReadProbeStatus_Response" in globals(): ReadProbeStatus_Response = namedtuple("ReadProbeStatus_Response", "ProbeEcho,FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,Side,PresetHeight,IsLiftUp,IsQuiet")
+    return ReadProbeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadProbePosition(Probe:int="", Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the actual positioner's position in X, Y and Z. The default Compensation
+    Mode is the currently activated compensation mode of the kernel.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadProbePosition 1 Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbePosition",Probe,Unit,PosRef,Comp)
+    global ReadProbePosition_Response
+    if not "ReadProbePosition_Response" in globals(): ReadProbePosition_Response = namedtuple("ReadProbePosition_Response", "ProbeEcho,X,Y,Z")
+    return ReadProbePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadProbeHeights(Probe:int="", Unit:str=""):
+    """
+    Returns the actual settings for the probe Z movement.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeHeights 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeHeights",Probe,Unit)
+    global ReadProbeHeights_Response
+    if not "ReadProbeHeights_Response" in globals(): ReadProbeHeights_Response = namedtuple("ReadProbeHeights_Response", "ProbeEcho,Contact,Overtravel,AlignDist,SepDist")
+    return ReadProbeHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def OrientProbe(Probe:int="", Side:str=""):
+    """
+    Defines the orientation of the positioner's coordinate system and turns the
+    Y-axis of the probe coordinate system.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Side:str = "Left"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:OrientProbe 1 R
+    """
+    rsp = MessageServerInterface.sendSciCommand("OrientProbe",Probe,Side)
+    return int(rsp[0])
+
+def InitProbe(Probe:int="", FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int="", FlagsInitInPlace:int=""):
+    """
+    Performs an initialization move and resets the coordinate system of the given
+    positioner.
+    API Status: published
+    Args:
+        Probe:int = 1
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+        FlagsInitInPlace:int = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 120000
+    Example:InitProbe 1 7 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("InitProbe",Probe,FlagsInit,FlagsDirection,FlagsMoveRange,FlagsInitInPlace)
+    return int(rsp[0])
+
+def MoveProbe(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbe 1 1000. 1000. R Y 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbe",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def MoveProbeIndex(Probe:int="", XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeIndex 1 1 1 R 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeIndex",Probe,XSteps,YSteps,PosRef,Velocity)
+    return int(rsp[0])
+
+def MoveProbeContact(Probe:int="", Velocity:Decimal=""):
+    """
+    Moves the given ProbeHeads Z axis to the preset contact height. If no contact
+    height is set, the kernel will return a 'Contact height not set' error.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeContact 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeContact",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeAlign(Probe:int="", Velocity:Decimal=""):
+    """
+    Moves the given ProbeHeads Z axis to the align height.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeAlign 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeAlign",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeSeparation(Probe:int="", Velocity:Decimal=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeSeparation 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeSeparation",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeZ(Probe:int="", Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves a given ProbeHeads Z axis to a defined Z height.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeZ 1 1000. R Y 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeZ",Probe,Height,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def MoveProbeLift(Probe:int="", SetLift:int=""):
+    """
+    Moves the positioner to the lower (0) or upper = lifted (1) position. The
+    command initiates the motion only, the whole movement may take some seconds.
+    API Status: published
+    Args:
+        Probe:int = 1
+        SetLift:int = 1
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 10000
+    Example:MoveProbeLift 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeLift",Probe,SetLift)
+    return int(rsp[0])
+
+def MoveProbeVelocity(Probe:int="", PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    '+' Move this axis into plus direction '-' Move this axis into minus direction
+    '0' Do not change this axis
+    API Status: published
+    Args:
+        Probe:int = 1
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeVelocity 1 + + Z 67 100 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeVelocity",Probe,PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+    return int(rsp[0])
+
+def StopProbeMovement(Probe:int="", FlagsStop:int=""):
+    """
+    Stops positioner movement for the given axes immediately. A smooth stop is
+    performed.
+    API Status: published
+    Args:
+        Probe:int = 1
+        FlagsStop:int = 7
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:StopProbeMovement 1 7
+    """
+    rsp = MessageServerInterface.sendSciCommand("StopProbeMovement",Probe,FlagsStop)
+    return int(rsp[0])
+
+def SetProbeMode(Probe:int="", Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+    """
+    The mode manages the way the chuck behaves when it is in contact height.
+    Positioner mode is made up from 5 flags and the user can control all of them by
+    using this command. Every flag can be turned on by setting value 1, or turned
+    off by setting value 0. Use the value 2 if no change for a flag is needed.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        AutoZFollow:int = 2
+        AutoQuiet:int = 2
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeMode 1 2 2 2 2
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeMode",Probe,Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+    return int(rsp[0])
+
+def SetProbeHome(Probe:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets the positioner's Home position in X and Y. This position identifies the
+    probe coordinate system for later movements. Usually this position is identical
+    to the die home position.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeHome 1 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeHome",Probe,Mode,Unit,XValue,YValue)
+    return int(rsp[0])
+
+def SetProbeIndex(Probe:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the positioner's index size or the location of the reference die relative
+    to the home die.
+    API Status: published
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeIndex 1 1000. 1000. Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeIndex",Probe,XValue,YValue,Unit)
+    return int(rsp[0])
+
+def SetProbeHeight(Probe:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align, load and separation height. No data sets contact height at current
+    position.
+    API Status: published
+    Args:
+        Probe:int = 1
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeHeight 1 C 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeHeight",Probe,PresetHeight,Mode,Unit,Value)
+    return int(rsp[0])
+
+def ReadProbeIndex(Probe:int="", Unit:str=""):
+    """
+    Returns the current positioner's wafer index values or the current positioner's
+    index positions for X and Y.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeIndex 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeIndex",Probe,Unit)
+    global ReadProbeIndex_Response
+    if not "ReadProbeIndex_Response" in globals(): ReadProbeIndex_Response = namedtuple("ReadProbeIndex_Response", "ProbeEcho,IndexX,IndexY")
+    return ReadProbeIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetProbeLED(Probe:int="", NewLEDState:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the positioner LED On or Off.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        NewLEDState:int = 0
+    Returns:
+        ProbeEcho:int
+        LEDState:int
+    Command Timeout: 5000
+    Example:SetProbeLED 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeLED",Probe,NewLEDState)
+    global SetProbeLED_Response
+    if not "SetProbeLED_Response" in globals(): SetProbeLED_Response = namedtuple("SetProbeLED_Response", "ProbeEcho,LEDState")
+    return SetProbeLED_Response(int(rsp[0]),int(rsp[1]))
+
+def GetProbeTableID(Probe:int="", TableName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the ID of a stored probe table or creates a new table. The ID is unique
+    for the name and the probe. The table itself has a string name. This name is not
+    case sensitive. The command has to be used before all other table commands can
+    be used. Access to tables is possible only with an ID Number (name dependent).
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableName:str = "ProbeTable"
+    Returns:
+        ProbeEcho:int
+        TableID:int
+    Command Timeout: 5000
+    Example:GetProbeTableID 1 ProbeTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProbeTableID",Probe,TableName)
+    global GetProbeTableID_Response
+    if not "GetProbeTableID_Response" in globals(): GetProbeTableID_Response = namedtuple("GetProbeTableID_Response", "ProbeEcho,TableID")
+    return GetProbeTableID_Response(int(rsp[0]),int(rsp[1]))
+
+def MoveProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 1
+        PointID:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeTablePoint 3 14 10 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeTablePoint",Probe,TableID,PointID,Velocity)
+    return int(rsp[0])
+
+def ReadProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads the data from a point of a stored table in the Kernel.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadProbeTablePoint 2 4 10 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeTablePoint",Probe,TableID,PointID,Unit)
+    global ReadProbeTablePoint_Response
+    if not "ReadProbeTablePoint_Response" in globals(): ReadProbeTablePoint_Response = namedtuple("ReadProbeTablePoint_Response", "ProbeEcho,CoordX,CoordY,CoordSystem")
+    return ReadProbeTablePoint_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets one point of a ProbeHeads table inside the Kernel. If there is still a
+    point with this index loaded, the Kernel returns an error. Number of positions
+    and number of tables are dependet on the internal memory. All positions are
+    stored persistent, that means after switching power on or off the positions are
+    still available. The table starts with point number 1 and ends with the ID 16.
+    The table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ProbeEcho:int
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetProbeTablePoint 3 12 10 8992.5 7883.0 Y Z M
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeTablePoint",Probe,TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    global SetProbeTablePoint_Response
+    if not "SetProbeTablePoint_Response" in globals(): SetProbeTablePoint_Response = namedtuple("SetProbeTablePoint_Response", "ProbeEcho,ValidPoint")
+    return SetProbeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ClearProbeTablePoint(Probe:int="", TableID:int="", StartPoint:int="", EndPoint:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of ProbeHead table site points in the Kernel. If StartPoint
+    is a negative value, the whole table will be deleted.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ProbeEcho:int
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearProbeTablePoint 3 4 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearProbeTablePoint",Probe,TableID,StartPoint,EndPoint)
+    global ClearProbeTablePoint_Response
+    if not "ClearProbeTablePoint_Response" in globals(): ClearProbeTablePoint_Response = namedtuple("ClearProbeTablePoint_Response", "ProbeEcho,ClearNumber,ValidNumber")
+    return ClearProbeTablePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def MoveScopeSilo(Index:int=""):
+    """
+    Move the scope to the reference position of the given silo. The reference
+    position should be - if not defined otherwise - 200 um above the safe z-height
+    in the center of the scope.
+    API Status: published
+    Args:
+        Index:int = 1
+    Command Timeout: 70000
+    Example:MoveScopeSilo 1
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeSilo",Index)
+
+
+def SetScopeSiloReference(Index:int="", X:Decimal="", Y:Decimal="", Z:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the reference position of a silo. The next time the scope moves to this
+    silo, it woll go to this position. The Referenceposition must be inside the silo
+    in xy and above the lower Z-Fence of the silo.  Setting the reference position
+    directly on the fence in x, y or z typically leads to errors. Try to keep a
+    safety margin.
+    API Status: internal
+    Args:
+        Index:int = 1
+        X:Decimal = 0
+        Y:Decimal = 0
+        Z:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeSiloReference 1 1000 2000 3000
+    """
+    MessageServerInterface.sendSciCommand("SetScopeSiloReference",Index,X,Y,Z)
+
+
+def AlignChuckTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+    """
+    This command causes a chuck Theta axis rotation to align the wafer to the chuck
+    X,Y movements.     It can be used to perform a two point alignment with
+    P1(X1,Y1) and P2(X2,Y2) as two points on a wafer street line.     The units of
+    the distances are not important - but both distances should use the same unit.
+    If one or both distances are zero, the command does not return an error and
+    instead ignore this alignment
+    API Status: published
+    Args:
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignChuckTheta 10000 10 R
+    """
+    MessageServerInterface.sendSciCommand("AlignChuckTheta",XDistance,YDistance,PosRef)
+
+
+def AlignScopeTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+    """
+    This command causes a virtual rotation of the scope coordinate system to align
+    the scope to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+    perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+    Calculation of X and Y distances:
+    API Status: published
+    Args:
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignScopeTheta 10000 10 R
+    """
+    MessageServerInterface.sendSciCommand("AlignScopeTheta",XDistance,YDistance,PosRef)
+
+
+def AlignProbeTheta(Probe:int="", XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+    """
+    This command causes a rotation of the coordinate system of given probe to align
+    the probe to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+    perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+    Calculation of Y and Y distances:
+    API Status: published
+    Args:
+        Probe:int = 1
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 10000
+    Example:AlignProbeTheta 1 10000 10 R
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignProbeTheta",Probe,XDistance,YDistance,PosRef)
+    return int(rsp[0])
+
+def AlignCardTheta(Angle:Decimal="", Unit:str="", PosRef:str=""):
+    """
+    This command causes a rotation of the chuck coordinate system to align the chuck
+    X, Y axis to the probecard.     The polarity of the data determines a left or a
+    right rotation of the chuck coordinate system.
+    API Status: published
+    Args:
+        Angle:Decimal = 0
+        Unit:str = "Degrees"
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignCardTheta 2.5 D R
+    """
+    MessageServerInterface.sendSciCommand("AlignCardTheta",Angle,Unit,PosRef)
+
+
+def ReadCardTheta(Unit:str=""):
+    """
+    Returns the angle between the chuck-coordinate-system and the probecard-
+    coordinate-system.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadCardTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCardTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadChuckTheta(Unit:str=""):
+    """
+    Returns the current chuck alignment angle which is identical to the current
+    value of theta rotation.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadScopeTheta(Unit:str=""):
+    """
+    Returns the scope's alignment angle, which is the angle between the chuck
+    coordinate system and the scope coordinate system.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadProbeTheta(Probe:int="", Unit:str=""):
+    """
+    Returns the actual positioner's alignment angle, which is the angle between the
+    chuck coordinate system and the positioner coordinate system.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Degrees"
+    Returns:
+        ProbeEcho:int
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeTheta 1 D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeTheta",Probe,Unit)
+    global ReadProbeTheta_Response
+    if not "ReadProbeTheta_Response" in globals(): ReadProbeTheta_Response = namedtuple("ReadProbeTheta_Response", "ProbeEcho,Angle")
+    return ReadProbeTheta_Response(int(rsp[0]),Decimal(rsp[1]))
+
+def ReadJoystickSpeeds(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the preset speeds, which are used by the joystick controller for moving a
+    single stage. The speeds can be read for XY, for Z and for Theta axis
+    separately. Jog timing and index timing are the times, the joystick controller
+    waits between two single jog or index moves.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "X"
+    Returns:
+        JogTime:Decimal
+        Speed2:Decimal
+        Speed3:Decimal
+        Speed4:Decimal
+        IndexTime:Decimal
+    Command Timeout: 5000
+    Example:ReadJoystickSpeeds S Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeeds",Stage,Axis)
+    global ReadJoystickSpeeds_Response
+    if not "ReadJoystickSpeeds_Response" in globals(): ReadJoystickSpeeds_Response = namedtuple("ReadJoystickSpeeds_Response", "JogTime,Speed2,Speed3,Speed4,IndexTime")
+    return ReadJoystickSpeeds_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetJoystickSpeeds(Stage:str="", JogTime:Decimal="", Speed2:Decimal="", Speed3:Decimal="", Speed4:Decimal="", IndexTime:Decimal="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the preset speeds, which are used by the joystick controller for moving a
+    single stage. After setting, the speeds can be selected by pressing the Speed n
+    buttons at the controller. The speeds must be set separately for XY, for Z and
+    for Theta axis. Jog timing and index timing are the times, the joystick
+    controller waits between two single jog or index moves.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        JogTime:Decimal = 0
+        Speed2:Decimal = 0
+        Speed3:Decimal = 0
+        Speed4:Decimal = 0
+        IndexTime:Decimal = 0
+        Axis:str = "X"
+    Command Timeout: 5000
+    Example:SetJoystickSpeeds S 10 20 30 40 50 Z
+    """
+    MessageServerInterface.sendSciCommand("SetJoystickSpeeds",Stage,JogTime,Speed2,Speed3,Speed4,IndexTime,Axis)
+
+
+def SetLoaderGate(Open:int=""):
+    """
+    Opens or closes the loader gate. Automatic handling systems can load wafers to
+    the chuck through the gate.
+    API Status: published
+    Args:
+        Open:int = 0
+    Command Timeout: 5000
+    Example:SetLoaderGate 0
+    """
+    MessageServerInterface.sendSciCommand("SetLoaderGate",Open)
+
+
+def ReadWaferStatus():
+    """
+    Returns whether the system detected a wafer. This feature can be used if the
+    probe station is equipped with a vacuum sensor and while vacuum is activated.
+    API Status: published
+    Returns:
+        SensedByVac:str
+    Command Timeout: 5000
+    Example:ReadWaferStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadWaferStatus")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadContactCount(Stage:str=""):
+    """
+    Returns the number of times this stage moved to contact since the last time the
+    counter was reset.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        Count:int
+    Command Timeout: 5000
+    Example:ReadContactCount C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadContactCount",Stage)
+    return int(rsp[0])
+
+def ResetContactCount(Stage:str=""):
+    """
+    Resets the contact counter for the specified stage to zero. Notifications: 23
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Command Timeout: 5000
+    Example:ResetContactCount C
+    """
+    MessageServerInterface.sendSciCommand("ResetContactCount",Stage)
+
+
+def SetManualMode(Enable:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command enables the manual mode on Elite/Summit/S300 systems. This mode
+    will allow to move the chuck using the knobs.
+    API Status: internal
+    Args:
+        Enable:int = 1
+    Command Timeout: 10000
+    Example:SetManualMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetManualMode",Enable)
+
+
+def GetManualMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns the state of the manual mode on Elite/Summit/S300 stations.
+    API Status: internal
+    Returns:
+        Enable:int
+    Command Timeout: 10000
+    Example:GetManualMode 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetManualMode")
+    return int(rsp[0])
+
+def GetAxisReverse(Stage:str="", Axis:str=""):
+    """
+    Allows reading if an axis is reverse.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        IsReverse:int
+    Command Timeout: 5000
+    Example:GetAxisReverse C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAxisReverse",Stage,Axis)
+    return int(rsp[0])
+
+def EnableEdgeSensor(EdgeSensor:int="", Enable:int=""):
+    """
+    Enables/disables the use of an edge sensor.
+    API Status: published
+    Args:
+        EdgeSensor:int = 1
+        Enable:int = 1
+    Command Timeout: 5000
+    Example:EnableEdgeSensor 1 1
+    """
+    MessageServerInterface.sendSciCommand("EnableEdgeSensor",EdgeSensor,Enable)
+
+
+def SetTypedOutput(Channel:str="", WantOutputOn:int="", PulseTime:int=""):
+    """
+    Controls the kernel valve driver signals and can be used to drive the outputs.
+    API Status: published
+    Args:
+        Channel:str = "NoSensor"
+        WantOutputOn:int = 0
+        PulseTime:int = -1
+    Command Timeout: 5000
+    Example:SetTypedOutput WaferVacuum 1
+    """
+    MessageServerInterface.sendSciCommand("SetTypedOutput",Channel,WantOutputOn,PulseTime)
+
+
+def ReadTypedSensor(Channel:str=""):
+    """
+    Returns the status of the specified input channel, output channel, or edge
+    sensor.
+    API Status: published
+    Args:
+        Channel:str = "NoSensor"
+    Returns:
+        IsSensorOn:int
+    Command Timeout: 10000
+    Example:ReadTypedSensor EmoIn I
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTypedSensor",Channel)
+    return int(rsp[0])
+
+def MoveCoolDownPosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck to the cool down position that is defined in KernelSetup. The
+    cooldown position is used to move the chuck away in XY while the robot is in the
+    chamber and tries to get a hot wafer.
+    API Status: internal
+    Command Timeout: 30000
+    Example:MoveCoolDownPosition
+    """
+    MessageServerInterface.sendSciCommand("MoveCoolDownPosition")
+
+
+def ReadJoystickSpeedsCycle(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the cycling speeds - these are the speeds that are used by
+    the USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        CycleJog:int
+        CycleSpeed2:int
+        CycleSpeed3:int
+        CycleSpeed4:int
+        CycleIndex:int
+    Command Timeout: 5000
+    Example:ReadJoystickSpeedsCycle S
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeedsCycle",Stage)
+    global ReadJoystickSpeedsCycle_Response
+    if not "ReadJoystickSpeedsCycle_Response" in globals(): ReadJoystickSpeedsCycle_Response = namedtuple("ReadJoystickSpeedsCycle_Response", "CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex")
+    return ReadJoystickSpeedsCycle_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetJoystickSpeedsCycle(Stage:str="", CycleJog:int="", CycleSpeed2:int="", CycleSpeed3:int="", CycleSpeed4:int="", CycleIndex:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets the cycling speeds - these are the speeds that are used by the
+    USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CycleJog:int = 0
+        CycleSpeed2:int = 0
+        CycleSpeed3:int = 0
+        CycleSpeed4:int = 0
+        CycleIndex:int = 0
+    Command Timeout: 5000
+    Example:SetJoystickSpeedsCycle C 1 1 1 1 1
+    """
+    MessageServerInterface.sendSciCommand("SetJoystickSpeedsCycle",Stage,CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex)
+
+
+def SendAUCSCommand(Command:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows sending low level AUCS commands to the ECX box stage. Only
+    applies to Elite/Summit/S300 stations.
+    API Status: internal
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 60000
+    Example:SendAUCSCommand "MM 1 0 INIT 0"
+    """
+    rsp = MessageServerInterface.sendSciCommand("SendAUCSCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadCompensationStatus(Stage:str="", Compensation:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command allows reading if a specific type of compensation is enabled or
+    disabled. Returns an error if this type of compensation is not available for
+    this stage.
+    API Status: internal
+    Args:
+        Stage:str = "None"
+        Compensation:str = "None"
+    Returns:
+        Enabled:int
+        Active:int
+    Command Timeout: 5000
+    Example:ReadCompensationStatus C A
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCompensationStatus",Stage,Compensation)
+    global ReadCompensationStatus_Response
+    if not "ReadCompensationStatus_Response" in globals(): ReadCompensationStatus_Response = namedtuple("ReadCompensationStatus_Response", "Enabled,Active")
+    return ReadCompensationStatus_Response(int(rsp[0]),int(rsp[1]))
+
+def RegisterNotification(NotificationCode:int="", WantNotification:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Deprecated. All Kernel notifications are now enabled by default.
+    API Status: internal
+    Args:
+        NotificationCode:int = 0
+        WantNotification:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("RegisterNotification",NotificationCode,WantNotification)
+
+
+def AlertNotification(NotificationId:int="", Value1:Decimal="", Value2:Decimal="", Value3:Decimal=""):
+    """
+    This is not a regular command. Asynchronous notifications will be sent from the
+    Kernel controller to the host system only. All notifications can be switched off
+    and on, except the Prober reset notification (ID01).  /warning This is a stub
+    implementation without appropriate handling
+    API Status: published
+    Args:
+        NotificationId:int = 0
+        Value1:Decimal = 0
+        Value2:Decimal = 0
+        Value3:Decimal = 0
+    Command Timeout: 5000
+    Example:AlertNotification 31 195000 160000 0
+    """
+    MessageServerInterface.sendSciCommand("AlertNotification",NotificationId,Value1,Value2,Value3)
+
+
+def SetCompensationStatus(Stage:str="", Compensation:str="", Status:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables a compensation mode for the specified stage
+    API Status: internal
+    Args:
+        Stage:str = "None"
+        Compensation:str = "None"
+        Status:int = -1
+    Command Timeout: 5000
+    Example:SetCompensationStatus C A 1
+    """
+    MessageServerInterface.sendSciCommand("SetCompensationStatus",Stage,Compensation,Status)
+
+
+def GetControllerInfo(ControllerInfo:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command gets the value "Value" for the parameter "Parameter". The unit is
+    parameter specific.
+    API Status: internal
+    Args:
+        ControllerInfo:str = "Unknown"
+    Returns:
+        Value:Decimal
+    Command Timeout: 1000
+    Example:GetControllerInfo HasScanChuckZ
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetControllerInfo",ControllerInfo)
+    return Decimal(rsp[0])
+
+def SetOperationalMode(OperationalMode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    In unprotected mode a number of security features like software fence and
+    initialization necessity are deactivated.          Unprotected mode is
+    deactivated automatically after 5 minutes. Sending 'SetOperationalMode U'
+    anytime before resets the timer back to 5 minutes. It is not necessary to
+    deactivate it before.  **WARNING**: If unprotected mode is enabled, even the
+    most basic safety- and sanity-checks are skipped. Any movement may cause
+    irreparable damage to the prober or attached hardware.
+    API Status: internal
+    Args:
+        OperationalMode:str = "ProtectedMode"
+    Command Timeout: 5000
+    Example:SetOperationalMode P
+    """
+    MessageServerInterface.sendSciCommand("SetOperationalMode",OperationalMode)
+
+
+def GetNanoChamberState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the currently configured Nano-chamber-state.
+    API Status: internal
+    Returns:
+        NanoChamberState:str
+    Command Timeout: 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNanoChamberState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetNanoChamberState(NanoChamberState:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the NanoChamber-state.
+    API Status: internal
+    Args:
+        NanoChamberState:str = "Free"
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("SetNanoChamberState",NanoChamberState)
+
+
+def SetCameraCool(State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows to force activate/deactivate the camera cool output or to let it be set
+    automatically by purge control.
+    API Status: internal
+    Args:
+        State:int = 2
+    Command Timeout: 10000
+    Example:SetCameraCool 0
+    """
+    MessageServerInterface.sendSciCommand("SetCameraCool",State)
+
+
+def ActivateChuckVacuum():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the chuck vacuum and forces it to be on. This command ignores the
+    vacuum sensor and timeout.
+    API Status: internal
+    Command Timeout: 10000
+    Example:ActivateChuckVacuum
+    """
+    MessageServerInterface.sendSciCommand("ActivateChuckVacuum")
+
+
+def ReadMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns a point from the matrix compensation table for the
+    specified axis from the kernel. All command parameters are mandatory.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        MatrixIndexX:int = 0
+        MatrixIndexY:int = 0
+    Returns:
+        XVal:Decimal
+        YVal:Decimal
+    Command Timeout: 5000
+    Example:ReadMatrixValues C 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMatrixValues",Stage,MatrixIndexX,MatrixIndexY)
+    global ReadMatrixValues_Response
+    if not "ReadMatrixValues_Response" in globals(): ReadMatrixValues_Response = namedtuple("ReadMatrixValues_Response", "XVal,YVal")
+    return ReadMatrixValues_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int="", XVal:Decimal="", YVal:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Downloads a point of the matrix compensation table for a specified stage to the
+    kernel. All command parameters are mandatory.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        MatrixIndexX:int = 0
+        MatrixIndexY:int = 0
+        XVal:Decimal = 0
+        YVal:Decimal = 0
+    Command Timeout: 5000
+    Example:SetMatrixValues C 0 0 5000.0 5000.0 2500.0
+    """
+    MessageServerInterface.sendSciCommand("SetMatrixValues",Stage,MatrixIndexX,MatrixIndexY,XVal,YVal)
+
+
+def ReadMEAStatus(Stage:str="", Type:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads if the MEA file for a stage is loaded/enabled (Nucleus legacy stations
+    only)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Type:int = 0
+    Returns:
+        Enable:int
+    Command Timeout: 5000
+    Example:ReadMEAStatus C 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMEAStatus",Stage,Type)
+    return int(rsp[0])
+
+def LoadMEAFile(Stage:str="", Type:int="", Load:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Load the MEA file for a stage (Nucleus legacy stations only)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Type:int = 0
+        Load:int = 0
+    Command Timeout: 5000
+    Example:LoadMEAFile C 0 1
+    """
+    MessageServerInterface.sendSciCommand("LoadMEAFile",Stage,Type,Load)
+
+
+def ReadSoftwareLimits(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The command returns the positions of the actual software limits (end of move
+    range) for each axis of the specified stage in microns. If the Theta stage is
+    selected Z1 and Z2 include the values for the Theta limits.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        ZLowValue:Decimal
+        ZHighValue:Decimal
+        X1Value:Decimal
+        Y1Value:Decimal
+        X2Value:Decimal
+        Y2Value:Decimal
+        X3Value:Decimal
+        Y3Value:Decimal
+        X4Value:Decimal
+        Y4Value:Decimal
+    Command Timeout: 5000
+    Example:ReadSoftwareLimits C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSoftwareLimits",Stage)
+    global ReadSoftwareLimits_Response
+    if not "ReadSoftwareLimits_Response" in globals(): ReadSoftwareLimits_Response = namedtuple("ReadSoftwareLimits_Response", "ZLowValue,ZHighValue,X1Value,Y1Value,X2Value,Y2Value,X3Value,Y3Value,X4Value,Y4Value")
+    return ReadSoftwareLimits_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def SetSoftwareFence(Stage:str="", AuxID:int="", FenceForm:str="", XBase:Decimal="", YBase:Decimal="", XDist:Decimal="", YDist:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets types and dimensions of technological software fences. It can
+    also be used for enabling and disabling the software fence.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxID:int = 0
+        FenceForm:str = "None"
+        XBase:Decimal = 0
+        YBase:Decimal = 0
+        XDist:Decimal = 0
+        YDist:Decimal = 0
+    Command Timeout: 10000
+    Example:SetSoftwareFence C 0 R 5000 5000 25000 25000
+    """
+    MessageServerInterface.sendSciCommand("SetSoftwareFence",Stage,AuxID,FenceForm,XBase,YBase,XDist,YDist)
+
+
+def GetSoftwareFence(Stage:str="", AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the type and the dimensions of an actual set technological
+    software fence. In case of a rectangular software fence, X and Y coordinates of
+    the four edge points of the fence are given back. In case of a circular software
+    fence, X and Y coordinates of the center point and the radius are given back.
+    All other return values are filled with zeros. All position values are in
+    microns from zero.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxID:int = 0
+    Returns:
+        FenceForm:str
+        XValue1:Decimal
+        YValue1:Decimal
+        XValue2:Decimal
+        YValue2:Decimal
+        XValue3:Decimal
+        YValue3:Decimal
+        XValue4:Decimal
+        YValue4:Decimal
+    Command Timeout: 10000
+    Example:GetSoftwareFence C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwareFence",Stage,AuxID)
+    global GetSoftwareFence_Response
+    if not "GetSoftwareFence_Response" in globals(): GetSoftwareFence_Response = namedtuple("GetSoftwareFence_Response", "FenceForm,XValue1,YValue1,XValue2,YValue2,XValue3,YValue3,XValue4,YValue4")
+    return GetSoftwareFence_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]))
+
+def GetZFence(Stage:str="", CompLayer:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This commands reads if the Z-Fence is activated and the currently set Z-fence
+    values for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CompLayer:str = "Default"
+    Returns:
+        Enabled:int
+        ZLow:Decimal
+        ZHigh:Decimal
+    Command Timeout: 10000
+    Example:GetZFence S
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZFence",Stage,CompLayer)
+    global GetZFence_Response
+    if not "GetZFence_Response" in globals(): GetZFence_Response = namedtuple("GetZFence_Response", "Enabled,ZLow,ZHigh")
+    return GetZFence_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetZFence(Stage:str="", Enabled:int="", ZLow:Decimal="", ZHigh:Decimal="", CompLayer:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This commands sets Z-Fence and the Z-fence values for the specified stage.
+    Values are stored uncompensated internally and set default compensated as
+    default.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Enabled:int = 0
+        ZLow:Decimal = 0
+        ZHigh:Decimal = 0
+        CompLayer:str = "Default"
+    Command Timeout: 10000
+    Example:SetZFence S 1 5000 10000
+    """
+    MessageServerInterface.sendSciCommand("SetZFence",Stage,Enabled,ZLow,ZHigh,CompLayer)
+
+
+def ResetProber(Mode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Restarts the Prober and replaces the current configuration with a formerly
+    written recovery file. If no recovery file was written, the configuration is
+    reset to the version of the last Prober restart. For ProberBench electronics,
+    'H' will restart the Operating system, 'S' will only restart the Kernel
+    application. For Windows Kernel, 'H' and 'S' are identical.
+    API Status: internal
+    Args:
+        Mode:str = "S"
+    Command Timeout: 20000
+    Example:ResetProber S
+    """
+    MessageServerInterface.sendSciCommand("ResetProber",Mode)
+
+
+def ResetCBox(ResetMode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reboots the operation system inside the Joystick Controller and restarts the
+    functionality. The restart will need a time of around 20 seconds.
+    API Status: internal
+    Args:
+        ResetMode:str = "S"
+    Command Timeout: 20000
+    Example:ResetCBox S
+    """
+    MessageServerInterface.sendSciCommand("ResetCBox",ResetMode)
+
+
+def ReadStageLocations(Stage:str="", LocationType:str="", AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The Home Position on the Chuck or ProbeHead Z axis is also called contact
+    height. The Home Position on the Scope Z axis is also called focus height.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        LocationType:str = "Center"
+        AuxID:int = 0
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadStageLocations C C 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadStageLocations",Stage,LocationType,AuxID)
+    global ReadStageLocations_Response
+    if not "ReadStageLocations_Response" in globals(): ReadStageLocations_Response = namedtuple("ReadStageLocations_Response", "X,Y,Z")
+    return ReadStageLocations_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetDataIterator(ShowAll:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a data stream handle which represents a data stream of setup parameters.
+    and requires the GetNextDatum command.
+    API Status: internal
+    Args:
+        ShowAll:int = 0
+    Returns:
+        IdentityToken:int
+        SizeNoAll:int
+    Command Timeout: 10000
+    Example:GetDataIterator 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDataIterator",ShowAll)
+    global GetDataIterator_Response
+    if not "GetDataIterator_Response" in globals(): GetDataIterator_Response = namedtuple("GetDataIterator_Response", "IdentityToken,SizeNoAll")
+    return GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def GetNextDatum(IdentityToken:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the next parameter from the data stream. Fields are separated by a
+    colon. Structure of the response parameter Value:
+    Path_Path:Name:Description:Value
+    API Status: internal
+    Args:
+        IdentityToken:int = 0
+    Returns:
+        IsLastDatum:int
+        DatumCode:int
+        Attributes:int
+        PathNameDescrValue:str
+    Command Timeout: 10000
+    Example:GetNextDatum 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNextDatum",IdentityToken)
+    global GetNextDatum_Response
+    if not "GetNextDatum_Response" in globals(): GetNextDatum_Response = namedtuple("GetNextDatum_Response", "IsLastDatum,DatumCode,Attributes,PathNameDescrValue")
+    return GetNextDatum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetDatum(PathNameAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        PathNameAndValue:str = ""
+    Command Timeout: 20000
+    Example:SetDatum Chuck:AlignGap:25
+    """
+    MessageServerInterface.sendSciCommand("SetDatum",PathNameAndValue)
+
+
+def GetDatum(PathName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a value string. The Value string consists of the value and the
+    description. The Locator only consists of the path and the name. All fields are
+    separated by a colon.  Structure of the command parameter Locator:
+    Path_Path:Name Structure of the response parameter Value: Value:Description
+    API Status: internal
+    Args:
+        PathName:str = ""
+    Returns:
+        Attributes:int
+        DatumCode:int
+        ValueDesc:str
+    Command Timeout: 5000
+    Example:GetDatum Chuck:AlignGap
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDatum",PathName)
+    global GetDatum_Response
+    if not "GetDatum_Response" in globals(): GetDatum_Response = namedtuple("GetDatum_Response", "Attributes,DatumCode,ValueDesc")
+    return GetDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetRecoveryDatum(PathNameAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        PathNameAndValue:str = ""
+    Command Timeout: 5000
+    Example:SetRecoveryDatum Chuck:AlignGap:25
+    """
+    MessageServerInterface.sendSciCommand("SetRecoveryDatum",PathNameAndValue)
+
+
+def TraceStart(Controller:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the motion recording. The recording parameters are set in dynamic
+    kernel setup.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Command Timeout: 10000
+    Example:TraceStart C
+    """
+    MessageServerInterface.sendSciCommand("TraceStart",Controller)
+
+
+def TraceStatus(Controller:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Checks the motion recording status for one stage.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Returns:
+        IsReady:int
+        SizeCh0Raw:int
+        SizeCh0Comp:int
+        SizeCh1Raw:int
+        SizeCh1Comp:int
+        SizeCh2Raw:int
+        SizeCh2Comp:int
+        SizeCh3Raw:int
+        SizeCh3Comp:int
+    Command Timeout: 10000
+    Example:TraceStatus C
+    """
+    rsp = MessageServerInterface.sendSciCommand("TraceStatus",Controller)
+    global TraceStatus_Response
+    if not "TraceStatus_Response" in globals(): TraceStatus_Response = namedtuple("TraceStatus_Response", "IsReady,SizeCh0Raw,SizeCh0Comp,SizeCh1Raw,SizeCh1Comp,SizeCh2Raw,SizeCh2Comp,SizeCh3Raw,SizeCh3Comp")
+    return TraceStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def TraceGetData(Controller:str="", Channel:int="", PointOne:int="", IsCompress:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get a collection of five data pairs. A pair is the index and the value of a
+    recording point. If the stream is empty or at the end the index is 1 and the
+    value 0. The index is relative to the start of the motion recording. The
+    recording is clocked by the motion controller cycle. The cycle time is contained
+    in the Kernel setup. In the raw stream all recorded trace points are contained.
+    But in the compressed stream only the non-linear depending trace points are
+    contained. To reload the recording points the stream must be reset to the first
+    recording point.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+        Channel:int = 0
+        PointOne:int = 1
+        IsCompress:int = 1
+    Returns:
+        Point1:int
+        Value1:int
+        Point2:int
+        Value2:int
+        Point3:int
+        Value3:int
+        Point4:int
+        Value4:int
+        Point5:int
+        Value5:int
+    Command Timeout: 10000
+    Example:TraceGetData C 0 0 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("TraceGetData",Controller,Channel,PointOne,IsCompress)
+    global TraceGetData_Response
+    if not "TraceGetData_Response" in globals(): TraceGetData_Response = namedtuple("TraceGetData_Response", "Point1,Value1,Point2,Value2,Point3,Value3,Point4,Value4,Point5,Value5")
+    return TraceGetData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def TraceSetDataPosition(Controller:str="", Channel:int="", NewPos:int="", IsCompress:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the index position in the raw or compressed stream for the next call of the
+    command TraceGetData.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+        Channel:int = 0
+        NewPos:int = 0
+        IsCompress:int = 1
+    Command Timeout: 10000
+    Example:TraceSetDataPosition C 0 1000 1
+    """
+    MessageServerInterface.sendSciCommand("TraceSetDataPosition",Controller,Channel,NewPos,IsCompress)
+
+
+def TraceStop(Controller:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the motion recording.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Command Timeout: 10000
+    Example:TraceStop C
+    """
+    MessageServerInterface.sendSciCommand("TraceStop",Controller)
+
+
+def SetZProfilePoint(Stage:str="", XValue:Decimal="", YValue:Decimal="", ZGap:Decimal="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set a point for the Z height profile. If this profile is enabled, the Z height
+    depends on a X and Y coordinate. The Z value is a gap to the current Z height.
+    Positive values are elevated spots, negative values are hollows. The height
+    profile is used to adjust the Z height. The adjusted Z height at a X and Y
+    position is derivated from the nearest profile point. The Z contact level will
+    be calculated from the contact height and the stored Z gap at this point.  See
+    GetZProfilePoint for details.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        ZGap:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        ZProfileType:int = 0
+    Returns:
+        ValueCount:int
+    Command Timeout: 5000
+    Example:SetZProfilePoint C 5000 5000 -3 H Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetZProfilePoint",Stage,XValue,YValue,ZGap,PosRef,Unit,ZProfileType)
+    return int(rsp[0])
+
+def ReadZProfilePoint(Stage:str="", Index:int="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get a single point and the corresponding Z gap of the Z height profile.  The
+    different z profiles are:  - transient: meant to be used on a per-wafer-basis,
+    default - persistent: configured once, stays in memory - persistent-offset: same
+    as persistent, active when offset is enabled - scratch: not used internaly. Can
+    be used to translate KernelDatums <-> ZProfile-Points
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Index:int = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        ZProfileType:int = 0
+    Returns:
+        XValue:Decimal
+        YValue:Decimal
+        ZGap:Decimal
+        ValueCount:int
+    Command Timeout: 5000
+    Example:ReadZProfilePoint C 1 H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadZProfilePoint",Stage,Index,PosRef,Unit,ZProfileType)
+    global ReadZProfilePoint_Response
+    if not "ReadZProfilePoint_Response" in globals(): ReadZProfilePoint_Response = namedtuple("ReadZProfilePoint_Response", "XValue,YValue,ZGap,ValueCount")
+    return ReadZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]))
+
+def ClearZProfile(Stage:str="", ZProfileType:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clears all profile points. See GetZProfile for type description.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZProfileType:int = 0
+    Command Timeout: 5000
+    Example:ClearZProfile C
+    """
+    MessageServerInterface.sendSciCommand("ClearZProfile",Stage,ZProfileType)
+
+
+def ReadScopeSilo(Index:int=""):
+    """
+    Returns the definition of a silo. If the type is rectangle, center means
+    _Point1_. If the type is circle, the meaning of Pos2X and Pos2Y is undefined.
+    API Status: published
+    Args:
+        Index:int = 1
+    Returns:
+        Type:str
+        CenterX:Decimal
+        CenterY:Decimal
+        Radius:Decimal
+        Pos2X:Decimal
+        Pos2Y:Decimal
+        ZHigh:Decimal
+        RefX:Decimal
+        RefY:Decimal
+        RefZ:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeSilo 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSilo",Index)
+    global ReadScopeSilo_Response
+    if not "ReadScopeSilo_Response" in globals(): ReadScopeSilo_Response = namedtuple("ReadScopeSilo_Response", "Type,CenterX,CenterY,Radius,Pos2X,Pos2Y,ZHigh,RefX,RefY,RefZ")
+    return ReadScopeSilo_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def NewProjectFile(FileName:str=""):
+    """
+    Alerts applications if the project file was changed.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("NewProjectFile",FileName)
+
+
+def SaveProjectFile(FileName:str=""):
+    """
+    Alerts applications to save the current project.  This notification _MUST_ only
+    be invoked by CommonCommands. Sending this notification directly _WILL_ give
+    erroneous results.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectFile",FileName)
+
+
+def NewAccessLevel(AccessLevel:str="", UserName:str="", VeloxLocked:int=""):
+    """
+    Alerts applications of new access level.
+    API Status: published
+    Args:
+        AccessLevel:str = "Engineer"
+        UserName:str = ""
+        VeloxLocked:int = 0
+    Command Timeout: 5000
+    Example:NewAccessLevel 1
+    """
+    MessageServerInterface.sendSciCommand("NewAccessLevel",AccessLevel,UserName,VeloxLocked)
+
+
+def LicenseInfo(AnnualEnabled:int="", AnnualDaysLeft:int="", VeloxProEnabled:int="", VueTrackEnabled:int="", VueTrack4PEnabled:int="", ReAlignEnabled:int="", AutomationEnabled:int="", IdToolsEnabled:int="", IVistaEnabled:int="", IVistaProEnabled:int="", LaserCutterEnabled:int="", SiPToolsEnabled:int="", AutoRfEnabled:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifys the listener about the licensed Velox features. Is sent cyclically by
+    CommonCommands.
+    API Status: internal
+    Args:
+        AnnualEnabled:int = 1
+        AnnualDaysLeft:int = 460
+        VeloxProEnabled:int = 0
+        VueTrackEnabled:int = 0
+        VueTrack4PEnabled:int = 0
+        ReAlignEnabled:int = 0
+        AutomationEnabled:int = 0
+        IdToolsEnabled:int = 0
+        IVistaEnabled:int = 0
+        IVistaProEnabled:int = 0
+        LaserCutterEnabled:int = 0
+        SiPToolsEnabled:int = 0
+        AutoRfEnabled:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LicenseInfo",AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled)
+
+
+def RegisterProberAppChange(AppName:str="", SecName:str="", NewRegistered:int=""):
+    """
+    Alerts applications that an application is registered or unregistered on
+    MsgServer.
+    API Status: published
+    Args:
+        AppName:str = "SharedTest"
+        SecName:str = "SharedTest"
+        NewRegistered:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("RegisterProberAppChange",AppName,SecName,NewRegistered)
+
+
+def AlignmentModeChange(AlignmentMode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications of a change of the current alignment mode
+    API Status: internal
+    Args:
+        AlignmentMode:str = "OnAxis"
+    Command Timeout: 5000
+    Example:AlignmentModeChange OnAxis
+    """
+    MessageServerInterface.sendSciCommand("AlignmentModeChange",AlignmentMode)
+
+
+def KernelConnectionStatus(ControllerNum:int="", Type:str="", Result:str="", Desc:str=""):
+    """
+    An example of Kernel Connection Status is &quot;Windows Socket Error Number and
+    Error Description.&quot;
+    API Status: published
+    Args:
+        ControllerNum:int = 1
+        Type:str = "Socket"
+        Result:str = "Disconnected"
+        Desc:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelConnectionStatus",ControllerNum,Type,Result,Desc)
+
+
+def KernelCompensationStatusChange(Stage:str="", Compensation:str="", Enabled:int="", Active:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications that a Kernel compensation has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Compensation:str = "None"
+        Enabled:int = 0
+        Active:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelCompensationStatusChange",Stage,Compensation,Enabled,Active)
+
+
+def KernelCompensationLevelChange(Stage:str="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications that a Kernel compensation level has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Comp:str = "None"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelCompensationLevelChange",Stage,Comp)
+
+
+def MoveZCombinedStatusChange(Status:str="", PlatenSafe:int="", Height:Decimal="", HeightMax:Decimal="", HeightRelative:Decimal="", SafeHeight:Decimal="", Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies about changes in the combined-z-move-system
+    API Status: internal
+    Args:
+        Status:str = "Off"
+        PlatenSafe:int = 0
+        Height:Decimal = 0
+        HeightMax:Decimal = 0
+        HeightRelative:Decimal = 0
+        SafeHeight:Decimal = 0
+        Message:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombinedStatusChange",Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message)
+
+
+def MachineStateChange(MachineState:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies about changes in the machine state
+    API Status: internal
+    Args:
+        MachineState:str = "Off"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MachineStateChange",MachineState)
+
+
+def ChuckVacuumChangeRequest(VacuumState:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies if the user requests a chuck vacuum change
+    API Status: internal
+    Args:
+        VacuumState:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ChuckVacuumChangeRequest",VacuumState)
+
+
+def SoftwareStopChangedNotify(SoftwareStopState:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies if software stop was activated or deactivated
+    API Status: internal
+    Args:
+        SoftwareStopState:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SoftwareStopChangedNotify",SoftwareStopState)
+
+
+def KernelQuietModeChange(IsQuiet:int="", Stage:str="", IsStageQuiet:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Informs if the overall quiet mode changes and about changes of single stages
+    API Status: internal
+    Args:
+        IsQuiet:int = 0
+        Stage:str = "None"
+        IsStageQuiet:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelQuietModeChange",IsQuiet,Stage,IsStageQuiet)
+
+
+def ConfigurationChanged(ParameterChanged:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies that a configuration item has changed by some application
+    API Status: internal
+    Args:
+        ParameterChanged:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ConfigurationChanged",ParameterChanged)
+
+
+def ScopeWorkingStageChanged(ScopeWorkingStage:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Informs that a new working stage is active
+    API Status: internal
+    Args:
+        ScopeWorkingStage:int = -1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ScopeWorkingStageChanged",ScopeWorkingStage)
+
+
+def BnR_AxisNotify(Stage:str="", Axis:str="", State:str="", AdditionalStateInfo:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the user Interface and Kernel if the state of the axis has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        State:str = "NotExisting"
+        AdditionalStateInfo:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AxisNotify",Stage,Axis,State,AdditionalStateInfo)
+
+
+def BnR_StageNotify(Stage:str="", State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the stage status has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_StageNotify",Stage,State)
+
+
+def BnR_InputNotify(Channel:str="", State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state of an input channel has changed.
+    API Status: internal
+    Args:
+        Channel:str = "0"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_InputNotify",Channel,State)
+
+
+def BnR_OutputNotify(Channel:str="", State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state of an output channel has changed.
+    API Status: internal
+    Args:
+        Channel:str = "0"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_OutputNotify",Channel,State)
+
+
+def BnR_AxisStatusNotify(Stage:str="", Axis:str="", Initialized:int="", PositiveLimit:int="", NegativeLimit:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifys the listener that an axis status has changed. Currently used to notify
+    the Kernel about the init state of a BnR axis.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        Initialized:int = 0
+        PositiveLimit:int = 0
+        NegativeLimit:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AxisStatusNotify",Stage,Axis,Initialized,PositiveLimit,NegativeLimit)
+
+
+def AutoXYModeChange(AutoXYModeOn:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent by Spectrum if Automation was enabled or disabled. This can be AutoXY,
+    AutoZ or VueTrack. Handled by WaferMap to ensure that automation is executed
+    when stepping.
+    API Status: internal
+    Args:
+        AutoXYModeOn:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("AutoXYModeChange",AutoXYModeOn)
+
+
+def ZoomLevelChange(ZoomLevel:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent by OpticalControl when the AZoom zoom level is changed. Spectrum should
+    handle this so it doesn't have to poll OpticalControl for the current zoom
+    level.
+    API Status: internal
+    Args:
+        ZoomLevel:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ZoomLevelChange",ZoomLevel)
+
+
+def BnR_AnalogIONotify(AnalogIO:str="", ValuePercent:Decimal="", UnderOverflow:int="", Error:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state or value of an analog input or output channel
+    has changed.
+    API Status: internal
+    Args:
+        AnalogIO:str = "AO_PurgeDewPoint"
+        ValuePercent:Decimal = 0
+        UnderOverflow:int = 0
+        Error:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AnalogIONotify",AnalogIO,ValuePercent,UnderOverflow,Error)
+
+
+def BnR_ControllerInfoNotify(ControllerNum:int="", ControllerInfo:str="", Value:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies the listener about changed controller info. Currently used to inform
+    Toolbar about the battery state of the BnR controller.
+    API Status: internal
+    Args:
+        ControllerNum:int = 1
+        ControllerInfo:str = "BatteryOK"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_ControllerInfoNotify",ControllerNum,ControllerInfo,Value)
+
+
+def BnR_PositionNotify(Stage:str="", XorT:Decimal="", Y:Decimal="", Z:Decimal="", CommandedXorT:Decimal="", CommandedY:Decimal="", CommandedZ:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent by BnR controller if a axis position has changed. Currently
+    used to notify the Kernel about the new axis position.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XorT:Decimal = 0
+        Y:Decimal = 0
+        Z:Decimal = 0
+        CommandedXorT:Decimal = 0
+        CommandedY:Decimal = 0
+        CommandedZ:Decimal = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_PositionNotify",Stage,XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ)
+
+
+def BnR_InfoNotify(InfoType:str="", Info:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Generic Information Notification
+    API Status: internal
+    Args:
+        InfoType:str = ""
+        Info:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_InfoNotify",InfoType,Info)
+
+
+def WMNewCurrentDie(DieX:int="", DieY:int="", XFromHome:Decimal="", YFromHome:Decimal="", CurSite:int="", LastSiteIndex:int=""):
+    """
+    Alerts applications that WaferMap has a new position.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        XFromHome:Decimal = 0
+        YFromHome:Decimal = 0
+        CurSite:int = 1
+        LastSiteIndex:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("WMNewCurrentDie",DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex)
+
+
+def WMSetupChange():
+    """
+    Alerts applications that a wafer's parameters have been changed.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("WMSetupChange")
+
+
+def ButtonPress(TargetIdent:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent when button instrumented for guided workflow is pressed. The TargetIdent is
+    the identifier for the button as defined for the guided workflow.
+    API Status: internal
+    Args:
+        TargetIdent:int = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("ButtonPress",TargetIdent)
+
+
+def CryoCmdReady(State:str="", Error:int="", ErrorDescription:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent when the cooling or heating process was terminated successfully or
+    incorrectly. Returns the status with which the process was finished (IDLE, COLD,
+    COOL DOWN, WARMUP) and sends the error code and error message.
+    API Status: internal
+    Args:
+        State:str = "IDLE"
+        Error:int = 0
+        ErrorDescription:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CryoCmdReady",State,Error,ErrorDescription)
+
+
+def VMProjectLoaded():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification sent when Spectrum VS project has finished loading.
+    API Status: internal
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("VMProjectLoaded")
+
+
+def VMProbeCardData(Access:str="", FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent when a probe card file is loaded.
+    API Status: internal
+    Args:
+        Access:str = "L"
+        FileName:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("VMProbeCardData",Access,FileName)
+
+
+def TTLTestDone():
+    """
+    Alerts applications that the TTL Test is ready.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("TTLTestDone")
+
+
+def PSStateChanged(State:str="", SubState:str="", Message:str="", Error:int=""):
+    """
+    Notification sent when VeloxPro changes its running state.
+    API Status: published
+    Args:
+        State:str = "Unknown"
+        SubState:str = "Unknown"
+        Message:str = ""
+        Error:int = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSStateChanged",State,SubState,Message,Error)
+
+
+def PSProgressChanged(ProgressPercent:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification sent during wafer stepping process. It updates the progress
+    information. 'Progress' is the relationship of dies tested to dies to be tested.
+    API Status: internal
+    Args:
+        ProgressPercent:Decimal = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSProgressChanged",ProgressPercent)
+
+
+def PSLoaderUsage(UseLoader:int="", UseAutoWafer:int="", WaferSizes:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent to notify the listener about usage of Loader, usage of
+    fully/semiautomatic mode and supported wafer sizes of process station.
+    API Status: internal
+    Args:
+        UseLoader:int = 0
+        UseAutoWafer:int = 0
+        WaferSizes:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSLoaderUsage",UseLoader,UseAutoWafer,WaferSizes)
+
+
+def LoaderMessage(Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent by loader to display a message on the process station.
+    API Status: internal
+    Args:
+        Message:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("LoaderMessage",Message)
+
+
+def OpenProjectDialog(ProjectFilename:str="", Option:int=""):
+    """
+    Asks if the current project should be saved and then brings up the Open Project
+    window which opens the selected project file if the user clicks ok.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+        Option:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("OpenProjectDialog",ProjectFilename,Option)
+
+
+def SaveProjectAsDialog():
+    """
+    Brings up the Save Project window which saves the project if the user clicks ok.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectAsDialog")
+
+
+def LoginDialog(LevelToOffer:str=""):
+    """
+    Brings up the Login window and sends a New Access Level alert if the user enters
+    a valid password.
+    API Status: published
+    Args:
+        LevelToOffer:str = "1"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LoginDialog",LevelToOffer)
+
+
+def GetStatus():
+    """
+    Returns the current software status. The server holds and maintains the software
+    status. Status can be changed by using any of the following commands:
+    BeginProbing, LoginDialog, AbortProbing, SetExternalMode, PauseProbing,
+    UnloadWafer, ResumeProbing
+    API Status: published
+    Returns:
+        DummyCommonMode:int
+        RunningMode:str
+        AccessLevel:str
+        ExternalMode:int
+        LicenseDaysLeft:int
+        MKH:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetStatus")
+    global GetStatus_Response
+    if not "GetStatus_Response" in globals(): GetStatus_Response = namedtuple("GetStatus_Response", "DummyCommonMode,RunningMode,AccessLevel,ExternalMode,LicenseDaysLeft,MKH")
+    return GetStatus_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def LicensingDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the Licensing window.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LicensingDialog")
+
+
+def GetLicenseInfo():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current license information.
+    API Status: internal
+    Returns:
+        AnnualEnabled:int
+        AnnualDaysLeft:int
+        VeloxProEnabled:int
+        VueTrackEnabled:int
+        VueTrack4PEnabled:int
+        ReAlignEnabled:int
+        AutomationEnabled:int
+        IdToolsEnabled:int
+        IVistaEnabled:int
+        IVistaProEnabled:int
+        LaserCutterEnabled:int
+        SiPToolsEnabled:int
+        AutoRfEnabled:int
+        SecsGemEnabled:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLicenseInfo")
+    global GetLicenseInfo_Response
+    if not "GetLicenseInfo_Response" in globals(): GetLicenseInfo_Response = namedtuple("GetLicenseInfo_Response", "AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled,SecsGemEnabled")
+    return GetLicenseInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]))
+
+def GetProjectFile():
+    """
+    Returns the current project file.
+    API Status: published
+    Returns:
+        ProjectFilename:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProjectFile")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportSoftwareVersion():
+    """
+    Returns the Velox software version as string.
+    API Status: published
+    Returns:
+        SoftwareVersion:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReportSoftwareVersion")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OpenProject(ProjectFilename:str=""):
+    """
+    The OpenProject command opens the specified project.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("OpenProject",ProjectFilename)
+
+
+def IsAppRegistered(Application:str=""):
+    """
+    Checks the server to see if the application "AppName" is registered with the
+    server.
+    API Status: published
+    Args:
+        Application:str = ""
+    Returns:
+        IsAppRegistered:int
+    Command Timeout: 5000
+    Example:IsAppRegistered WaferMap
+    """
+    rsp = MessageServerInterface.sendSciCommand("IsAppRegistered",Application)
+    return int(rsp[0])
+
+def SaveProject(ProjectFilename:str=""):
+    """
+    Saves the current data to the project file.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("SaveProject",ProjectFilename)
+
+
+def GetSoftwarePath(PathType:str=""):
+    """
+    Returns the path for either the applications/data or project files.
+    API Status: published
+    Args:
+        PathType:str = "User"
+    Returns:
+        SoftwarePath:str
+    Command Timeout: 5000
+    Example:GetSoftwarePath User
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwarePath",PathType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CCSelectLens(Lens:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Internal AZoom Helper Command.
+    API Status: internal
+    Args:
+        Lens:int = 1
+    Command Timeout: 10000
+    Example:CCSelectLens 1
+    """
+    MessageServerInterface.sendSciCommand("CCSelectLens",Lens)
+
+
+def CCReadCurrentLens():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Internal AZoom Helper Command. Probably no longer used.
+    API Status: internal
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CCReadCurrentLens")
+    return int(rsp[0])
+
+def CCMoveAuxSite(AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command calls the Kernel command MoveAuxSite to move the chuck to the
+    position of a given AUX site. For the transfer move a safe height is used. If
+    AUX ID is set to 0, the target of the move is the wafer site. If the flag 'Auto
+    Align by Spectrum' in ControlCenter-SystemSetup-Aux Sites is True, the Spectrum
+    command AlignAux is executed after MoveAuxSite to align the site automatically.
+    The flag is only visible, if the aux site type is CalSubstrate and Spectrum is
+    installed. AUX ID in the response is the ID of the new active site.
+    API Status: internal
+    Args:
+        AuxID:int = 1
+    Command Timeout: 200000
+    """
+    MessageServerInterface.sendSciCommand("CCMoveAuxSite",AuxID)
+
+
+def ExecuteCleaningSequence(SequenceName:str="", AllowMediaReuse:int="", SkipAlignAux:int="", SkipReturnMove:int=""):
+    """
+    This command moves to the single cleaning site, executes CleanProbeTip, moves to
+    the contact verify site, and then moves to contact. Returns an error if the
+    clean or verify sites aren't defined.
+    API Status: published
+    Args:
+        SequenceName:str = ""
+        AllowMediaReuse:int = 0
+        SkipAlignAux:int = 0
+        SkipReturnMove:int = 0
+    Command Timeout: 1800000
+    Example:ExecuteCleaningSequence "DeepClean"
+    """
+    MessageServerInterface.sendSciCommand("ExecuteCleaningSequence",SequenceName,AllowMediaReuse,SkipAlignAux,SkipReturnMove)
+
+
+def GetAlignmentMode():
+    """
+    Get the active alignment mode (either on axis or off axis).
+    API Status: published
+    Returns:
+        AlignmentMode:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAlignmentMode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetAlignmentMode(AlignmentMode:str=""):
+    """
+    Sets the active alignment mode (either on axis or off axis).
+    API Status: published
+    Args:
+        AlignmentMode:str = "OnAxis"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SetAlignmentMode",AlignmentMode)
+
+
+def GetLoginData(CmdUserName:str=""):
+    """
+    Gets the Velox user data: name, full name, group, access level.     If the
+    commanded user name is empty, the data of the current user will be responded
+    API Status: published
+    Args:
+        CmdUserName:str = ""
+    Returns:
+        UserName:str
+        LongUserName:str
+        UserGroup:str
+        AccessLevel:str
+        VeloxLocked:int
+    Command Timeout: 5000
+    Example:GetLoginData
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLoginData",CmdUserName)
+    global GetLoginData_Response
+    if not "GetLoginData_Response" in globals(): GetLoginData_Response = namedtuple("GetLoginData_Response", "UserName,LongUserName,UserGroup,AccessLevel,VeloxLocked")
+    return GetLoginData_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]))
+
+def NucleusInitChuck():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up message box to warn user of chuck initialization for Nucleus stations.
+    Allows user to OK/Cancel.
+    API Status: internal
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("NucleusInitChuck")
+
+
+def ShutdownVeloxWithSave():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up message box to allow saving project before shutting down Velox. Allows
+    user to OK/Cancel.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ShutdownVeloxWithSave")
+
+
+def WinCalAutoCal():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalAutoCal command to WinCal.
+    API Status: internal
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalAutoCal")
+
+
+def WinCalCheckAutoRFStability(AllowMove:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalCheckAutoRFStability command to WinCal.
+    API Status: internal
+    Args:
+        AllowMove:int = 0
+    Returns:
+        StabilityPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalCheckAutoRFStability",AllowMove)
+    return int(rsp[0])
+
+def WinCalCloseRFStabilityReport():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalCloseRFStabilityReport command to WinCal.
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalCloseRFStabilityReport")
+
+
+def WinCalMoveToIssRef(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalMoveToIssRef command to WinCal to move to the specified ISS
+    reference.     The ISS index is the IssIdxMap index as returned from
+    WinCalGetIssListForAuxSite.
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("WinCalMoveToIssRef",IssIdx)
+
+
+def WinCalVerifyIssRefLocAtHome(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalVerifyIssRefLocAtHome command to WinCal and returns AllRefAtHome
+    as 1 if stage and positioners at home.
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Returns:
+        AllRefAtHome:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalVerifyIssRefLocAtHome",IssIdx)
+    return int(rsp[0])
+
+def WinCalGetIssForAuxSite(AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalGetIssForAuxSite command to WinCal and returns the ISS
+    information for the given aux site ID.
+    API Status: internal
+    Args:
+        AuxID:int = 0
+    Returns:
+        IssIdx:int
+        IssPN:str
+        IssDescription:str
+        IssEnabled:int
+        AuxSiteName:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetIssForAuxSite",AuxID)
+    global WinCalGetIssForAuxSite_Response
+    if not "WinCalGetIssForAuxSite_Response" in globals(): WinCalGetIssForAuxSite_Response = namedtuple("WinCalGetIssForAuxSite_Response", "IssIdx,IssPN,IssDescription,IssEnabled,AuxSiteName")
+    return WinCalGetIssForAuxSite_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def WinCalGetNameAndVersion():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalGetNameAndVersion command to WinCal.
+    API Status: internal
+    Returns:
+        ServerName:str
+        Version:str
+        MajorVersion:int
+        MinorVersion:int
+        Revision:int
+        Build:int
+    Command Timeout: 30000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNameAndVersion")
+    global WinCalGetNameAndVersion_Response
+    if not "WinCalGetNameAndVersion_Response" in globals(): WinCalGetNameAndVersion_Response = namedtuple("WinCalGetNameAndVersion_Response", "ServerName,Version,MajorVersion,MinorVersion,Revision,Build")
+    return WinCalGetNameAndVersion_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def WinCalMonitorNoMove():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalMonitorNoMove command to WinCal. Triggers WinCal to measure the
+    monitor portion of the current calibration setup.
+    API Status: internal
+    Returns:
+        MonitorPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalMonitorNoMove")
+    return int(rsp[0])
+
+def WinCalValidateAdvanced(ProbeSpacing:Decimal="", ResetTrace:int="", AllowMove:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalValidateAdvanced command to WinCal. Performs the validation step of
+    the currently selected calibration setup.     Resets the controller used in WinCal
+    for validataion.
+    API Status: internal
+    Args:
+        ProbeSpacing:Decimal = 130
+        ResetTrace:int = 1
+        AllowMove:int = 1
+    Returns:
+        ValidationPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalValidateAdvanced",ProbeSpacing,ResetTrace,AllowMove)
+    return int(rsp[0])
+
+def WinCalMeasureMonitorReference(AllowMove:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalMeasureMonitorReference command to WinCal.
+    API Status: internal
+    Args:
+        AllowMove:int = 0
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalMeasureMonitorReference",AllowMove)
+
+
+def WinCalGetNumValidationPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumValidationPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumValidationPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumValidationPorts")
+    return int(rsp[0])
+
+def WinCalSetNumValidationPorts(NumValidationPorts:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumValidationPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumValidationPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumValidationPorts",NumValidationPorts)
+
+
+def WinCalGetNumMonitoringPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumMonitoringPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumMonitoringPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumMonitoringPorts")
+    return int(rsp[0])
+
+def WinCalSetNumMonitoringPorts(NumMonitoringPorts:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumMonitoringPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumMonitoringPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumMonitoringPorts",NumMonitoringPorts)
+
+
+def WinCalGetNumRepeatabilityPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumRepeatabilityPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumRepeatabilityPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumRepeatabilityPorts")
+    return int(rsp[0])
+
+def WinCalSetNumRepeatabilityPorts(NumRepeatabilityPorts:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumRepeatabilityPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumRepeatabilityPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumRepeatabilityPorts",NumRepeatabilityPorts)
+
+
+def WinCalValidate():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalValidate command to WinCal. Performs the validation step of the
+    currently selected calibration setup in WinCal.
+    API Status: internal
+    Returns:
+        ValidationPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalValidate")
+    return int(rsp[0])
+
+def WinCalGetValidationSetup(Port:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends CalGetValidationSetup command to WinCal. Returns calibration setup
+    parameters.
+    API Status: internal
+    Args:
+        Port:int = 1
+    Returns:
+        StandardType:str
+        StandardPorts:int
+        StandardCompareType:int
+        StructureType:str
+        PostCorrect:int
+        PostCorrectMatching:int
+        AutoConfigure:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetValidationSetup",Port)
+    global WinCalGetValidationSetup_Response
+    if not "WinCalGetValidationSetup_Response" in globals(): WinCalGetValidationSetup_Response = namedtuple("WinCalGetValidationSetup_Response", "StandardType,StandardPorts,StandardCompareType,StructureType,PostCorrect,PostCorrectMatching,AutoConfigure")
+    return WinCalGetValidationSetup_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def WinCalAutoCalNoValidation(ProbeSpacing:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalAutoCalNoValidation command to WinCal. Performs an AutoCal
+    without the validation step
+    API Status: internal
+    Args:
+        ProbeSpacing:Decimal = 130
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalAutoCalNoValidation",ProbeSpacing)
+
+
+def WinCalHideAllWindows():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalHideAllWindows command to WinCal. This minimizes all the WinCal
+    windows
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalHideAllWindows")
+
+
+def WinCalGetReferenceStructureInfo(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetReferenceStructureInfo command to WinCal. Given the WinCal ISS
+    index it will return a string with the reference information
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Returns:
+        ReferenceInfo:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetReferenceStructureInfo",IssIdx)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def WinCalSystemSetupHasUnappliedChanges(ShowErrors:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalSystemSetupHasUnappliedChanges command to WinCal. Returns true
+    if WinCal has unapplied changes
+    API Status: internal
+    Args:
+        ShowErrors:int = 0
+    Returns:
+        HasUnappliedChanges:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalSystemSetupHasUnappliedChanges",ShowErrors)
+    return int(rsp[0])
+
+def WinCalRecordIssRefAtCurrentLoc(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalRecordIssRefAtCurrentLoc command to WinCal. Record the ISS,
+    indicated by the index, reference as being the current location
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalRecordIssRefAtCurrentLoc",IssIdx)
+
+
+def SaveProjectAsTemplateDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the Save Project as Template window which saves the project template
+    if the user clicks ok.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectAsTemplateDialog")
+
+
+def CreateProjectFromTemplateDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the New Project from Template dialog which allows the user to select a
+    template and create a new project.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CreateProjectFromTemplateDialog")
+
+
+def WinCalGetNumPortsAndProbes():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns Max Ports and Number of probes connected to a port
+    API Status: internal
+    Returns:
+        MaxPorts:int
+        NumPortsConnectedtoProbes:int
+    Command Timeout: 1000
+    Example:WinCalGetNumPortsAndProbes
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumPortsAndProbes")
+    global WinCalGetNumPortsAndProbes_Response
+    if not "WinCalGetNumPortsAndProbes_Response" in globals(): WinCalGetNumPortsAndProbes_Response = namedtuple("WinCalGetNumPortsAndProbes_Response", "MaxPorts,NumPortsConnectedtoProbes")
+    return WinCalGetNumPortsAndProbes_Response(int(rsp[0]),int(rsp[1]))
+
+def WinCalGetProbeInfoForPort(VnaPortNum:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the properties from one probe, based on the passed in index. Pass in a
+    physical VNA port number that is less than or equal to Max Probes from the call
+    to CalGetNumPortsAndProbes
+    API Status: internal
+    Args:
+        VnaPortNum:int = 1
+    Returns:
+        IsSelected:int
+        BaseProbe:str
+        Options:str
+        PhysicalOrient:str
+        IsDual:int
+        IsSymmetric:int
+        SignalConfig:str
+        SelectedPitch:int
+    Command Timeout: 1000
+    Example:WinCalGetProbeInfoForPort 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetProbeInfoForPort",VnaPortNum)
+    global WinCalGetProbeInfoForPort_Response
+    if not "WinCalGetProbeInfoForPort_Response" in globals(): WinCalGetProbeInfoForPort_Response = namedtuple("WinCalGetProbeInfoForPort_Response", "IsSelected,BaseProbe,Options,PhysicalOrient,IsDual,IsSymmetric,SignalConfig,SelectedPitch")
+    return WinCalGetProbeInfoForPort_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),str(rsp[6]),int(rsp[7]))
+
+def GetMachineState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current state of the machine.
+    API Status: internal
+    Returns:
+        MachineState:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMachineState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowAboutDialog(Pid:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shows the help about dialog for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ShowAboutDialog",Pid)
+
+
+def ShowSplashScreen(Pid:int="", TimeoutMs:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shows the splash screen for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+        TimeoutMs:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ShowSplashScreen",Pid,TimeoutMs)
+
+
+def CloseSplashScreen(Pid:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the splash screen for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("CloseSplashScreen",Pid)
+
+
+def GetLastFourProjects():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the last four project files that were opened.
+    API Status: internal
+    Returns:
+        ProjectFile1:str
+        ProjectFile2:str
+        ProjectFile3:str
+        ProjectFile4:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLastFourProjects")
+    global GetLastFourProjects_Response
+    if not "GetLastFourProjects_Response" in globals(): GetLastFourProjects_Response = namedtuple("GetLastFourProjects_Response", "ProjectFile1,ProjectFile2,ProjectFile3,ProjectFile4")
+    return GetLastFourProjects_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def WinCalExecuteCommand(Command:str=""):
+    """
+    Sends the WinCalExecuteCommand command to WinCal and returns the response
+    string.
+    API Status: published
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalExecuteCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDemoMode(TurnOnDemoMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+    This command will return an error if its called with any other parameter as 0.
+    API Status: internal
+    Args:
+        TurnOnDemoMode:int = 1
+    Command Timeout: 5000
+    Example:SetDemoMode 0
+    """
+    MessageServerInterface.sendSciCommand("SetDemoMode",TurnOnDemoMode)
+
+
+def ChangeDemoRsp(Param:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Override a command with a demo response. The command will not reach its
+    destination but the supplied demo response will be returned. An active overide
+    for a command will be removed if the provided timeout is negative. Format:  [ID]
+    [Time] [ErrorCode]:[Response]  - Id: command id in hex withoud leding 0x - Time:
+    time in ms between command and response, negativ to reset demo mode for this
+    command - Errorcode: 0 for success, everything else indicates an error -
+    Response: response string
+    API Status: internal
+    Args:
+        Param:str = ""
+    Command Timeout: 5000
+    Example:ChangeDemoRsp 31 200 0:5000.0 5000.0 8500
+    """
+    MessageServerInterface.sendSciCommand("ChangeDemoRsp",Param)
+
+
+def GetDemoMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+    This command will always return 0.
+    API Status: internal
+    Returns:
+        DemoModeOn:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDemoMode")
+    return int(rsp[0])
+
+def ResetNetworkPort(Param:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    (Re)sets the IP address and listen port of the socket to which the NetworkDriver
+    tries to connect to (IP address and listen port of Kernel socket). Dummy
+    implementation for Kernel to support backwards.
+    API Status: internal
+    Args:
+        Param:str = ""
+    Command Timeout: 10000
+    Example:ResetNetworkPort 192.168.3.1 10000
+    """
+    MessageServerInterface.sendSciCommand("ResetNetworkPort",Param)
+
+
+def GetNDriverClientStatus(ClientNum:int="", Param:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets status information about the connection NetworkDriver to Kernel. Socket
+    Error is the Windows socket error, Description the Windows socket error
+    description. If Socket Error is 0, the description 'Registered' informs that the
+    Kernel is ready to receive Remote Commands.
+    API Status: internal
+    Args:
+        ClientNum:int = 1
+        Param:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 5000
+    Example:GetNDriverClientStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNDriverClientStatus",ClientNum,Param)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OverrideCommandTimeout(CmdID:int="", TimeoutMilliSec:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows specifying a separate command timeout for a single instance
+    of a command. This is especially useful if the application that receives a
+    command knows how long a command will take.  This command had been added for
+    SoakTime-handling of StepNextDie. A safe guess for the timeout of StepNextDie is
+    5s.
+    API Status: internal
+    Args:
+        CmdID:int = 0
+        TimeoutMilliSec:int = 1000
+    Command Timeout: 5000
+    Example:OverrideCommandTimeout 3234 20000
+    """
+    MessageServerInterface.sendSciCommand("OverrideCommandTimeout",CmdID,TimeoutMilliSec)
+
+
+def ShutdownVelox(IgnorePID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shutdown all Velox applications in an ordered fashion. When this command returns
+    success, all non-mandatory apps are closed and the mandatory ones will follow
+    shortly
+    API Status: internal
+    Args:
+        IgnorePID:int = 0
+    Command Timeout: 120000
+    Example:ShutdownVelox
+    """
+    MessageServerInterface.sendSciCommand("ShutdownVelox",IgnorePID)
+
+
+def InitializationDone(CommandGroup:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Registration of an application can be delayed. To trigger this behavior,
+    RegisterProberApp has to be called with flag 3 set (0x04). From
+    RegisterProberApp to the time this command is sent, the application can send
+    commands but can't receive commands. This is necessary because some application
+    have to communicate with others during initialization and can not handle
+    commands properly during this time.  The command group is necessary because of
+    architectural reasons (By design, the command receiver does not now the sender
+    of a command).
+    API Status: internal
+    Args:
+        CommandGroup:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("InitializationDone",CommandGroup)
+
+
+def StepFirstZProfilePoint(XPos:Decimal="", YPos:Decimal="", NumberOfPoints:int="", NumberOfEPoints:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command goes to the first Z Profile Point, adjusts Z (in the automatic mode
+    only) and pauses after it (even in the automatic mode)
+    API Status: internal
+    Args:
+        XPos:Decimal = 0
+        YPos:Decimal = 0
+        NumberOfPoints:int = 0
+        NumberOfEPoints:int = 0
+    Command Timeout: 60000
+    Example:StepFirstZProfilePoint 10000 20000 5 5
+    """
+    MessageServerInterface.sendSciCommand("StepFirstZProfilePoint",XPos,YPos,NumberOfPoints,NumberOfEPoints)
+
+
+def StepNextZProfilePoint(Point:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command calculates a delta value for the current point and then moves to
+    the specified point (if it's presented) or to the next one. Note, that in case
+    of the automatic Z detecting a return ZDelta parameter is a value for the
+    current point, but in case of the semiautomatic mode the command returns ZDelta
+    as a value for a previous tested point. If the profiling is finished this
+    command will return #807 error (End of the profile). Point indices are started
+    from 1 (1 is first, 2 is second, and so on).
+    API Status: internal
+    Args:
+        Point:int = 0
+    Returns:
+        XPos:Decimal
+        YPos:Decimal
+        Delta:Decimal
+        CurPoint:int
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 60000
+    Example:StepNextZProfilePoint 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextZProfilePoint",Point)
+    global StepNextZProfilePoint_Response
+    if not "StepNextZProfilePoint_Response" in globals(): StepNextZProfilePoint_Response = namedtuple("StepNextZProfilePoint_Response", "XPos,YPos,Delta,CurPoint,NumberOfPoints,NumberOfEPoints")
+    return StepNextZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def SetZProfileOptions(ProfileMode:str="", SepSpeed:Decimal="", ProfileSensor:str="", Stage:str="", SearchSpeed:Decimal="", Gap:Decimal="", Units:str="", ClearElectronics:int="", ClearRefZ:int="", Inaccuracy:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets some Z Profile Program Options remotely.
+    API Status: internal
+    Args:
+        ProfileMode:str = "S"
+        SepSpeed:Decimal = 25
+        ProfileSensor:str = "E"
+        Stage:str = "C"
+        SearchSpeed:Decimal = 50
+        Gap:Decimal = 10
+        Units:str = "Y"
+        ClearElectronics:int = 1
+        ClearRefZ:int = 1
+        Inaccuracy:Decimal = 0
+    Command Timeout: 10000
+    Example:SetZProfileOptions S 25 E C 50 10 Y 1 1 0
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileOptions",ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy)
+
+
+def GetZProfileOptions():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return predefined settings of the Z Profile Program.
+    API Status: internal
+    Returns:
+        ProfileMode:str
+        SepSpeed:Decimal
+        ProfileSensor:str
+        Stage:str
+        SearchSpeed:Decimal
+        Gap:Decimal
+        Units:str
+        ClearElectronics:int
+        ClearRefZ:int
+        Inaccuracy:Decimal
+    Command Timeout: 10000
+    Example:GetZProfileOptions
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileOptions")
+    global GetZProfileOptions_Response
+    if not "GetZProfileOptions_Response" in globals(): GetZProfileOptions_Response = namedtuple("GetZProfileOptions_Response", "ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy")
+    return GetZProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str(rsp[6]),int(rsp[7]),int(rsp[8]),Decimal(rsp[9]))
+
+def OpenZProfileFile(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command opens the file inside of the Z Profiling.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 240000
+    Example:OpenZProfileFile Profile1
+    """
+    rsp = MessageServerInterface.sendSciCommand("OpenZProfileFile",FileName)
+    global OpenZProfileFile_Response
+    if not "OpenZProfileFile_Response" in globals(): OpenZProfileFile_Response = namedtuple("OpenZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+    return OpenZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def SaveZProfileFile(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves the current profile in the specified file.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:SaveZProfileFile Profile1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SaveZProfileFile",FileName)
+    global SaveZProfileFile_Response
+    if not "SaveZProfileFile_Response" in globals(): SaveZProfileFile_Response = namedtuple("SaveZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+    return SaveZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadZProfile(NewOrigin:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read a profile from the ProberBench Electronics II to the application. Return a
+    number of available points.
+    API Status: internal
+    Args:
+        NewOrigin:str = "Z"
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:ReadZProfile H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadZProfile",NewOrigin)
+    return int(rsp[0])
+
+def SetZProfile():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Uploads the current profile to the ProberBench Electronics II. Returns a number
+    of written points.
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:SetZProfile
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetZProfile")
+    return int(rsp[0])
+
+def CloseZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the Z-Profiling application.
+    API Status: internal
+    Command Timeout: 5000
+    Example:CloseZProfiling
+    """
+    MessageServerInterface.sendSciCommand("CloseZProfiling")
+
+
+def SetZProfileStartPoint(X:Decimal="", Y:Decimal="", PosRef:str="", Units:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets new start point for the profile. All points of the profile will be shifted
+    accordingly.
+    API Status: internal
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        PosRef:str = "Z"
+        Units:str = "Y"
+    Command Timeout: 10000
+    Example:SetZProfileStartPoint 0 0 H Y
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileStartPoint",X,Y,PosRef,Units)
+
+
+def GetZProfilingStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a status of the profiling process. If this status is true it means the
+    process is started.
+    API Status: internal
+    Returns:
+        Started:int
+    Command Timeout: 10000
+    Example:GetZProfilingStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfilingStatus")
+    return int(rsp[0])
+
+def StopZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the profiling process.
+    API Status: internal
+    Command Timeout: 10000
+    Example:StopZProfiling
+    """
+    MessageServerInterface.sendSciCommand("StopZProfiling")
+
+
+def SetZProfileOrigin(Pos:str="", X:Decimal="", Y:Decimal="", Z:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets an origin for the profile. If the origin position is H the command ignores
+    X and Y parameters. If Z is None the command clears Z value of the origin.
+    Otherwise it tries to extract a double value from the string and set it.
+    API Status: internal
+    Args:
+        Pos:str = "H"
+        X:Decimal = 0
+        Y:Decimal = 0
+        Z:str = "None"
+    Command Timeout: 10000
+    Example:SetZProfileOrigin H 0 0 None
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileOrigin",Pos,X,Y,Z)
+
+
+def GetZProfileOrigin():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current parameters of the profile origin. If the origin Z has no value
+    the return string for it will be None, otherwise it consists a double value of
+    the profile Z.
+    API Status: internal
+    Returns:
+        Pos:str
+        X:Decimal
+        Y:Decimal
+        Z:str
+    Command Timeout: 10000
+    Example:GetZProfileOrigin
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileOrigin")
+    global GetZProfileOrigin_Response
+    if not "GetZProfileOrigin_Response" in globals(): GetZProfileOrigin_Response = namedtuple("GetZProfileOrigin_Response", "Pos,X,Y,Z")
+    return GetZProfileOrigin_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def StartZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command works in the automatic mode only. It starts the profiling process,
+    profiles the entire wafer and then returns a number of tested points. This
+    command does upload the current profile to the ProberBench Electronics II. To do
+    it please use SetZProfile command
+    API Status: internal
+    Command Timeout: 10000
+    Example:StartZProfiling
+    """
+    MessageServerInterface.sendSciCommand("StartZProfiling")
+
+
+def ZProfileWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command works in the automatic mode only. It starts the profiling process,
+    profiles the entire wafer and then returns a number of tested points. This
+    command does upload the current profile to the ProberBench Electronics II. To do
+    it please use SetZProfile command
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 36000000
+    Example:ZProfileWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("ZProfileWafer")
+    global ZProfileWafer_Response
+    if not "ZProfileWafer_Response" in globals(): ZProfileWafer_Response = namedtuple("ZProfileWafer_Response", "NumberOfPoints,NumberOfEPoints")
+    return ZProfileWafer_Response(int(rsp[0]),int(rsp[1]))
+
+def GetZProfileStartPoint(PosRef:str="", Units:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current start point of the profile by using given units and a
+    reference position.
+    API Status: internal
+    Args:
+        PosRef:str = "Z"
+        Units:str = "Y"
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 10000
+    Example:GetZProfileStartPoint H Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileStartPoint",PosRef,Units)
+    global GetZProfileStartPoint_Response
+    if not "GetZProfileStartPoint_Response" in globals(): GetZProfileStartPoint_Response = namedtuple("GetZProfileStartPoint_Response", "X,Y")
+    return GetZProfileStartPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AddZProfilePoint(X:Decimal="", Y:Decimal="", After:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Adds new point to the profile at the end (default) or after the given point.
+    Returns an index of new point and a number of all points in the profile. Point
+    indices are started from 1.
+    API Status: internal
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        After:int = 0
+    Returns:
+        Index:int
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:AddZProfilePoint 50000 50000
+    """
+    rsp = MessageServerInterface.sendSciCommand("AddZProfilePoint",X,Y,After)
+    global AddZProfilePoint_Response
+    if not "AddZProfilePoint_Response" in globals(): AddZProfilePoint_Response = namedtuple("AddZProfilePoint_Response", "Index,NumberOfPoints,NumberOfEPoints")
+    return AddZProfilePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def DeleteZProfilePoint(Index:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Deletes the point from the profile. Returns a number of all and enabled points
+    in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:DeleteZProfilePoint 11
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteZProfilePoint",Index)
+    global DeleteZProfilePoint_Response
+    if not "DeleteZProfilePoint_Response" in globals(): DeleteZProfilePoint_Response = namedtuple("DeleteZProfilePoint_Response", "NumberOfPoints,NumberOfEPoints")
+    return DeleteZProfilePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def SetZProfilePointStatus(Index:int="", Status:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables the point in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+        Status:str = "0"
+    Command Timeout: 10000
+    Example:SetZProfilePointStatus 11 E
+    """
+    MessageServerInterface.sendSciCommand("SetZProfilePointStatus",Index,Status)
+
+
+def GetZProfilePointStatus(Index:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a status of the point in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    Example:GetZProfilePointStatus 11
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfilePointStatus",Index)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def PreciseZProfile():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    All points are covered by triangles, each vertex of the triangle is a point of
+    the profile. The centers of the triangles are new points of the profile. If all
+    three vertexes of the triangle are tested points the new point will be marked as
+    tested also and has Z value equal to average Z of all three vertexes. Otherwise
+    the new point will be marked as untested. The command returns a number of points
+    in the profile after the update.
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:PreciseZProfile
+    """
+    rsp = MessageServerInterface.sendSciCommand("PreciseZProfile")
+    return int(rsp[0])
+
+def CloseTableView():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the TableView application.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CloseTableView")
+
+
+def StepChuckSite(Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the wafer chuck stage to the requested Site no. of the chuck table view.
+    If no Site no is specified the chuck will step automatically to the next logical
+    site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepChuckSite",Site)
+    return int(rsp[0])
+
+def StepChuckSubsite(Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the wafer chuck stage to the requested Subsite no. of the chuck subsite
+    table view. If no Subsite no. is specified the chuck will step automatically to
+    the next logical site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepChuckSubsite",Site)
+    return int(rsp[0])
+
+def StepScopeSite(Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the microscope stage to the requested Site no. of the scope table view. If
+    no Site no is specified the scope will step automatically to the next logical
+    site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepScopeSite",Site)
+    return int(rsp[0])
+
+def StepProbeSite(Probe:int="", Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the specified probe to the requested Site no. of the Probe no table view.
+    If no Site no. is specified the Probe no. will step automatically to the next
+    logical site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Probe:int = -1
+        Site:int = -1
+    Returns:
+        ProbeRet:int
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepProbeSite",Probe,Site)
+    global StepProbeSite_Response
+    if not "StepProbeSite_Response" in globals(): StepProbeSite_Response = namedtuple("StepProbeSite_Response", "ProbeRet,SiteRet")
+    return StepProbeSite_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadChuckSitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual chuck site position. The first site in the table is site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckSitePosition")
+    global ReadChuckSitePosition_Response
+    if not "ReadChuckSitePosition_Response" in globals(): ReadChuckSitePosition_Response = namedtuple("ReadChuckSitePosition_Response", "Site,X,Y")
+    return ReadChuckSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeSitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the site position of the specified probe. The first site in the table is
+    site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSitePosition")
+    global ReadScopeSitePosition_Response
+    if not "ReadScopeSitePosition_Response" in globals(): ReadScopeSitePosition_Response = namedtuple("ReadScopeSitePosition_Response", "Site,X,Y")
+    return ReadScopeSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadProbeSitePosition(Probe:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the site position of the specified probe. The first site in the table is
+    site 1.
+    API Status: internal
+    Args:
+        Probe:int = -1
+    Returns:
+        ProbeRet:int
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeSitePosition",Probe)
+    global ReadProbeSitePosition_Response
+    if not "ReadProbeSitePosition_Response" in globals(): ReadProbeSitePosition_Response = namedtuple("ReadProbeSitePosition_Response", "ProbeRet,Site,X,Y")
+    return ReadProbeSitePosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadChuckSubsitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the chuck subsite position. The first site in the table is site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckSubsitePosition")
+    global ReadChuckSubsitePosition_Response
+    if not "ReadChuckSubsitePosition_Response" in globals(): ReadChuckSubsitePosition_Response = namedtuple("ReadChuckSubsitePosition_Response", "Site,X,Y")
+    return ReadChuckSubsitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def StepFirstDie(ClearBins:int="", RecalcRoute:int=""):
+    """
+    Steps the chuck to the first die of the wafer map. Returns the row and column
+    number of the actual die location after the move is completed. If ClearBins is
+    1, all binning data will be cleared from dies. If yes the route will be
+    recalculated. All dies marked to skip during the last test (marked to skip with
+    SetDieStatus) will be eliminated from the route.
+    API Status: published
+    Args:
+        ClearBins:int = 1
+        RecalcRoute:int = 1
+    Returns:
+        DieX:int
+        DieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFirstDie",ClearBins,RecalcRoute)
+    global StepFirstDie_Response
+    if not "StepFirstDie_Response" in globals(): StepFirstDie_Response = namedtuple("StepFirstDie_Response", "DieX,DieY,CurSite,LastSiteIndex")
+    return StepFirstDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def StepNextDie(CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Steps the chuck to the specified x,y die location of the wafer map. If no
+    command data is passed, the chuck automatically steps to the next logical wafer
+    map die location. Returns the row and column number of the actual die location
+    after the move is completed. In addition, the SubDie location, and total number
+    of SubDies is also returned.  If Site (i.e. SubDie) is -1, the chuck will move
+    to SubDie 0, on the next die; in this case, the first 2 parameters are ignored.
+    If sent without parameters, it will literally 'step to the next die'. When using
+    this command from shared code, use SendWithoutParameter().
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextDie",CDieX,CDieY,Site)
+    global StepNextDie_Response
+    if not "StepNextDie_Response" in globals(): StepNextDie_Response = namedtuple("StepNextDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return StepNextDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinMapDie(Bin:int="", CDieX:int="", CDieY:int=""):
+    """
+    Assigns the bin information to the wafer map at the current die, unless a row
+    and column is specified. Inks the device if the real time inking option (of the
+    wafer map) is enabled.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+    Command Timeout: 30000
+    Example:BinMapDie 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinMapDie",Bin,CDieX,CDieY)
+    global BinMapDie_Response
+    if not "BinMapDie_Response" in globals(): BinMapDie_Response = namedtuple("BinMapDie_Response", "RDieX,RDieY")
+    return BinMapDie_Response(int(rsp[0]),int(rsp[1]))
+
+def AssignMapBins(Bins:str=""):
+    """
+    Assigns the pass or fail information to the actual bin value. Redundant to
+    SetBinCode.
+    API Status: published
+    Args:
+        Bins:str = ""
+    Command Timeout: 10000
+    Example:AssignMapBins PFFFFFF
+    """
+    MessageServerInterface.sendSciCommand("AssignMapBins",Bins)
+
+
+def StepFailedBack():
+    """
+    Steps the chuck back the number of consecutive failed dies (goes back to the
+    last known good die) and returns the number of consecutive failed dies.
+    API Status: published
+    Returns:
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedBack")
+    return int(rsp[0])
+
+def StepFailedForward():
+    """
+    Steps the chuck forward the number of consecutive failed dies (goes to next
+    untested die).
+    API Status: published
+    Returns:
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedForward")
+    return int(rsp[0])
+
+def ReadMapPosition(Pos:int="", FromPos:str=""):
+    """
+    Returns the actual Wafer Map chuck position. The SubDie collection is 1-based,
+    the first value is 1, not 0.     M_pnCurSite returns the currently selected
+    Subdie (1-based) or 0 if no Subdie is currently selected. This command (i.e.
+    ReadMapPosition) has been included for legacy support.       ReadMapPosition2 is
+    the preferred method for reading Wafer Map chuck position.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        DieX:int
+        DieY:int
+        XFromHome:Decimal
+        YFromHome:Decimal
+        CurSite:int
+        LastSiteIndex:int
+        CurDie:int
+        DiesCount:int
+        CurCluster:int
+        ClustersCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapPosition",Pos,FromPos)
+    global ReadMapPosition_Response
+    if not "ReadMapPosition_Response" in globals(): ReadMapPosition_Response = namedtuple("ReadMapPosition_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+    return ReadMapPosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadMapYield():
+    """
+    Returns the actual wafer map yield data information.
+    API Status: published
+    Returns:
+        TotalDies:int
+        TestedDies:int
+        Passed:int
+        Failed:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapYield")
+    global ReadMapYield_Response
+    if not "ReadMapYield_Response" in globals(): ReadMapYield_Response = namedtuple("ReadMapYield_Response", "TotalDies,TestedDies,Passed,Failed")
+    return ReadMapYield_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinStepDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Bins the current die and steps the chuck to the next selected die location of
+    the wafer map (default) or steps to the specified Column and Row position, if
+    these values are passed.  In contrast to StepNextDie, the BinStepDie command
+    will only step from die to die while staying on the current subdie. It will not
+    step through the subdies so it cannot be used for subdie stepping.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    Example:BinStepDie 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinStepDie",Bin,CDieX,CDieY,Site)
+    global BinStepDie_Response
+    if not "BinStepDie_Response" in globals(): BinStepDie_Response = namedtuple("BinStepDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return BinStepDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetMapHome(DieX:int="", DieY:int=""):
+    """
+    If the command has no parameters it sets the current position as home position
+    both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+    home position using the given die coordinates.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapHome",DieX,DieY)
+
+
+def SaveMapFile(FileName:str="", FileType:str=""):
+    """
+    Saves current map file with specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+        FileType:str = "m"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SaveMapFile",FileName,FileType)
+
+
+def SetWaferMapMode(Mode:str=""):
+    """
+    Enables or disables an external mode for the application. In the external mode,
+    all controls are disabled. The application handles all its remote commands in
+    both modes. Special interactive modes can also be turned on.
+    API Status: published
+    Args:
+        Mode:str = ""
+    Returns:
+        ModeType:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetWaferMapMode",Mode)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetWaferMapMode(ModeType:str=""):
+    """
+    Returns whether the application is in external mode or not.
+    API Status: published
+    Args:
+        ModeType:str = ""
+    Returns:
+        Mode:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapMode",ModeType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferNum(Number:str=""):
+    """
+    Specifies the wafer number.
+    API Status: published
+    Args:
+        Number:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferNum",Number)
+
+
+def GetWaferNum():
+    """
+    Returns the wafer number for the current wafer.
+    API Status: published
+    Returns:
+        Number:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferNum")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferID(ID:str=""):
+    """
+    Specifies the ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferID",ID)
+
+
+def GetWaferID():
+    """
+    Returns the wafer ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetProductID(ID:str=""):
+    """
+    Specifies the product ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetProductID",ID)
+
+
+def GetProductID():
+    """
+    Displays the product ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProductID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DoInkerRun():
+    """
+    Instructs the WaferMap to perform an ink run on the current wafer. Returns the
+    number of dies which were inked during the inker run.
+    API Status: published
+    Returns:
+        InkedDies:int
+    Command Timeout: 30000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DoInkerRun")
+    return int(rsp[0])
+
+def CloseWaferMap():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the Wafer Map application.
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("CloseWaferMap")
+
+
+def GetNumSelectedDies():
+    """
+    Gets the number of dies in the map which are selected for probing.
+    API Status: published
+    Returns:
+        SelectedDies:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNumSelectedDies")
+    return int(rsp[0])
+
+def GetSelectedDieCoords(Die:int=""):
+    """
+    Given the index of a selected die in the range [1..NumSelectedDies], returns the
+    column and row indices for the selected die.
+    API Status: published
+    Args:
+        Die:int = 0
+    Returns:
+        DieX:int
+        DieY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSelectedDieCoords",Die)
+    global GetSelectedDieCoords_Response
+    if not "GetSelectedDieCoords_Response" in globals(): GetSelectedDieCoords_Response = namedtuple("GetSelectedDieCoords_Response", "DieX,DieY")
+    return GetSelectedDieCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def StepNextDieOffset(XOffset:Decimal="", YOffset:Decimal="", CDieX:int="", CDieY:int=""):
+    """
+    Moves to a user-specified offset within a die. The optional col row params can
+    be used to specify the die. If they are omitted, WaferMap moves to the specified
+    offset within the next selected die.
+    API Status: published
+    Args:
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextDieOffset",XOffset,YOffset,CDieX,CDieY)
+    global StepNextDieOffset_Response
+    if not "StepNextDieOffset_Response" in globals(): StepNextDieOffset_Response = namedtuple("StepNextDieOffset_Response", "RDieX,RDieY")
+    return StepNextDieOffset_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadMapPosition2(Pos:int="", FromPos:str=""):
+    """
+    Returns the actual Wafer Map chuck position. The SubDie collection is 0-based,
+    the first value is 0, not 1. M_pnCurSite returns the currently selected Subdie
+    (0-based) or -1 if no Subdie is currently selected.  This command is the
+    preferred method for reading Wafer Map chuck position.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        DieX:int
+        DieY:int
+        XFromHome:Decimal
+        YFromHome:Decimal
+        CurSite:int
+        LastSiteIndex:int
+        CurDie:int
+        DiesCount:int
+        CurCluster:int
+        ClustersCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapPosition2",Pos,FromPos)
+    global ReadMapPosition2_Response
+    if not "ReadMapPosition2_Response" in globals(): ReadMapPosition2_Response = namedtuple("ReadMapPosition2_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+    return ReadMapPosition2_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def DeleteSubDie2(Site:int=""):
+    """
+    Deletes selected subdie. The SubDie collection is 0-based, the first value is 0,
+    not 1.       This command is the preferred method for deleting a selected
+    subdie.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteSubDie2",Site)
+    return int(rsp[0])
+
+def DeleteAllSubDie():
+    """
+    Deletes all subdies for all dies.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("DeleteAllSubDie")
+
+
+def GetDieLabel(DieX:int="", DieY:int=""):
+    """
+    Returns a label from the wafer map at the current die, unless a row and column
+    are specified.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieLabel",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabel(Label:str="", DieX:int="", DieY:int=""):
+    """
+    Assigns a label to the wafer map at the current die, unless a row and column are
+    specified.
+    API Status: published
+    Args:
+        Label:str = ""
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieLabel",Label,DieX,DieY)
+
+
+def StepNextSubDie(Site:int=""):
+    """
+    Steps the chuck to the specified SubDie number relative to the current die
+    origin of the wafer map. Returns the SubDie number of the actual die location
+    after the move is completed and the total number of subdies.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextSubDie",Site)
+    global StepNextSubDie_Response
+    if not "StepNextSubDie_Response" in globals(): StepNextSubDie_Response = namedtuple("StepNextSubDie_Response", "CurSite,LastSiteIndex")
+    return StepNextSubDie_Response(int(rsp[0]),int(rsp[1]))
+
+def OpenWaferMap(FileName:str=""):
+    """
+    Opens a Wafer Map file.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("OpenWaferMap",FileName)
+
+
+def SetDieResult(Result:str="", DieX:int="", DieY:int=""):
+    """
+    Assigns a measurement result to the wafer map at the current die, unless a row
+    and column are specified.
+    API Status: published
+    Args:
+        Result:str = ""
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieResult",Result,DieX,DieY)
+
+
+def GetDieResult(DieX:int="", DieY:int=""):
+    """
+    Returns a measurement result from the wafer map at the current die, unless a row
+    and column are specified.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieResult",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResult(Result:str="", DieX:int="", DieY:int="", Site:int=""):
+    """
+    Assigns a measurement result to the wafer die map at the current die and the
+    current subdie, unless a subdie, row, and column are specified. The SubDie
+    collection is 0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Result:str = ""
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieMapResult",Result,DieX,DieY,Site)
+
+
+def GetDieMapResult(DieX:int="", DieY:int="", Site:int=""):
+    """
+    Returns a measurement result from the wafer map at the current die and current
+    subdie, unless a row, column, and subdie are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieMapResult",DieX,DieY,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BinSubDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Assigns the bin information for the current subdie in the current die, unless a
+    subdie, row, and column are specified. The SubDie collection is 0-based, the
+    first value is 0, not 1.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinSubDie",Bin,CDieX,CDieY,Site)
+    global BinSubDie_Response
+    if not "BinSubDie_Response" in globals(): BinSubDie_Response = namedtuple("BinSubDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return BinSubDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetSubDieData(Site:int="", X:Decimal="", Y:Decimal="", Label:str=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        Site:int = 0
+        X:Decimal = 0
+        Y:Decimal = 0
+        Label:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieData",Site,X,Y,Label)
+
+
+def GetSubDieData(Site:int=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        CurSite:int
+        X:Decimal
+        Y:Decimal
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieData",Site)
+    global GetSubDieData_Response
+    if not "GetSubDieData_Response" in globals(): GetSubDieData_Response = namedtuple("GetSubDieData_Response", "CurSite,X,Y,Label")
+    return GetSubDieData_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def GetMapHome():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the home die location of the WaferMap.
+    API Status: internal
+    Returns:
+        DieX:int
+        DieY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapHome")
+    global GetMapHome_Response
+    if not "GetMapHome_Response" in globals(): GetMapHome_Response = namedtuple("GetMapHome_Response", "DieX,DieY")
+    return GetMapHome_Response(int(rsp[0]),int(rsp[1]))
+
+def GetMapDims():
+    """
+    Returns the parameters for the current wafer.
+    API Status: published
+    Returns:
+        MapType:str
+        XIndex:Decimal
+        YIndex:Decimal
+        Columns:int
+        Rows:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapDims")
+    global GetMapDims_Response
+    if not "GetMapDims_Response" in globals(): GetMapDims_Response = namedtuple("GetMapDims_Response", "MapType,XIndex,YIndex,Columns,Rows")
+    return GetMapDims_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetWaferMapParams(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+    """
+    Creates the circle wafer with specified parameters. If parameter is omitted,
+    then zero is used. For this version of the command, units for XOffset and
+    YOffset are percentages.
+    API Status: published
+    Args:
+        Diameter:Decimal = 200
+        DieWidth:Decimal = 10000
+        DieHeight:Decimal = 10000
+        FlatLength:Decimal = 20
+        FlatAngle:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        EdgeArea:Decimal = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferMapParams",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def SetRectMapParams(DieWidth:Decimal="", DieHeight:Decimal="", Columns:int="", Rows:int=""):
+    """
+    Creates the rectangle wafer with specified parameters.
+    API Status: published
+    Args:
+        DieWidth:Decimal = 0
+        DieHeight:Decimal = 0
+        Columns:int = 0
+        Rows:int = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetRectMapParams",DieWidth,DieHeight,Columns,Rows)
+
+
+def StepToDie(DieNumber:int="", Site:int=""):
+    """
+    Steps the chuck to the die location specified by the die number of the wafer
+    map. If no command data is passed, the chuck automatically steps to the next
+    logical wafer map die location. Returns the row and column number of the actual
+    die location after the move is completed. In addition, the SubDie location, and
+    total number of SubDies is also returned.
+    API Status: published
+    Args:
+        DieNumber:int = -1
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepToDie",DieNumber,Site)
+    global StepToDie_Response
+    if not "StepToDie_Response" in globals(): StepToDie_Response = namedtuple("StepToDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return StepToDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetMapOrientation(UseOrientationCornerForShift:int=""):
+    """
+    Returns parameters of the map coordinate system.
+    API Status: published
+    Args:
+        UseOrientationCornerForShift:int = 0
+    Returns:
+        Orientation:int
+        OriginShiftX:int
+        OriginShiftY:int
+        UseAlphas:int
+        UseIOs:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapOrientation",UseOrientationCornerForShift)
+    global GetMapOrientation_Response
+    if not "GetMapOrientation_Response" in globals(): GetMapOrientation_Response = namedtuple("GetMapOrientation_Response", "Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs")
+    return GetMapOrientation_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetMapOrientation(Orientation:int="", OriginShiftX:int="", OriginShiftY:int="", UseAlphas:int="", UseIOs:int="", UseOrientationCornerForShift:int=""):
+    """
+    Sets up new map origin and new coordinate system after that.
+    API Status: published
+    Args:
+        Orientation:int = 0
+        OriginShiftX:int = 0
+        OriginShiftY:int = 0
+        UseAlphas:int = 0
+        UseIOs:int = 1
+        UseOrientationCornerForShift:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapOrientation",Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs,UseOrientationCornerForShift)
+
+
+def SetDieStatus(DieX:int="", DieY:int="", Status:str=""):
+    """
+    Sets the die status.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Status:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieStatus",DieX,DieY,Status)
+
+
+def GetDieStatus(DieX:int="", DieY:int=""):
+    """
+    Gets the die status.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieStatus",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieStatus(Site:int="", Status:str=""):
+    """
+    Sets the SubDie status. The SubDie collection is 0-based, the first value is 0,
+    not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+        Status:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieStatus",Site,Status)
+
+
+def GetSubDieStatus(Site:int=""):
+    """
+    Returns the SubDie status. The SubDie collection is 0-based, the first value is
+    0, not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieStatus",Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetBinCode(Bin:int=""):
+    """
+    Returns the Die size from the current map.
+    API Status: published
+    Args:
+        Bin:int = 0
+    Returns:
+        Chars:str
+        Color:int
+        Status:str
+        Inker1:int
+        Inker2:int
+        Inker3:int
+        Inker4:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBinCode",Bin)
+    global GetBinCode_Response
+    if not "GetBinCode_Response" in globals(): GetBinCode_Response = namedtuple("GetBinCode_Response", "Chars,Color,Status,Inker1,Inker2,Inker3,Inker4")
+    return GetBinCode_Response(str(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetBinCode(Bin:int="", Chars:str="", Color:int="", Status:str="", Inker1:int="", Inker2:int="", Inker3:int="", Inker4:int=""):
+    """
+    Appends the Bin information to a bin code.
+    API Status: published
+    Args:
+        Bin:int = 0
+        Chars:str = ""
+        Color:int = 0
+        Status:str = ""
+        Inker1:int = 0
+        Inker2:int = 0
+        Inker3:int = 0
+        Inker4:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetBinCode",Bin,Chars,Color,Status,Inker1,Inker2,Inker3,Inker4)
+
+
+def GetDieDataAsNum(CDieIndex:int=""):
+    """
+    Returns the Die Information in the Row Column format. If the Die Number is
+    invalid it returns an error. If the Die Number is absent it uses the current die
+    on the wafer.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        RDieIndex:int
+        DieX:int
+        DieY:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieDataAsNum",CDieIndex)
+    global GetDieDataAsNum_Response
+    if not "GetDieDataAsNum_Response" in globals(): GetDieDataAsNum_Response = namedtuple("GetDieDataAsNum_Response", "RDieIndex,DieX,DieY,Bin,Result")
+    return GetDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsNum(DieIndex:int="", Bin:int="", Result:str=""):
+    """
+    Sets the Die Information. If the Die Number is invalid it returns an error.
+    API Status: published
+    Args:
+        DieIndex:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieDataAsNum",DieIndex,Bin,Result)
+
+
+def GetSubDieDataAsNum(CDieIndex:int="", Site:int=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        RDieIndex:int
+        DieX:int
+        DieY:int
+        CurSite:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsNum",CDieIndex,Site)
+    global GetSubDieDataAsNum_Response
+    if not "GetSubDieDataAsNum_Response" in globals(): GetSubDieDataAsNum_Response = namedtuple("GetSubDieDataAsNum_Response", "RDieIndex,DieX,DieY,CurSite,Bin,Result")
+    return GetSubDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsNum(DieIndex:int="", Site:int="", Bin:int="", Result:str=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        DieIndex:int = 0
+        Site:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieDataAsNum",DieIndex,Site,Bin,Result)
+
+
+def GetDieDataAsColRow(CDieX:int="", CDieY:int=""):
+    """
+    Returns the Die Information in the Row Column format. If the Die Number is
+    invalid it returns an error. If the Die Column and Row are absent it uses the
+    current die on the wafer.
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        DieIndex:int
+        RDieX:int
+        RDieY:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieDataAsColRow",CDieX,CDieY)
+    global GetDieDataAsColRow_Response
+    if not "GetDieDataAsColRow_Response" in globals(): GetDieDataAsColRow_Response = namedtuple("GetDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,Bin,Result")
+    return GetDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsColRow(DieX:int="", DieY:int="", Bin:int="", Result:str=""):
+    """
+    Sets the Data in the Row Column format. If the Die is invalid it returns an
+    error.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieDataAsColRow",DieX,DieY,Bin,Result)
+
+
+def GetSubDieDataAsColRow(CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        DieIndex:int
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsColRow",CDieX,CDieY,Site)
+    global GetSubDieDataAsColRow_Response
+    if not "GetSubDieDataAsColRow_Response" in globals(): GetSubDieDataAsColRow_Response = namedtuple("GetSubDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,CurSite,Bin,Result")
+    return GetSubDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsColRow(DieX:int="", DieY:int="", Site:int="", Bin:int="", Result:str=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieDataAsColRow",DieX,DieY,Site,Bin,Result)
+
+
+def SelectAllDiesForProbing(DoSelectAll:int="", DoEdgeDies:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables all dies.
+    API Status: internal
+    Args:
+        DoSelectAll:int = 0
+        DoEdgeDies:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SelectAllDiesForProbing",DoSelectAll,DoEdgeDies)
+
+
+def GetMapName():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current WaferMap Filename.
+    API Status: internal
+    Returns:
+        Name:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapName")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetLotID(ID:str=""):
+    """
+    Specifies the ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetLotID",ID)
+
+
+def GetLotID():
+    """
+    Returns the Lot ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLotID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StepFirstCluster(ClearBins:int="", RecalcRoute:int=""):
+    """
+    Steps the chuck to the first die cluster of the cluster map. If clusters are not
+    defined, the first Die is used. Returns the row and column information of the
+    actual cluster and die location after the move is completed. Switches to remote
+    control if the "Disable Velox" flag is set in the external options window.
+    API Status: published
+    Args:
+        ClearBins:int = 1
+        RecalcRoute:int = 1
+    Returns:
+        ClusterX:int
+        ClusterY:int
+        ClusterIndex:int
+        IncompleteCluster:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFirstCluster",ClearBins,RecalcRoute)
+    global StepFirstCluster_Response
+    if not "StepFirstCluster_Response" in globals(): StepFirstCluster_Response = namedtuple("StepFirstCluster_Response", "ClusterX,ClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+    return StepFirstCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def StepNextCluster(CClusterX:int="", CClusterY:int=""):
+    """
+    Steps the chuck to the specified x,y cluster die location of the cluster map. If
+    no command data is passed, the chuck automatically steps to the next logical
+    cluster map location. If clusters are not defined, the Die information is used.
+    Returns the row and column number of the actual die location after the move is
+    completed.
+    API Status: published
+    Args:
+        CClusterX:int = 0
+        CClusterY:int = 0
+    Returns:
+        RClusterX:int
+        RClusterY:int
+        ClusterIndex:int
+        IncompleteCluster:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextCluster",CClusterX,CClusterY)
+    global StepNextCluster_Response
+    if not "StepNextCluster_Response" in globals(): StepNextCluster_Response = namedtuple("StepNextCluster_Response", "RClusterX,RClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+    return StepNextCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetMapRoute(MoveMode:str="", StartColumn:str="", StartRow:str="", MoveParam:str=""):
+    """
+    Specifies the Move Path for the probe station inside the Wafer Map. Optimization
+    is done for the shortest move way for the station.
+    API Status: published
+    Args:
+        MoveMode:str = "B"
+        StartColumn:str = "L"
+        StartRow:str = "T"
+        MoveParam:str = "H"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapRoute",MoveMode,StartColumn,StartRow,MoveParam)
+
+
+def GetMapRoute():
+    """
+    Returns the specified move path for the probe station inside the Wafer Map.
+    API Status: published
+    Returns:
+        MoveMode:str
+        StartColumn:str
+        StartRow:str
+        MoveParam:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapRoute")
+    global GetMapRoute_Response
+    if not "GetMapRoute_Response" in globals(): GetMapRoute_Response = namedtuple("GetMapRoute_Response", "MoveMode,StartColumn,StartRow,MoveParam")
+    return GetMapRoute_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetClusterParams(UseClusters:int="", ClusterWidth:int="", ClusterHeight:int="", TestIncomplete:int=""):
+    """
+    Specifies the clusters parameters.
+    API Status: published
+    Args:
+        UseClusters:int = 0
+        ClusterWidth:int = 1
+        ClusterHeight:int = 1
+        TestIncomplete:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetClusterParams",UseClusters,ClusterWidth,ClusterHeight,TestIncomplete)
+
+
+def GetClusterParams():
+    """
+    Returns current clusters parameters.
+    API Status: published
+    Returns:
+        UseClusters:int
+        ClusterWidth:int
+        ClusterHeight:int
+        TestIncomplete:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterParams")
+    global GetClusterParams_Response
+    if not "GetClusterParams_Response" in globals(): GetClusterParams_Response = namedtuple("GetClusterParams_Response", "UseClusters,ClusterWidth,ClusterHeight,TestIncomplete")
+    return GetClusterParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def NewWaferMap():
+    """
+    Deletes current wafer map, sub dies and binning information; then creates new
+    wafer map with defaults parameters.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("NewWaferMap")
+
+
+def AddSubDie(X:Decimal="", Y:Decimal="", Label:str=""):
+    """
+    Adds new subdie at the end of the table.
+    API Status: published
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        Label:str = ""
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("AddSubDie",X,Y,Label)
+    return int(rsp[0])
+
+def DeleteSubDie(Site:int=""):
+    """
+    Deletes selected subdie. The SubDie collection is 1-based, the first value is 1,
+    not 0. If 0 is passed in as the subdie index, WaferMap will delete all subdies
+    for all dies.This command (i.e. DeleteSubDie) has been included for legacy
+    support.       DeleteSubDie2 is the preferred method for deleting a selected
+    subdie. DeleteAllSubDie is the preferred method for deleting all subdies for all
+    dies.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteSubDie",Site)
+    return int(rsp[0])
+
+def GetNumSelectedClusters():
+    """
+    Gets the number of clusters in the map which are selected for probing.
+    API Status: published
+    Returns:
+        SelectedClusters:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNumSelectedClusters")
+    return int(rsp[0])
+
+def GetSelectedClusterCoords(ClusterIndex:int=""):
+    """
+    Given the index of a selected cluster in the range [1..NumSelectedClusters],
+    returns the column and row indices for the selected cluster.
+    API Status: published
+    Args:
+        ClusterIndex:int = 0
+    Returns:
+        ClusterX:int
+        ClusterY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSelectedClusterCoords",ClusterIndex)
+    global GetSelectedClusterCoords_Response
+    if not "GetSelectedClusterCoords_Response" in globals(): GetSelectedClusterCoords_Response = namedtuple("GetSelectedClusterCoords_Response", "ClusterX,ClusterY")
+    return GetSelectedClusterCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def GetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int=""):
+    """
+    Gets the die status in the cluster. Die coordinates are internal for the cluster
+    using the wafer map coordinate system. (0,0) die in the cluster is left top
+    corner (whether this die exists or not).
+    API Status: published
+    Args:
+        ClusterX:int = 0
+        ClusterY:int = 0
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterDieStatus",ClusterX,ClusterY,DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int="", Status:str=""):
+    """
+    Sets the die status in the cluster. Die coordinates are internal for the cluster
+    using the wafer map coordinate system. (0,0) die in the cluster is left top
+    corner (whether this die exists or not).
+    API Status: published
+    Args:
+        ClusterX:int = 0
+        ClusterY:int = 0
+        DieX:int = 0
+        DieY:int = 0
+        Status:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetClusterDieStatus",ClusterX,ClusterY,DieX,DieY,Status)
+
+
+def OpenBinCodeTable(FileName:str=""):
+    """
+    Opens a Bin Code Table file (.bct) with the specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("OpenBinCodeTable",FileName)
+
+
+def SaveBinCodeTable(FileName:str=""):
+    """
+    Saves bin code table to a file with the specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SaveBinCodeTable",FileName)
+
+
+def SetBinTableSize(BinsSize:int=""):
+    """
+    Sets size of the bin code table. This is the size of bins used in statistics and
+    binning.
+    API Status: published
+    Args:
+        BinsSize:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetBinTableSize",BinsSize)
+
+
+def GetBinTableSize():
+    """
+    Gets size of the bin code table.
+    API Status: published
+    Returns:
+        BinsSize:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBinTableSize")
+    return int(rsp[0])
+
+def StepFailedClusterBack():
+    """
+    Steps the chuck the consecutive failed clusters back (goes back to the last
+    known good cluster) and returns the number of consecutive failed clusters.
+    API Status: published
+    Returns:
+        FailedClusters:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedClusterBack")
+    return int(rsp[0])
+
+def StepFailedClusterForward():
+    """
+    Steps the chuck the consecutive failed clusters forward and returns the number
+    of consecutive failed clusters (goes to next untested cluster).
+    API Status: published
+    Returns:
+        FailedClusters:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedClusterForward")
+    return int(rsp[0])
+
+def GoToWaferHome():
+    """
+    Moves the chuck to the wafer home position.
+    API Status: published
+    Command Timeout: 6000000
+    """
+    MessageServerInterface.sendSciCommand("GoToWaferHome")
+
+
+def GetWaferInfo():
+    """
+    Returns a number of all units marked to test. Note that TestSites is a number of
+    all sites for all dies.
+    API Status: published
+    Returns:
+        ClustersCount:int
+        DiesCount:int
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferInfo")
+    global GetWaferInfo_Response
+    if not "GetWaferInfo_Response" in globals(): GetWaferInfo_Response = namedtuple("GetWaferInfo_Response", "ClustersCount,DiesCount,SitesCount")
+    return GetWaferInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetClusterInfo(Cluster:int=""):
+    """
+    Returns a number of all dies and sites marked to test in the given cluster.
+    API Status: published
+    Args:
+        Cluster:int = 0
+    Returns:
+        DiesCount:int
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterInfo",Cluster)
+    global GetClusterInfo_Response
+    if not "GetClusterInfo_Response" in globals(): GetClusterInfo_Response = namedtuple("GetClusterInfo_Response", "DiesCount,SitesCount")
+    return GetClusterInfo_Response(int(rsp[0]),int(rsp[1]))
+
+def GetDieInfo(Die:int=""):
+    """
+    Returns a number of sites marked to test in the given die.
+    API Status: published
+    Args:
+        Die:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieInfo",Die)
+    return int(rsp[0])
+
+def ConvertToAlphas(Start:int="", Finish:int=""):
+    """
+    Returns a string of the alpha column coordinates for the given range divided by
+    spaces.
+    API Status: published
+    Args:
+        Start:int = 0
+        Finish:int = 0
+    Returns:
+        Alphas:str
+    Command Timeout: 240000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ConvertToAlphas",Start,Finish)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetActiveLayer(Layer:str=""):
+    """
+    Sets new active layer.
+    API Status: published
+    Args:
+        Layer:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetActiveLayer",Layer)
+
+
+def GetActiveLayer():
+    """
+    Returns current active layer.
+    API Status: published
+    Returns:
+        Layer:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetActiveLayer")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieRefPoint(RefX:Decimal="", RefY:Decimal=""):
+    """
+    Sets a new reference point for the die. This point is NOT used for die stepping,
+    nor for subdie stepping. When using the "Chuck Position from Reference" WaferMap
+    GUI setting, the Die Reference Point can be set to be more representative of the
+    actual reference location within the die. A setting of (0.0, 0.0) is defined as
+    the upper left corner of the die. All subdie coordinates are relative to upper
+    left corner of the die.
+    API Status: published
+    Args:
+        RefX:Decimal = 0
+        RefY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieRefPoint",RefX,RefY)
+
+
+def GetDieRefPoint():
+    """
+    Returns current reference point for the die. For details see SetDieRefPoint
+    command.
+    API Status: published
+    Returns:
+        RefX:Decimal
+        RefY:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieRefPoint")
+    global GetDieRefPoint_Response
+    if not "GetDieRefPoint_Response" in globals(): GetDieRefPoint_Response = namedtuple("GetDieRefPoint_Response", "RefX,RefY")
+    return GetDieRefPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ClearAllBins():
+    """
+    Clears all binning data in the wafer map.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ClearAllBins")
+
+
+def SetWindowState(State:str="", Window:str=""):
+    """
+    Has sense in the application only (not for ActiveX controls). It shows or hides
+    a window. All parameters are case-insensitive.
+    API Status: published
+    Args:
+        State:str = "s"
+        Window:str = "setup"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWindowState",State,Window)
+
+
+def SetCurrentBin(Bin:int="", ButtonStatus:int=""):
+    """
+    Sets the current bin for the application. Second parameter allows to enable or
+    disable "Mark with Bin" mode in the application.
+    API Status: published
+    Args:
+        Bin:int = 0
+        ButtonStatus:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetCurrentBin",Bin,ButtonStatus)
+
+
+def GetCurrentBin():
+    """
+    Returns the current bin in the application.
+    API Status: published
+    Returns:
+        Bin:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCurrentBin")
+    return int(rsp[0])
+
+def ReadClusterPosition(Pos:int="", FromPos:str=""):
+    """
+    Returns the actual wafer map cluster position. If the cluster probing is
+    disabled, the command will assume a cluster of size 1x1.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        ClusterX:int
+        ClusterY:int
+        ClusterIndex:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+        ClusterWidth:int
+        ClusterHeight:int
+        EnabledDies:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadClusterPosition",Pos,FromPos)
+    global ReadClusterPosition_Response
+    if not "ReadClusterPosition_Response" in globals(): ReadClusterPosition_Response = namedtuple("ReadClusterPosition_Response", "ClusterX,ClusterY,ClusterIndex,DieX,DieY,DieIndex,ClusterWidth,ClusterHeight,EnabledDies")
+    return ReadClusterPosition_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str("" if len(rsp) < 9 else ' '.join(rsp[8:])))
+
+def GetWaferMapParams():
+    """
+    Returns the circle wafer parameters. For this version of the command, units for
+    XOffset and YOffset are percentages.
+    API Status: published
+    Returns:
+        Diameter:Decimal
+        DieWidth:Decimal
+        DieHeight:Decimal
+        FlatLength:Decimal
+        FlatAngle:int
+        XOffset:Decimal
+        YOffset:Decimal
+        EdgeArea:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams")
+    global GetWaferMapParams_Response
+    if not "GetWaferMapParams_Response" in globals(): GetWaferMapParams_Response = namedtuple("GetWaferMapParams_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+    return GetWaferMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def GetRectMapParams():
+    """
+    Creates a rectangular wafermap with specified parameters.
+    API Status: published
+    Returns:
+        DieWidth:Decimal
+        DieHeight:Decimal
+        Columns:int
+        Rows:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetRectMapParams")
+    global GetRectMapParams_Response
+    if not "GetRectMapParams_Response" in globals(): GetRectMapParams_Response = namedtuple("GetRectMapParams_Response", "DieWidth,DieHeight,Columns,Rows")
+    return GetRectMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SyncMapHome(X:Decimal="", Y:Decimal=""):
+    """
+    Tries to find an appropriate position in the wafer for the current chuck
+    position. X and Y describe the chuck position of the wafer center relatively to
+    the chuck zero position. If the wafer position is found the command sets it as
+    the wafer map home position and sets the current chuck position as the chuck
+    home position. If there is no corresponding wafer position the command returns
+    error 701. Command is used by AutoAlign for the BuildMap feature.
+    API Status: published
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SyncMapHome",X,Y)
+
+
+def SetWaferProfileOptions(ProfileSensor:str="", SearchSpeed:Decimal="", Gap:Decimal="", SuccessRatio:Decimal="", ProfDistX:Decimal="", ProfDistY:Decimal=""):
+    """
+    Sets some WaferMap profiling options remotely.
+    API Status: published
+    Args:
+        ProfileSensor:str = "e"
+        SearchSpeed:Decimal = 50
+        Gap:Decimal = 10
+        SuccessRatio:Decimal = 75
+        ProfDistX:Decimal = 0
+        ProfDistY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferProfileOptions",ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY)
+
+
+def GetWaferProfileOptions():
+    """
+    Returns predefined settings of the WaferMap profiling options.
+    API Status: published
+    Returns:
+        ProfileSensor:str
+        SearchSpeed:Decimal
+        Gap:Decimal
+        SuccessRatio:Decimal
+        ProfDistX:Decimal
+        ProfDistY:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferProfileOptions")
+    global GetWaferProfileOptions_Response
+    if not "GetWaferProfileOptions_Response" in globals(): GetWaferProfileOptions_Response = namedtuple("GetWaferProfileOptions_Response", "ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY")
+    return GetWaferProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def StartWaferProfiling(DoContinue:int=""):
+    """
+    Starts the profiling process. To determine the current profiling state, use
+    GetWaferProfilingStatus command.
+    API Status: published
+    Args:
+        DoContinue:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("StartWaferProfiling",DoContinue)
+
+
+def GetWaferProfilingStatus():
+    """
+    Returns status of the profiling process. If this status is true, the process is
+    started.
+    API Status: published
+    Returns:
+        Started:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferProfilingStatus")
+    return int(rsp[0])
+
+def StopWaferProfiling():
+    """
+    Stops the profiling process.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("StopWaferProfiling")
+
+
+def DoWaferProfiling():
+    """
+    Profiles the wafer and returns a status of the profiling as an error code.
+    API Status: published
+    Command Timeout: 36000000
+    """
+    MessageServerInterface.sendSciCommand("DoWaferProfiling")
+
+
+def DoWaferProfilingOffAxis():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Profiles the wafer and returns a status of the profiling as an error code.
+    Executes profiling using the off axis camera
+    API Status: internal
+    Command Timeout: 36000000
+    """
+    MessageServerInterface.sendSciCommand("DoWaferProfilingOffAxis")
+
+
+def GetSubDieLabel(DieX:int="", DieY:int="", Site:int=""):
+    """
+    Returns a label from the wafer map at the current die and current subdie, unless
+    a row, column, and subdie are specified. The SubDie collection is 0-based, the
+    first value is 0, not 1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieLabel",DieX,DieY,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabel(Label:str="", DieX:int="", DieY:int="", Site:int=""):
+    """
+    Assigns a label to the wafer map at the current die and the current subdie,
+    unless a subdie, row, and column are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Label:str = ""
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieLabel",Label,DieX,DieY,Site)
+
+
+def GetSubDieLabelAsNum(CDieIndex:int="", Site:int=""):
+    """
+    Returns a label from the wafer map the current die and the current subdie,
+    unless a subdie, and die number are specified. The SubDie collection is 0-based,
+    the first value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieLabelAsNum",CDieIndex,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabelAsNum(Label:str="", CDieIndex:int="", Site:int=""):
+    """
+    Assigns a label to the wafer map at the current die and the current subdie,
+    unless a subdie, and die number are specified. The SubDie collection is 0-based,
+    the first value is 0, not 1.
+    API Status: published
+    Args:
+        Label:str = ""
+        CDieIndex:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieLabelAsNum",Label,CDieIndex,Site)
+
+
+def GetDieLabelAsNum(CDieIndex:int=""):
+    """
+    Returns a label from the wafer map at the current die, unless a die number is
+    specified.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieLabelAsNum",CDieIndex)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabelAsNum(Label:str="", CDieIndex:int=""):
+    """
+    Assigns a label to the wafer map at the current die, unless a die number is
+    specified.
+    API Status: published
+    Args:
+        Label:str = ""
+        CDieIndex:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieLabelAsNum",Label,CDieIndex)
+
+
+def GetHomeDieOffset():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the XY offset from the reference position of the Home Die to wafer
+    center in chuck coordinates.
+    API Status: internal
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHomeDieOffset")
+    global GetHomeDieOffset_Response
+    if not "GetHomeDieOffset_Response" in globals(): GetHomeDieOffset_Response = namedtuple("GetHomeDieOffset_Response", "X,Y")
+    return GetHomeDieOffset_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetWaferMapParams2(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+    """
+    Creates the circle wafer with specified parameters. If parameter is omitted,
+    then zero is used. For this version of the command, units for XOffset and
+    YOffset are microns.
+    API Status: published
+    Args:
+        Diameter:Decimal = 200
+        DieWidth:Decimal = 10000
+        DieHeight:Decimal = 10000
+        FlatLength:Decimal = 20
+        FlatAngle:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        EdgeArea:Decimal = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferMapParams2",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def GetWaferMapParams2():
+    """
+    Returns the circle wafer parameters. For this version of the command, units for
+    XOffset and YOffset are microns.
+    API Status: published
+    Returns:
+        Diameter:Decimal
+        DieWidth:Decimal
+        DieHeight:Decimal
+        FlatLength:Decimal
+        FlatAngle:int
+        XOffset:Decimal
+        YOffset:Decimal
+        EdgeArea:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams2")
+    global GetWaferMapParams2_Response
+    if not "GetWaferMapParams2_Response" in globals(): GetWaferMapParams2_Response = namedtuple("GetWaferMapParams2_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+    return GetWaferMapParams2_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def SetWaferTestAngle(Angle:int=""):
+    """
+    This command sets the Wafer Test Angle. This is different from the notch angle
+    and allows rotating the WaferMap.
+    API Status: published
+    Args:
+        Angle:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferTestAngle",Angle)
+
+
+def GetWaferTestAngle():
+    """
+    This returns the Wafer Test Angle. This is different from the notch angle and
+    allows rotating the WaferMap.
+    API Status: published
+    Returns:
+        Angle:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferTestAngle")
+    return int(rsp[0])
+
+def LoadPreMappedDiesTable(FileName:str="", ClearMap:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Loads the Pre-Mapped Dies Table file with specified name.
+    API Status: internal
+    Args:
+        FileName:str = ""
+        ClearMap:int = 1
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("LoadPreMappedDiesTable",FileName,ClearMap)
+
+
+def GetPreMappedDieInfo(DieX:int="", DieY:int=""):
+    """
+    This command is valid when a PreMapped Dies Table has been loaded. Returns
+    values at the current die, unless a column (M_pnDieX) and row (M_pnDieY) are
+    specified.  Returns actual (as measured during the Pre-Mapping) x, y, z, and
+    theta die positions. Also returns whether or not Z and Theta are being used.
+    This command is only valid when a Pre-Mapped Dies Table has been loaded. If a
+    PreMapped Dies Table has NOT been loaded, ERR_IllegalParameters (715) is
+    returned.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        UseZ:int
+        UseTheta:int
+        ActualX:Decimal
+        ActualY:Decimal
+        ActualZ:Decimal
+        Theta:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPreMappedDieInfo",DieX,DieY)
+    global GetPreMappedDieInfo_Response
+    if not "GetPreMappedDieInfo_Response" in globals(): GetPreMappedDieInfo_Response = namedtuple("GetPreMappedDieInfo_Response", "UseZ,UseTheta,ActualX,ActualY,ActualZ,Theta")
+    return GetPreMappedDieInfo_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def GetDieResultAsNum(CDieIndex:int=""):
+    """
+    Returns a measurement result from the wafer map at the current die, unless a die
+    number is specified.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieResultAsNum",CDieIndex)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieResultAsNum(Result:str="", CDieIndex:int=""):
+    """
+    Assigns a measurement result to the wafer map at the current die, unless a die
+    number is specified.
+    API Status: published
+    Args:
+        Result:str = ""
+        CDieIndex:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieResultAsNum",Result,CDieIndex)
+
+
+def GetDieMapResultAsNum(CDieIndex:int="", Site:int=""):
+    """
+    Returns a measurement result from the wafer map the current die and the current
+    subdie, unless a subdie, and die number are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieMapResultAsNum",CDieIndex,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResultAsNum(Result:str="", CDieIndex:int="", Site:int=""):
+    """
+    Assigns a measurement result to the wafer die map at the current die at the
+    current subdie, unless a subdie, and die number are specified. The SubDie
+    collection is 0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Result:str = ""
+        CDieIndex:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieMapResultAsNum",Result,CDieIndex,Site)
+
+
+def MapEdgeDies(Enable:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables edge dies for test
+    API Status: internal
+    Args:
+        Enable:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("MapEdgeDies",Enable)
+
+
+def GetSpectrumData(DataPath:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows access to read any data item in Spectrum explorer.     GetSpectrumData
+    AlignWafer/ProjectData/Mark1/ChuckPosition/X     GetSpectrumData Chuck
+    Camera/Camera Settings/Shutter
+    API Status: internal
+    Args:
+        DataPath:str = ""
+    Returns:
+        Value:str
+    Command Timeout: 6000
+    Example:GetSpectrumData Chuck Camera/Camera Settings/Shutter
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSpectrumData",DataPath)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumData(PathAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows changing any data item in Spectrum explorer. Works independent of access
+    level. SetSpectrumData AlignWafer/ProjectData/Mark1/ChuckPosition/X=1000
+    SetSpectrumData Chuck Camera/Camera Settings/Shutter=17
+    API Status: internal
+    Args:
+        PathAndValue:str = ""
+    Command Timeout: 6000
+    Example:SetSpectrumData Scope Camera/Camera Settings/Shutter=17
+    """
+    MessageServerInterface.sendSciCommand("SetSpectrumData",PathAndValue)
+
+
+def ReadVMPosition(ToolName:str="", XY:int="", Z:int="", Model:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the current chuck and microscope position and sets them as
+    new controller or chuck and microscope positions.     The command was originally used
+    by ReAlignWizard but may be removed in the future because of direct access to
+    tooldata     within Spectrum.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        XY:int = 1
+        Z:int = 0
+        Model:int = -1
+    Command Timeout: 60000
+    Example:ReadVMPosition AlignWafer 1 0 0
+    """
+    MessageServerInterface.sendSciCommand("ReadVMPosition",ToolName,XY,Z,Model)
+
+
+def MoveToVMPosition(ToolName:str="", XYChuck:int="", ZChuck:int="", XYScope:int="", ZScope:int="", Model:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command moves to trained stages positions of a requested tool. Command is
+    used by ReAlignWizard to move to     the trained positions for AutoAlign and
+    DetectWaferHeight.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        XYChuck:int = 1
+        ZChuck:int = 1
+        XYScope:int = 0
+        ZScope:int = 0
+        Model:int = -1
+    Command Timeout: 120000
+    Example:MoveToVMPosition AlignWafer 1 0 0 0 0
+    """
+    MessageServerInterface.sendSciCommand("MoveToVMPosition",ToolName,XYChuck,ZChuck,XYScope,ZScope,Model)
+
+
+def ShapeTracker(SetHome:int="", AutoEdgeFind:int="", FileName:str=""):
+    """
+    ShapeTracker automatically tracks the shape of a substrate (e.g. a broken wafer)
+    to determine the contour of it. The data will be memorized as xy coordinates of
+    contour points referenced to the home position. These Points are written to a
+    file after tracking the shape.
+    API Status: published
+    Args:
+        SetHome:int = 1
+        AutoEdgeFind:int = 0
+        FileName:str = ""
+    Command Timeout: 600000
+    Example:ShapeTracker 1
+    """
+    MessageServerInterface.sendSciCommand("ShapeTracker",SetHome,AutoEdgeFind,FileName)
+
+
+def DetectWaferHeight(SetStartPosition:int="", Synchronize:int="", ChuckX:Decimal="", ChuckY:Decimal=""):
+    """
+    Synchronizes chuck and top camera in X, Y and Z. Then the wafer surface is
+    focused on the trained chuck position or the manual adjusted reference position.
+    This tool uses the FindFocus tool with its own Range.
+    API Status: published
+    Args:
+        SetStartPosition:int = 0
+        Synchronize:int = 0
+        ChuckX:Decimal = -1
+        ChuckY:Decimal = -1
+    Returns:
+        PositionX:Decimal
+        PositionY:Decimal
+        WaferHeight:Decimal
+        SynchGap:Decimal
+        ZOffset:Decimal
+        Stage:str
+    Command Timeout: 300000
+    Example:DetectWaferHeight 0 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("DetectWaferHeight",SetStartPosition,Synchronize,ChuckX,ChuckY)
+    global DetectWaferHeight_Response
+    if not "DetectWaferHeight_Response" in globals(): DetectWaferHeight_Response = namedtuple("DetectWaferHeight_Response", "PositionX,PositionY,WaferHeight,SynchGap,ZOffset,Stage")
+    return DetectWaferHeight_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def CheckSpectrumPlugin(Plugin:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command checks if a plugin is trained and returns a string of error/warning
+    messages including information about what is not trained, setup for the tool to
+    run.
+    API Status: internal
+    Args:
+        Plugin:str = ""
+    Returns:
+        PluginAvailable:int
+        Message:str
+    Command Timeout: 1000
+    Example:CheckSpectrumPlugin AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("CheckSpectrumPlugin",Plugin)
+    global CheckSpectrumPlugin_Response
+    if not "CheckSpectrumPlugin_Response" in globals(): CheckSpectrumPlugin_Response = namedtuple("CheckSpectrumPlugin_Response", "PluginAvailable,Message")
+    return CheckSpectrumPlugin_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AutoAlign(SetValue:int="", SkipSettingHome:int=""):
+    """
+    Executes the AutoAlign tool to do a theta alignment of the wafer with optional
+    index calculation or thermal expansion measurement. The command will update home
+    if home was trained. It will only move to its trained chuck/scope position
+    before starting the alignment if the option "MoveToTrainedXYPosition" and/or
+    "MoveToTrainedZPosition" is true.
+    API Status: published
+    Args:
+        SetValue:int = 0
+        SkipSettingHome:int = 0
+    Command Timeout: 300000
+    Example:AutoAlign 1
+    """
+    MessageServerInterface.sendSciCommand("AutoAlign",SetValue,SkipSettingHome)
+
+
+def SetCameraQuiet(Active:int=""):
+    """
+    Activates/deactivates the camera quiet mode. (Applies only to ATM300A and
+    SPS300/SUMMIT200 stations.)     The camera quiet mode deactivates the chuck,
+    platen and contact view camera and triggers a digital output     which
+    connects/disconnects these cameras firewire connection to the PC.
+    API Status: published
+    Args:
+        Active:int = 0
+    Command Timeout: 30000
+    Example:SetCameraQuiet 1
+    """
+    MessageServerInterface.sendSciCommand("SetCameraQuiet",Active)
+
+
+def SetRefDieOffset(RefDieCol:int="", RefDieRow:int="", RefDieDistToCentreX:Decimal="", RefDieDistToCentreY:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is based on the SetMapOrientation command. It allows shifting the
+    center of the reference die to the center of the wafer.
+    API Status: internal
+    Args:
+        RefDieCol:int = 0
+        RefDieRow:int = 0
+        RefDieDistToCentreX:Decimal = 0
+        RefDieDistToCentreY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetRefDieOffset",RefDieCol,RefDieRow,RefDieDistToCentreX,RefDieDistToCentreY)
+
+
+def AlignWafer(TrackPosition:int=""):
+    """
+    Performs a two-point alignment and moves chuck to the trained align position. XY
+    correction is made afterwards to calculate the new home position.
+    API Status: published
+    Args:
+        TrackPosition:int = 0
+    Returns:
+        ThetaOffset:Decimal
+    Command Timeout: 120000
+    Example:AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignWafer",TrackPosition)
+    return Decimal(rsp[0])
+
+def AlignChip():
+    """
+    Performs a single or two point alignment and moves the current chip to the
+    trained aligned position in Theta (in degrees) and X, Y (in microns). The
+    current chip is assumed to be in the region of interest when the command is
+    called.
+    API Status: published
+    Returns:
+        ThetaOffset:Decimal
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 180000
+    Example:AlignChip
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignChip")
+    global AlignChip_Response
+    if not "AlignChip_Response" in globals(): AlignChip_Response = namedtuple("AlignChip_Response", "ThetaOffset,XOffset,YOffset")
+    return AlignChip_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def FindFocus(StepCount:int="", Range:Decimal=""):
+    """
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search.
+    API Status: published
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocus 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocus",StepCount,Range)
+    global FindFocus_Response
+    if not "FindFocus_Response" in globals(): FindFocus_Response = namedtuple("FindFocus_Response", "ZPosition,Stage")
+    return FindFocus_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAux(AuxSiteID:int=""):
+    """
+    Performs an automated aux site alignment in XYZ. Tool can correct reference
+    position and contact height for the given aux site.
+    API Status: published
+    Args:
+        AuxSiteID:int = 0
+    Command Timeout: 300000
+    Example:AlignAux 1
+    """
+    MessageServerInterface.sendSciCommand("AlignAux",AuxSiteID)
+
+
+def FindFeature(Model:int="", ReturnDistanceFromModelOrigin:int="", UseSingleImageAcquisition:int=""):
+    """
+    Search user-defined models. Up to 40 different models can be trained. After
+    training, these models can be searched on screen either by direct user
+    interaction or from external applications with a remote command. The remote
+    command returns the X/Y-Positions, angle (degree) and score value (0 - 1.0) for
+    each instance of the controller found in the region of interest.
+    API Status: published
+    Args:
+        Model:int = 1
+        ReturnDistanceFromModelOrigin:int = 0
+        UseSingleImageAcquisition:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 10000
+    Example:FindFeature 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFeature",Model,ReturnDistanceFromModelOrigin,UseSingleImageAcquisition)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CloseSpectrum():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    CloseSpectrum closes the Spectrum application. Used internally by CommonCommands
+    during Project loading. Does save configuration data but does not save project
+    data.
+    API Status: internal
+    Command Timeout: 6000
+    Example:CloseSpectrum
+    """
+    MessageServerInterface.sendSciCommand("CloseSpectrum")
+
+
+def SnapImage(MountPos:str="", FullPath:str="", SnapShotMode:int=""):
+    """
+    Saves the currently displayed image to the specified file. The image is stored
+    in the requested file format (bmp, jpg or png). By default. it will save the raw
+    camera image and an image with the overlays that are currently visible on the
+    camera view. Using a parameter, one can decide to only save either raw image,
+    overlay image or both. By Specifying 'ALL' as the mount position, the captured
+    screenshot will consist of the currently selected camera layout without
+    providing the raw image. If MountPos and FullPath are empty then the current
+    camera view with overlays is copied to the clipboard.
+    API Status: published
+    Args:
+        MountPos:str = "Scope"
+        FullPath:str = "Image.bmp"
+        SnapShotMode:int = 2
+    Command Timeout: 60000
+    Example:SnapImage Scope C:/Temp/Image.bmp
+    """
+    MessageServerInterface.sendSciCommand("SnapImage",MountPos,FullPath,SnapShotMode)
+
+
+def SetCameraView(Name:str="", Zoom:int="", LiveVideo:int="", WindowState:int=""):
+    """
+    Switches the desired video window of Spectrum as foreground and active view. The
+    camera view can be determined over a tool name or the camera mount position. The
+    second parameter defines the displays zoom factor to be used. Third parameter is
+    used to toogle the live video. Last parameter can be used to maximize a window.
+    API Status: published
+    Args:
+        Name:str = ""
+        Zoom:int = 0
+        LiveVideo:int = 2
+        WindowState:int = 1
+    Command Timeout: 6000
+    Example:SetCameraView AlignWafer 0 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetCameraView",Name,Zoom,LiveVideo,WindowState)
+
+
+def SetCameraLight(Name:str="", State:int="", Shutter:Decimal="", Gain:Decimal="", Brightness:int="", Contrast:int="", Sharpness:int="", Illumination:int=""):
+    """
+    Switches the light of the choosen camera on or off. Light values of -1 will
+    cause that the parameter is not affected.
+    API Status: published
+    Args:
+        Name:str = ""
+        State:int = 0
+        Shutter:Decimal = -1
+        Gain:Decimal = -1
+        Brightness:int = -1
+        Contrast:int = -1
+        Sharpness:int = -1
+        Illumination:int = -1
+    Command Timeout: 6000
+    Example:SetCameraLight AlignWafer 1 20 5
+    """
+    MessageServerInterface.sendSciCommand("SetCameraLight",Name,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination)
+
+
+def ShowWizard(ToolName:str="", MountPosition:str="", AskExecute:int=""):
+    """
+    Starts the wizard of a given tool on the display defined in the tool settings.
+    Additionally it can start a wizard for training single models with the syntax
+    e.g. ShowWizard FindFeature/ProjectData/Features/Feature1/Model For the tools
+    MeasureOnScreen, Calibrate and CameraOrigin you can specify a mount position
+    e.g. ShowWizard Calibrate Platen
+    API Status: published
+    Args:
+        ToolName:str = ""
+        MountPosition:str = ""
+        AskExecute:int = 0
+    Returns:
+        Cancelled:int
+    Command Timeout: 10000000
+    Example:ShowWizard AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("ShowWizard",ToolName,MountPosition,AskExecute)
+    return int(rsp[0])
+
+def ProbeToPadAlign(Position:str=""):
+    """
+    Sets a new Home position. The command is used during ReAlign to search the
+    trained home reference controller and to calculate the new xy home position.
+    API Status: published
+    Args:
+        Position:str = "H"
+    Returns:
+        XOffsetWafer:Decimal
+        YOffsetWafer:Decimal
+    Command Timeout: 120000
+    Example:ProbeToPadAlign H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProbeToPadAlign",Position)
+    global ProbeToPadAlign_Response
+    if not "ProbeToPadAlign_Response" in globals(): ProbeToPadAlign_Response = namedtuple("ProbeToPadAlign_Response", "XOffsetWafer,YOffsetWafer")
+    return ProbeToPadAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ReadOcrString():
+    """
+    Reads the wafer ID string from the wafer's surface. Returns the read ID as
+    string. Requires IDTools license.
+    API Status: published
+    Returns:
+        OcrString:str
+    Command Timeout: 60000
+    Example:ReadOcrString
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadOcrString")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadBarCode():
+    """
+    Reads the wafers barcode and decodes it to a string. Requires IDTools license.
+    API Status: published
+    Returns:
+        BarCodeString:str
+    Command Timeout: 60000
+    Example:ReadBarCode
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadBarCode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def Read2DMatrixCode():
+    """
+    Reads the wafers matrix code and decodes it to a string. Requires IDTools
+    license.
+    API Status: published
+    Returns:
+        MatrixCodeString:str
+    Command Timeout: 60000
+    Example:Read2DMatrixCode
+    """
+    rsp = MessageServerInterface.sendSciCommand("Read2DMatrixCode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumRemote(Activate:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the Spectrum remote mode. In this mode all user interface elements are
+    hidden and disabled. This is used when Spectrum is hosted inside VeloxPro.
+    API Status: internal
+    Args:
+        Activate:int = 1
+    Command Timeout: 10000
+    Example:SetSpectrumRemote 1
+    """
+    MessageServerInterface.sendSciCommand("SetSpectrumRemote",Activate)
+
+
+def GetCameraLight(Name:str=""):
+    """
+    Returns light properties of choosen camera.
+    API Status: published
+    Args:
+        Name:str = ""
+    Returns:
+        MountPosition:str
+        State:int
+        Shutter:Decimal
+        Gain:Decimal
+        Brightness:int
+        Contrast:int
+        Sharpness:int
+        Illumination:int
+    Command Timeout: 6000
+    Example:GetCameraLight Scope
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraLight",Name)
+    global GetCameraLight_Response
+    if not "GetCameraLight_Response" in globals(): GetCameraLight_Response = namedtuple("GetCameraLight_Response", "MountPosition,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination")
+    return GetCameraLight_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def GetCameraView(Name:str=""):
+    """
+    Returns the present camera view state of a desired tool or active view.
+    API Status: published
+    Args:
+        Name:str = ""
+    Returns:
+        MountPosition:str
+        Zoom:int
+        LiveVideo:int
+        WindowState:int
+    Command Timeout: 6000
+    Example:GetCameraView AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraView",Name)
+    global GetCameraView_Response
+    if not "GetCameraView_Response" in globals(): GetCameraView_Response = namedtuple("GetCameraView_Response", "MountPosition,Zoom,LiveVideo,WindowState")
+    return GetCameraView_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetPattern(ToolName:str="", ModelName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Transforms the specific controller of a demanded tool into a bitmap. This bitmap will
+    be stored in the same folder as the project file.     The command was originally
+    required by ReAlignWizard and is currently no longer in use.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        ModelName:str = ""
+    Returns:
+        BitmapPath:str
+    Command Timeout: 30000
+    Example:GetPattern AlignWafer Model1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPattern",ToolName,ModelName)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowPosition(MountPosition:str="", DistPositionX:Decimal="", DistPositionY:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the ChuckCenter under a given camera. When no camera mount position is
+    given, Spectrum uses active view. If there is an Offset different from zero,
+    this position will be moved under the camera.
+    API Status: internal
+    Args:
+        MountPosition:str = ""
+        DistPositionX:Decimal = 0
+        DistPositionY:Decimal = 0
+    Command Timeout: 60000
+    Example:ShowPosition Scope
+    """
+    MessageServerInterface.sendSciCommand("ShowPosition",MountPosition,DistPositionX,DistPositionY)
+
+
+def GetCameraHomePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the home die coordinates when the home die is under the alignment camera
+    (for instance, the top camera).     Command was used during TrainReAlign to get
+    the start position for Z-Profiling. Command is no longer used.
+    API Status: internal
+    Returns:
+        XPosition:Decimal
+        YPosition:Decimal
+        ZPosition:Decimal
+    Command Timeout: 6000
+    Example:GetCameraHomePosition
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraHomePosition")
+    global GetCameraHomePosition_Response
+    if not "GetCameraHomePosition_Response" in globals(): GetCameraHomePosition_Response = namedtuple("GetCameraHomePosition_Response", "XPosition,YPosition,ZPosition")
+    return GetCameraHomePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SynchronizeCamera(MountPos:str="", SynchronizeXY:int="", SynchronizeZ:int=""):
+    """
+    Synchronizes the Platen camera with the calibration mark. The mark is mounted on
+    the chuck camera. The chuck must be moved to get the mark in view of the
+    specified camera.
+    API Status: published
+    Args:
+        MountPos:str = "Scope"
+        SynchronizeXY:int = 0
+        SynchronizeZ:int = 0
+    Returns:
+        XPosition:Decimal
+        YPosition:Decimal
+        ZPosition:Decimal
+    Command Timeout: 120000
+    Example:SynchronizeCamera S 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SynchronizeCamera",MountPos,SynchronizeXY,SynchronizeZ)
+    global SynchronizeCamera_Response
+    if not "SynchronizeCamera_Response" in globals(): SynchronizeCamera_Response = namedtuple("SynchronizeCamera_Response", "XPosition,YPosition,ZPosition")
+    return SynchronizeCamera_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ProbeCardOCS(UpdateZ:int="", MeasureBothGroups:int=""):
+    """
+    Determines the chuck XYZ axis position where the needles of the probe card are
+    in focus. The output parameter is the Z axis value in microns from zero of the
+    new focus height.
+    API Status: published
+    Args:
+        UpdateZ:int = 1
+        MeasureBothGroups:int = 1
+    Returns:
+        ZPosition:Decimal
+    Command Timeout: 360000
+    Example:ProbeCardOCS 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProbeCardOCS",UpdateZ,MeasureBothGroups)
+    return Decimal(rsp[0])
+
+def MoveChuckAutoXY(XPosition:Decimal="", YPosition:Decimal="", XSubsiteOffset:Decimal="", YSubsiteOffset:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is sent by WaferMap to trigger AutoXY, AutoZ or VueTrack for each die
+    move. Automation must be activated/trained before command can be used. Response
+    is X, Y relative distance of adjustment from requested position.
+    API Status: internal
+    Args:
+        XPosition:Decimal = 0
+        YPosition:Decimal = 0
+        XSubsiteOffset:Decimal = 0
+        YSubsiteOffset:Decimal = 0
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 6000000
+    Example:MoveChuckAutoXY 5000 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveChuckAutoXY",XPosition,YPosition,XSubsiteOffset,YSubsiteOffset)
+    global MoveChuckAutoXY_Response
+    if not "MoveChuckAutoXY_Response" in globals(): MoveChuckAutoXY_Response = namedtuple("MoveChuckAutoXY_Response", "XOffset,YOffset")
+    return MoveChuckAutoXY_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def VueTrackAlign(FullVueTrackAlign:int=""):
+    """
+    Alignment for the next wafer when using VueTrack.
+    API Status: published
+    Args:
+        FullVueTrackAlign:int = 1
+    Command Timeout: 6000000
+    Example:VueTrackAlign
+    """
+    MessageServerInterface.sendSciCommand("VueTrackAlign",FullVueTrackAlign)
+
+
+def AutoFocusEVue(DistBelow:Decimal="", DistAbove:Decimal="", XOffsetCenter:int="", YOffsetCenter:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is only used internally for software testing and for providing backwards
+    compatibility with SCPI legacy commands. It executes a focus search using the
+    eVue focus drive.
+    API Status: internal
+    Args:
+        DistBelow:Decimal = 0
+        DistAbove:Decimal = 0
+        XOffsetCenter:int = 0
+        YOffsetCenter:int = 0
+    Returns:
+        FocusScore:Decimal
+        ZPosition:Decimal
+    Command Timeout: 30000
+    Example:AutoFocusEVue 200 200 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutoFocusEVue",DistBelow,DistAbove,XOffsetCenter,YOffsetCenter)
+    global AutoFocusEVue_Response
+    if not "AutoFocusEVue_Response" in globals(): AutoFocusEVue_Response = namedtuple("AutoFocusEVue_Response", "FocusScore,ZPosition")
+    return AutoFocusEVue_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AutoAlignOffAxis(SetValue:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes the ReAlign Wafer Alignment tool to do a theta alignment of the wafer
+    with optional index calculation or thermal expansion measurement. AutoAlign is
+    performed using the Platen camera. Only supported for systems with off-axis
+    camera.
+    API Status: internal
+    Args:
+        SetValue:int = 0
+    Command Timeout: 300000
+    Example:AutoAlignOffAxis 1
+    """
+    MessageServerInterface.sendSciCommand("AutoAlignOffAxis",SetValue)
+
+
+def FindFocusOffAxis(StepCount:int="", Range:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search. Focus search is performed using the Platen camera. Only supported for
+    systems with off-axis camera.
+    API Status: internal
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocusOffAxis 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocusOffAxis",StepCount,Range)
+    global FindFocusOffAxis_Response
+    if not "FindFocusOffAxis_Response" in globals(): FindFocusOffAxis_Response = namedtuple("FindFocusOffAxis_Response", "ZPosition,Stage")
+    return FindFocusOffAxis_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAuxOffAxis(AuxSiteID:int=""):
+    """
+    Performs an automated aux site alignment in XYZ using the Off Axis camera. Tool
+    can correct reference position and contact height for the given aux site.
+    API Status: published
+    Args:
+        AuxSiteID:int = 0
+    Command Timeout: 300000
+    Example:AlignAuxOffAxis 1
+    """
+    MessageServerInterface.sendSciCommand("AlignAuxOffAxis",AuxSiteID)
+
+
+def FindFocusPlaten(StepCount:int="", Range:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search. Uses the FindFocus tool settings but always the Platen camera -
+    independent of the FindFocus mount. This command is used on e.g. BlueRay systems
+    that have a platen camera but can't use ReAlign/DetectWaferHeight as they don't
+    have an upward looking camera.
+    API Status: internal
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocusPlaten 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocusPlaten",StepCount,Range)
+    global FindFocusPlaten_Response
+    if not "FindFocusPlaten_Response" in globals(): FindFocusPlaten_Response = namedtuple("FindFocusPlaten_Response", "ZPosition,Stage")
+    return FindFocusPlaten_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignChipOffAxis():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a single or two point alignment and moves the current chip to the
+    trained aligned position in Theta (in degrees) and X, Y (in microns). This
+    command is using the off axis platen camera with functionality of ReAlign.
+    API Status: internal
+    Returns:
+        ThetaOffset:Decimal
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 180000
+    Example:AlignChipOffAxis
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignChipOffAxis")
+    global AlignChipOffAxis_Response
+    if not "AlignChipOffAxis_Response" in globals(): AlignChipOffAxis_Response = namedtuple("AlignChipOffAxis_Response", "ThetaOffset,XOffset,YOffset")
+    return AlignChipOffAxis_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SelectAZoomLens(Lens:int=""):
+    """
+    Selects 1 of 4 symbolic lenses (4 classified coarse ranges).
+    API Status: published
+    Args:
+        Lens:int = 1
+    Command Timeout: 10000
+    Example:SelectAZoomLens 1
+    """
+    MessageServerInterface.sendSciCommand("SelectAZoomLens",Lens)
+
+
+def GetAZoomLens():
+    """
+    Returns 1 of 4 symbolic lenses, coarse ranges.
+    API Status: published
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    Example:GetAZoomLens
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAZoomLens")
+    return int(rsp[0])
+
+def AZoomSetupDialog():
+    """
+    Opens the operator panel. In this window you can change the settings for all
+    defined lenses.
+    API Status: published
+    Command Timeout: 5000
+    Example:AZoomSetupDialog
+    """
+    MessageServerInterface.sendSciCommand("AZoomSetupDialog")
+
+
+def MoveAZoomFocus(Focus:int="", Ref:str=""):
+    """
+    Changes the focus magnitude.
+    API Status: published
+    Args:
+        Focus:int = 100
+        Ref:str = "R"
+    Returns:
+        RetFocus:int
+    Command Timeout: 10000
+    Example:MoveAZoomFocus 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAZoomFocus",Focus,Ref)
+    return int(rsp[0])
+
+def ReadAZoomFocus():
+    """
+    Returns the focus magnitude.
+    API Status: published
+    Returns:
+        Focus:int
+    Command Timeout: 5000
+    Example:ReadAZoomFocus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAZoomFocus")
+    return int(rsp[0])
+
+def MoveAZoomVelocity(Direction:str="", Velocity:int=""):
+    """
+    Moves the A-Zoom using the set focus speed.
+    API Status: published
+    Args:
+        Direction:str = ""
+        Velocity:int = 100
+    Returns:
+        RetVelocity:Decimal
+    Command Timeout: 240000
+    Example:MoveAZoomVelocity + 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAZoomVelocity",Direction,Velocity)
+    return Decimal(rsp[0])
+
+def StopAZoom():
+    """
+    Stops the A-Zoom movements.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopAZoom
+    """
+    MessageServerInterface.sendSciCommand("StopAZoom")
+
+
+def SetAZoomLight(Light:int=""):
+    """
+    Switches all lights ON or OFF. ON means the values defined by the current lens.
+    1 switches the light on, 0 switches the light off. Without parameter toggles
+    between on an off.
+    API Status: published
+    Args:
+        Light:int = 0
+    Command Timeout: 5000
+    Example:SetAZoomLight 1
+    """
+    MessageServerInterface.sendSciCommand("SetAZoomLight",Light)
+
+
+def CloseAZoom():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the OpticalControl application. Used during Project File handling.
+    API Status: internal
+    Command Timeout: 5000
+    Example:CloseAZoom
+    """
+    MessageServerInterface.sendSciCommand("CloseAZoom")
+
+
+def OCLightVal(Value:int="", Channel:int="", Segment:int=""):
+    """
+    Set the brightness of given channel and segment to the given value.
+    API Status: published
+    Args:
+        Value:int = 0
+        Channel:int = 1
+        Segment:int = 1
+    Command Timeout: 5000
+    Example:OCLightVal 128 1 4
+    """
+    MessageServerInterface.sendSciCommand("OCLightVal",Value,Channel,Segment)
+
+
+def OCLightOn(On:int="", Channel:int=""):
+    """
+    Switch the light (if it has segments then all) in a given channel ON or OFF.
+    Switch ON - that means: light to the before adjusted brightness.
+    API Status: published
+    Args:
+        On:int = 0
+        Channel:int = 1
+    Command Timeout: 5000
+    Example:OCLightOn 1 1
+    """
+    MessageServerInterface.sendSciCommand("OCLightOn",On,Channel)
+
+
+def OCSetZoomLevel(Zoom:int="", Motor:int=""):
+    """
+    Set logical zoom factor for given motor (if has more then one, else to the one)
+    API Status: published
+    Args:
+        Zoom:int = 0
+        Motor:int = 1
+    Command Timeout: 5000
+    Example:OCSetZoomLevel 50 1
+    """
+    MessageServerInterface.sendSciCommand("OCSetZoomLevel",Zoom,Motor)
+
+
+def OCGetZoomLevel(Motor:int=""):
+    """
+    Get logical zoom factor for given motor (if has more then one, else to the one)
+    API Status: published
+    Args:
+        Motor:int = 1
+    Returns:
+        Zoom:int
+    Command Timeout: 5000
+    Example:OCGetZoomLevel 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("OCGetZoomLevel",Motor)
+    return int(rsp[0])
+
+def StartReAlignTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int=""):
+    """
+    Starts temperature ramping using ReAlign. ReAlign will re-adjust the probes and
+    wafer during ramping to the new target temperature. Command returns immediately.
+    The status of temperature ramping must be checked using the
+    GetReAlignTemperatureStatus command.
+    API Status: published
+    Args:
+        TargetTemperature:Decimal = 0
+        ThetaAlignOnFinish:int = 0
+        ContactOnFinish:int = 0
+    Command Timeout: 5000
+    Example:StartReAlignTemperature 150
+    """
+    MessageServerInterface.sendSciCommand("StartReAlignTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish)
+
+
+def StopReAlignTemperature():
+    """
+    Stops temperature ramping using ReAlign.
+    API Status: published
+    Command Timeout: 10000
+    Example:StopReAlignTemperature
+    """
+    MessageServerInterface.sendSciCommand("StopReAlignTemperature")
+
+
+def GetReAlignTemperatureStatus():
+    """
+    Returns the status of the current temperature ramping using ReAlign process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 300000
+    Example:GetReAlignTemperatureStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetReAlignTemperatureStatus")
+    global GetReAlignTemperatureStatus_Response
+    if not "GetReAlignTemperatureStatus_Response" in globals(): GetReAlignTemperatureStatus_Response = namedtuple("GetReAlignTemperatureStatus_Response", "StatusId,StatusStr")
+    return GetReAlignTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+    """
+    Performs an automatic realignment of the wafer. This includes measuring the
+    needle drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck
+    drift XYZ and optionally a Z-Profile. Alternatively the tool performs a
+    ProbeToDie Alignment to correct the needle position for the current die. Command
+    returns once ReAlign is finished or aborted because of an error.
+    API Status: published
+    Args:
+        Repeats:int = 1
+        Mode:str = "H"
+        AlignProbeCard:int = 2
+        CorrectZ:int = 2
+    Returns:
+        XOffsetWafer:Decimal
+        YOffsetWafer:Decimal
+        ZOffsetWafer:Decimal
+        XOffsetCard:Decimal
+        YOffsetCard:Decimal
+        ZOffsetCard:Decimal
+    Command Timeout: 1000000
+    Example:ReAlign 2 H 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+    global ReAlign_Response
+    if not "ReAlign_Response" in globals(): ReAlign_Response = namedtuple("ReAlign_Response", "XOffsetWafer,YOffsetWafer,ZOffsetWafer,XOffsetCard,YOffsetCard,ZOffsetCard")
+    return ReAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def NextWafer():
+    """
+    Starts the NextWafer routine.
+    API Status: published
+    Returns:
+        Canceled:int
+    Command Timeout: 60000000
+    Example:NextWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("NextWafer")
+    return int(rsp[0])
+
+def StartReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+    """
+    Starts an automatic realignment of the wafer. This includes measuring the needle
+    drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck drift
+    XYZ and optionally a Z-Profile. Alternatively the tool performs a ProbeToPad
+    Alignment to correct the needle position for the current die. Command returns
+    immediately. The status of the asynchronous ReAlign execution must be checked
+    using the GetReAlignStatus command.
+    API Status: published
+    Args:
+        Repeats:int = 1
+        Mode:str = "H"
+        AlignProbeCard:int = 2
+        CorrectZ:int = 2
+    Command Timeout: 60000
+    Example:StartReAlign 2 H 0 0
+    """
+    MessageServerInterface.sendSciCommand("StartReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+
+
+def StopReAlign():
+    """
+    Stops the ReAlign procedure.
+    API Status: published
+    Command Timeout: 120000
+    Example:StopReAlign
+    """
+    MessageServerInterface.sendSciCommand("StopReAlign")
+
+
+def GetReAlignStatus():
+    """
+    Returns a status of the ReAlign procedure. If the return value is true, ReAlign
+    is running.
+    API Status: published
+    Returns:
+        Running:int
+    Command Timeout: 60000
+    Example:GetReAlignStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetReAlignStatus")
+    return int(rsp[0])
+
+def EnableOverlay(Overlay:int=""):
+    """
+    Allows activating the overlay of the needles for the top camera.
+    API Status: published
+    Args:
+        Overlay:int = 0
+    Command Timeout: 6000
+    Example:EnableOverlay 0
+    """
+    MessageServerInterface.sendSciCommand("EnableOverlay",Overlay)
+
+
+def SwitchOffset(Offset:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Switches the offset compensation. Applicable for MicroAlign stations only.
+    API Status: internal
+    Args:
+        Offset:int = 0
+    Command Timeout: 60000
+    Example:SwitchOffset 1
+    """
+    MessageServerInterface.sendSciCommand("SwitchOffset",Offset)
+
+
+def TrainFeature(Model:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command was only implemented for supporting a SCPI legacy command. Does not make
+    sense in Velox, as there is no default training rectangle on the screen as in
+    Nucleus.
+    API Status: internal
+    Args:
+        Model:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 30000
+    Example:TrainFeature 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("TrainFeature",Model)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetEvueExposureLevel():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the exposure value of the eVue. Implemented for supporting SCPI legacy
+    command.
+    API Status: internal
+    Returns:
+        Exposure:Decimal
+    Command Timeout: 10000
+    Example:GetEvueExposureLevel
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueExposureLevel")
+    return Decimal(rsp[0])
+
+def SetEvueExposureLevel(Exposure:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the exposure value of the eVue. Implemented for supporting SCPI legacy
+    command.
+    API Status: internal
+    Args:
+        Exposure:Decimal = 0
+    Command Timeout: 10000
+    Example:SetEvueExposureLevel
+    """
+    MessageServerInterface.sendSciCommand("SetEvueExposureLevel",Exposure)
+
+
+def MoveEvueFocusStage(EvueZ:Decimal="", EvueVelocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the eVue focus stage to a specified position. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Args:
+        EvueZ:Decimal = 0
+        EvueVelocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveEvueFocusStage 1000
+    """
+    MessageServerInterface.sendSciCommand("MoveEvueFocusStage",EvueZ,EvueVelocity)
+
+
+def GetEvueFocusStagePos():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the eVue focus stage. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Returns:
+        EvueZ:Decimal
+    Command Timeout: 5000
+    Example:GetEvueFocusStagePos
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueFocusStagePos")
+    return Decimal(rsp[0])
+
+def RunEvueAutoExpose(UseCB:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command runs the AutoExpose function for the eVue. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Args:
+        UseCB:int = 1
+    Command Timeout: 20000
+    Example:RunEvueAutoExpose 1
+    """
+    MessageServerInterface.sendSciCommand("RunEvueAutoExpose",UseCB)
+
+
+def GetEvueZoomLevel():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Valid only with the eVue microscope that is connected to Velox.     On eVue
+    systems, this command, returns values ranging from 0.5 to 5.0 for a 10x system
+    and 0.5 to 20.0 for a 40x system.
+    API Status: internal
+    Returns:
+        Zoom:Decimal
+    Command Timeout: 5000
+    Example:GetEvueZoomLevel
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueZoomLevel")
+    return Decimal(rsp[0])
+
+def SetEvueZoomLevel(Zoom:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Valid only with the eVue microscope or an A-Zoom microscope that is connected to
+    Velox. On eVue systems, this command sets the proper CCD zoom level to the
+    appropriate optical path.
+    API Status: internal
+    Args:
+        Zoom:Decimal = 0
+    Command Timeout: 5000
+    Example:SetEvueZoomLevel 2.0
+    """
+    MessageServerInterface.sendSciCommand("SetEvueZoomLevel",Zoom)
+
+
+def StartAutomationTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int="", AlignOnFinish:int=""):
+    """
+    Starts temperature ramping using Automation. The Automation (mostly VueTrack)
+    will re-adjust the probes and wafer during ramping to the new target
+    temperature.
+    API Status: published
+    Args:
+        TargetTemperature:Decimal = 0
+        ThetaAlignOnFinish:int = 0
+        ContactOnFinish:int = 0
+        AlignOnFinish:int = 1
+    Command Timeout: 5000
+    Example:StartAutomationTemperature 150
+    """
+    MessageServerInterface.sendSciCommand("StartAutomationTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish,AlignOnFinish)
+
+
+def StopAutomationTemperature():
+    """
+    Stops temperature ramping using Automation.
+    API Status: published
+    Command Timeout: 10000
+    Example:StopAutomationTemperature
+    """
+    MessageServerInterface.sendSciCommand("StopAutomationTemperature")
+
+
+def GetAutomationTemperatureStatus():
+    """
+    Returns the status of the current temperature ramping using automation process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 300000
+    Example:GetAutomationTemperatureStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationTemperatureStatus")
+    global GetAutomationTemperatureStatus_Response
+    if not "GetAutomationTemperatureStatus_Response" in globals(): GetAutomationTemperatureStatus_Response = namedtuple("GetAutomationTemperatureStatus_Response", "StatusId,StatusStr")
+    return GetAutomationTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationActive():
+    """
+    Command to read from Spectrum if Automation (AutoXY, AutoZ or VueTrack) is
+    active. Command is used     by WaferMap to read if it must send MoveChuckAutoXY
+    instead of MoveChuck
+    API Status: published
+    Returns:
+        Active:int
+    Command Timeout: 1000
+    Example:GetAutomationActive
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationActive")
+    return int(rsp[0])
+
+def AutomationNeedleSearch(NeedleIndex:int="", MoveScope:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    VueTrack vision search of the given needle index.
+    API Status: internal
+    Args:
+        NeedleIndex:int = 1
+        MoveScope:int = 1
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+        ZOffset:Decimal
+        XYMatchScore:Decimal
+        ZMatchScore:Decimal
+    Command Timeout: 60000
+    Example:AutomationNeedleSearch 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationNeedleSearch",NeedleIndex,MoveScope)
+    global AutomationNeedleSearch_Response
+    if not "AutomationNeedleSearch_Response" in globals(): AutomationNeedleSearch_Response = namedtuple("AutomationNeedleSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore,ZMatchScore")
+    return AutomationNeedleSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def AutomationReferenceSearch():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    AutomationReferenceSearch exposes the functionality of searching the Automation
+    reference target via remote command
+    API Status: internal
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+        ZOffset:Decimal
+        XYMatchScore:Decimal
+    Command Timeout: 60000
+    Example:AutomationReferenceSearch
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationReferenceSearch")
+    global AutomationReferenceSearch_Response
+    if not "AutomationReferenceSearch_Response" in globals(): AutomationReferenceSearch_Response = namedtuple("AutomationReferenceSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore")
+    return AutomationReferenceSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def MovePositionersSafe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the configured motorized positioners to a safe position
+    API Status: internal
+    Command Timeout: 60000
+    Example:MovePositionersSafe
+    """
+    MessageServerInterface.sendSciCommand("MovePositionersSafe")
+
+
+def SetConstantContactMode(IsOn:int="", ForceLastCorrection:int=""):
+    """
+    Starts Constant Contact mode using Automation. The Automation will re-adjust the
+    wafer during ramping to the new target temperature.
+    API Status: published
+    Args:
+        IsOn:int = 0
+        ForceLastCorrection:int = 0
+    Command Timeout: 5000
+    Example:SetConstantContactMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetConstantContactMode",IsOn,ForceLastCorrection)
+
+
+def GetConstantContactModeStatus():
+    """
+    Returns the status of the current ConstantContact automation process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 5000
+    Example:GetConstantContactModeStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetConstantContactModeStatus")
+    global GetConstantContactModeStatus_Response
+    if not "GetConstantContactModeStatus_Response" in globals(): GetConstantContactModeStatus_Response = namedtuple("GetConstantContactModeStatus_Response", "StatusId,StatusStr")
+    return GetConstantContactModeStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetAutomationActive(Activate:int=""):
+    """
+    Command to set if Automation (AutoXY, AutoZ or VueTrack) is active. Command can
+    be used to e.g. deactivate automation     programmatically in case it is no
+    longer used.     When activating automation, the command will return an error in
+    case it is not possible (e.g. not trained)
+    API Status: published
+    Args:
+        Activate:int = 0
+    Command Timeout: 1000
+    Example:SetAutomationActive 1
+    """
+    MessageServerInterface.sendSciCommand("SetAutomationActive",Activate)
+
+
+def AutomationSearchCurrentDie():
+    """
+    Performs an Automation search and position correction using the current chuck
+    position. Response is X, Y relative distance of adjustment.
+    API Status: published
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 6000000
+    Example:AutomationSearchCurrentDie
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationSearchCurrentDie")
+    global AutomationSearchCurrentDie_Response
+    if not "AutomationSearchCurrentDie_Response" in globals(): AutomationSearchCurrentDie_Response = namedtuple("AutomationSearchCurrentDie_Response", "XOffset,YOffset")
+    return AutomationSearchCurrentDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def PreMapWafer():
+    """
+    PreMapWafer finds actual singulated die locations and updates positions used by
+    WaferMap.
+    API Status: published
+    Returns:
+        NumberOfDies:int
+    Command Timeout: 14400000
+    Example:PreMapWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("PreMapWafer")
+    return int(rsp[0])
+
+def ISSProbeAlign():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs an probe to pad operation on the ISS with two RF positioners.
+    API Status: internal
+    Command Timeout: 6000000
+    Example:ISSProbeAlign
+    """
+    MessageServerInterface.sendSciCommand("ISSProbeAlign")
+
+
+def FindWaferCenter(NoManualRecovery:int=""):
+    """
+    FindWaferCenter finds the center of the wafer using edge detection.
+    API Status: published
+    Args:
+        NoManualRecovery:int = 0
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 300000
+    Example:FindWaferCenter
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindWaferCenter",NoManualRecovery)
+    global FindWaferCenter_Response
+    if not "FindWaferCenter_Response" in globals(): FindWaferCenter_Response = namedtuple("FindWaferCenter_Response", "ChuckX,ChuckY")
+    return FindWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def LocateHomeDie(NoManualRecovery:int=""):
+    """
+    LocateHomeDie finds the center of the wafer using edge detection and sets the
+    home position.
+    API Status: published
+    Args:
+        NoManualRecovery:int = 0
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 300000
+    Example:LocateHomeDie
+    """
+    rsp = MessageServerInterface.sendSciCommand("LocateHomeDie",NoManualRecovery)
+    global LocateHomeDie_Response
+    if not "LocateHomeDie_Response" in globals(): LocateHomeDie_Response = namedtuple("LocateHomeDie_Response", "ChuckX,ChuckY")
+    return LocateHomeDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetAutomationProbeLayout(LayoutName:str="", ProbeID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stores the provided X or Y offset for the given probe for the specified layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+    Command Timeout: 10000
+    Example:SetAutomationProbeLayout "layout1" 1 100.0 0
+    """
+    MessageServerInterface.sendSciCommand("SetAutomationProbeLayout",LayoutName,ProbeID,XOffset,YOffset)
+
+
+def DeleteAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Delete the specfied layout. If LayoutName is empty then all layouts are deleted.
+    If optional ProbeID parmameter is set, it removes just that probe from the
+    layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+    Command Timeout: 10000
+    Example:DeleteAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("DeleteAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def CaptureAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Capture the specfied layout. If optional ProbeID parmameter is set, it captures
+    just that probe from the layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+    Command Timeout: 30000
+    Example:CaptureAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("CaptureAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def MoveToAutomationProbeLayout(LayoutName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move to the probes to specfied layout which are offsets from the trained
+    positions.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+    Command Timeout: 300000
+    Example:MoveToAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("MoveToAutomationProbeLayout",LayoutName)
+
+
+def ResetAutomation():
+    """
+    Reset automation data back to trained values.
+    API Status: published
+    Command Timeout: 10000
+    Example:ResetAutomation
+    """
+    MessageServerInterface.sendSciCommand("ResetAutomation")
+
+
+def GetWaferCenter():
+    """
+    GetWaferCenter returns the chuck location (zero based) of the wafer center. It
+    returns 0 0 if FindWaferCenter has not been executed for the current wafer.
+    API Status: published
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 10000
+    Example:GetWaferCenter
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferCenter")
+    global GetWaferCenter_Response
+    if not "GetWaferCenter_Response" in globals(): GetWaferCenter_Response = namedtuple("GetWaferCenter_Response", "ChuckX,ChuckY")
+    return GetWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def InitEvueFocusStage():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initializes the eVue focus stage by finding the limit switches
+    API Status: internal
+    Command Timeout: 30000
+    Example:InitEvueFocusStage
+    """
+    MessageServerInterface.sendSciCommand("InitEvueFocusStage")
+
+
+def EvueSetNumTraceEntriesPreTrigger(NumTraceEntriesPreTrigger:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the number of trace log items to preserve prior to the trigger event. With
+    the continuous event capture log in Bluestone, up to {X} events are captured and
+    kept after the trigger event is sensed. Then, events are captured after the
+    trigger event until the trace log is full and then trace capture is halted.
+    API Status: internal
+    Args:
+        NumTraceEntriesPreTrigger:int = 0
+    Command Timeout: 30000
+    Example:EvueSetNumTraceEntriesPreTrigger 14
+    """
+    MessageServerInterface.sendSciCommand("EvueSetNumTraceEntriesPreTrigger",NumTraceEntriesPreTrigger)
+
+
+def EvueGetNumTraceEntriesPreTrigger():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the number of trace log items to preserve prior to the trigger event. With
+    the continuous event capture log in Bluestone, up to {X} events are captured and
+    kept after the trigger event is sensed. Then, events are captured after the
+    trigger event until the trace log is full and then trace capture is halted.
+    API Status: internal
+    Returns:
+        NumTraceEntriesPreTrigger:int
+    Command Timeout: 30000
+    Example:EvueGetNumTraceEntriesPreTrigger
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntriesPreTrigger")
+    return int(rsp[0])
+
+def EvueStartCaptureServoTrace():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts capturing events in the eVue motion capture log. Capture continues until
+    the log is full. However, log entries will overwrite the oldest entry until the
+    trigger event is encountered. Then, {X} events are preserved prior to the
+    trigger event and the oldest events are only overwritten if they are not part of
+    that preserved set.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EvueStartCaptureServoTrace
+    """
+    MessageServerInterface.sendSciCommand("EvueStartCaptureServoTrace")
+
+
+def EvueGetTraceMachineStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current status of the trace machine. Bit fields - bit0 is 1 and bit4 is
+    16, etc. bit0 - active and in pre-trigger state bit1 - active and in post-
+    trigger state bit2 - stopped by servo error, lens crash or lens removal bit3 -
+    stopped on requested server state entry bit4 - stopped by immediate command
+    bit5..31 - reserved
+    API Status: internal
+    Returns:
+        TraceMachineStatus:int
+    Command Timeout: 30000
+    Example:EvueGetTraceMachineStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetTraceMachineStatus")
+    return int(rsp[0])
+
+def EvueSetTraceCaptureStopBits(TraceCaptureStopBits:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets condition bits to trigger servo trace capture. Bit fields - bit0 is 1 and
+    bit4 is 16, etc. bit0 - immediate stop bit1 - stop on servo error, lens crash or
+    lens removal bit2 - stop on requested server state (defined by bits 4..7) bit3 -
+    stop on motor move finish bit4..7 - servo state that triggers a trace stop (not
+    an index but the 4-bit state that, if seen, is the trigger for trace capture)
+    bit8..31 - reserved
+    API Status: internal
+    Args:
+        TraceCaptureStopBits:int = 0
+    Command Timeout: 30000
+    Example:EvueSetTraceCaptureStopBits
+    """
+    MessageServerInterface.sendSciCommand("EvueSetTraceCaptureStopBits",TraceCaptureStopBits)
+
+
+def EvueGetNumTraceEntries():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current status of the trace machine.
+    API Status: internal
+    Returns:
+        TraceEntries:int
+    Command Timeout: 30000
+    Example:EvueGetNumTraceEntries
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntries")
+    return int(rsp[0])
+
+def EvueGetTraceEntry(EntryIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the N'th trace entry in the log.
+    API Status: internal
+    Args:
+        EntryIdx:int = 0
+    Returns:
+        CommandedPositionMotorCounts:int
+        CommandedPositionMicrons:Decimal
+        MeasuredPositionMotorCounts:int
+        MeasuredPositionMicrons:Decimal
+        TimestampMicroseconds:int
+        ServoStatus:int
+        PwmVal:int
+    Command Timeout: 30000
+    Example:EvueGetTraceEntry 32
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetTraceEntry",EntryIdx)
+    global EvueGetTraceEntry_Response
+    if not "EvueGetTraceEntry_Response" in globals(): EvueGetTraceEntry_Response = namedtuple("EvueGetTraceEntry_Response", "CommandedPositionMotorCounts,CommandedPositionMicrons,MeasuredPositionMotorCounts,MeasuredPositionMicrons,TimestampMicroseconds,ServoStatus,PwmVal")
+    return EvueGetTraceEntry_Response(int(rsp[0]),Decimal(rsp[1]),int(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def AutomationRFProbeSearch(ImageFilename:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the distance in X,Y between the center tips of the RF probes.
+    API Status: internal
+    Args:
+        ImageFilename:str = ""
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    Example:AutomationRFProbeSearch
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationRFProbeSearch",ImageFilename)
+    global AutomationRFProbeSearch_Response
+    if not "AutomationRFProbeSearch_Response" in globals(): AutomationRFProbeSearch_Response = namedtuple("AutomationRFProbeSearch_Response", "X,Y")
+    return AutomationRFProbeSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def StartAutoRFCalibration():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts the AutoRF calibration sequence.
+    API Status: internal
+    Command Timeout: 3000
+    Example:StartAutoRFCalibration
+    """
+    MessageServerInterface.sendSciCommand("StartAutoRFCalibration")
+
+
+def StopAutoRFCalibration():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the currently running AutoRF calibraiton.
+    API Status: internal
+    Command Timeout: 10000
+    Example:StopAutoRFCalibration
+    """
+    MessageServerInterface.sendSciCommand("StopAutoRFCalibration")
+
+
+def GetAutoRFCalibrationStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the status of the AutoRF calibration sequence.
+    API Status: internal
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 1000
+    Example:GetAutoRFCalibrationStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutoRFCalibrationStatus")
+    global GetAutoRFCalibrationStatus_Response
+    if not "GetAutoRFCalibrationStatus_Response" in globals(): GetAutoRFCalibrationStatus_Response = namedtuple("GetAutoRFCalibrationStatus_Response", "StatusId,StatusStr")
+    return GetAutoRFCalibrationStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationLastStepDiagnostics(Index:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the diagnostic state information for the provided index.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        DiagnosticInfo:str
+    Command Timeout: 5000
+    Example:GetAutomationLastStepDiagnostics
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationLastStepDiagnostics",Index)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMNanoChamberState(State:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the WLEM Nano Chamber State.
+    API Status: internal
+    Args:
+        State:str = "Free"
+    Command Timeout: 5000
+    Example:SetWLEMNanoChamberState Free
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMNanoChamberState",State)
+
+
+def GetWLEMNanoChamberState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the WLEM Nano Chamber State.
+    API Status: internal
+    Returns:
+        State:str
+    Command Timeout: 5000
+    Example:GetWLEMNanoChamberState
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMNanoChamberState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMState(State:str="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the state of a WLEM pneumatic control (valve).
+    API Status: internal
+    Args:
+        State:str = "NCSeal"
+        Value:int = 0
+    Command Timeout: 5000
+    Example:SetWLEMState NCSeal 1
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMState",State,Value)
+
+
+def GetWLEMState(State:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the state of a WLEM pneumatic control (valve).
+    API Status: internal
+    Args:
+        State:str = "NCSeal"
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:GetWLEMState NCSeal
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMState",State)
+    return int(rsp[0])
+
+def GetWLEMSensorValue(Sensor:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the value of a WLEM Sensor.
+    API Status: internal
+    Args:
+        Sensor:str = "O2Concentration"
+    Returns:
+        Value:Decimal
+    Command Timeout: 5000
+    Example:GetWLEMSensorValue O2Concentration
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMSensorValue",Sensor)
+    return Decimal(rsp[0])
+
+def SetWLEMOption(Option:str="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets a WLEM Control program option.
+    API Status: internal
+    Args:
+        Option:str = "MinimizeToTray"
+        Value:int = 0
+    Command Timeout: 5000
+    Example:SetWLEMOption MinimizeToTray 1
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMOption",Option,Value)
+
+
+def GetWLEMOption(Option:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets a WLEM Control program option.
+    API Status: internal
+    Args:
+        Option:str = "MinimizeToTray"
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:GetWLEMOption MinimizeToTray
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMOption",Option)
+    return int(rsp[0])
+
+def NewTesterProject(LotID:str="", TileID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that a new Lot/Tile is to be tested. The tester
+    responds with the correct project name for the test. This is needed because the
+    prober needs to verify that the correct project is loaded. In case no valid
+    project is available, the command is returned with an error.
+    API Status: internal
+    Args:
+        LotID:str = ""
+        TileID:str = ""
+    Returns:
+        ProjectName:str
+    Command Timeout: 30000
+    Example:NewTesterProject Lot01 Tile01
+    """
+    rsp = MessageServerInterface.sendSciCommand("NewTesterProject",LotID,TileID)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StartMeasurement(DieColumn:int="", DieRow:int="", ActiveDies:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester to begin measuring (Needles are in correct
+    position and in contact). The command is responded when the measurement has
+    finished. The response string holds the binning information separated by comma.
+    For deactivated dies, a bin value of '0' should be responded.
+    API Status: internal
+    Args:
+        DieColumn:int = 0
+        DieRow:int = 0
+        ActiveDies:str = ""
+    Returns:
+        BinNumbers:str
+    Command Timeout: 100000
+    Example:StartMeasurement 1 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StartMeasurement",DieColumn,DieRow,ActiveDies)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def EndOfWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester, that the test of the current substrate has
+    finished. It enables the tester application to save measurement data and/or
+    prepare for the next substrate.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EndOfWafer
+    """
+    MessageServerInterface.sendSciCommand("EndOfWafer")
+
+
+def EndOfLot():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester, that the test of the current lot has finished. It
+    enables the tester application to save measurement data and/or prepare for the
+    next lot.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EndOfLot
+    """
+    MessageServerInterface.sendSciCommand("EndOfLot")
+
+
+def VerifyProductID(ProductID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the ProductID that is to be tested. The
+    tester can respond with an error in case the ProductID is not allowed for
+    testing.
+    API Status: internal
+    Args:
+        ProductID:str = ""
+    Command Timeout: 30000
+    Example:VerifyProductID Product123
+    """
+    MessageServerInterface.sendSciCommand("VerifyProductID",ProductID)
+
+
+def VerifyLotID(LotID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the LotID that is to be tested. The tester
+    can respond with an error in case the LotID is not allowed for testing.
+    API Status: internal
+    Args:
+        LotID:str = ""
+    Command Timeout: 30000
+    Example:VerifyLotID Lot123
+    """
+    MessageServerInterface.sendSciCommand("VerifyLotID",LotID)
+
+
+def VerifySubstrateID(SubstrateID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the SubstrateID that is to be tested. The
+    tester can respond with an error in case the SubstrateID is not allowed for
+    testing.
+    API Status: internal
+    Args:
+        SubstrateID:str = ""
+    Command Timeout: 30000
+    Example:VerifySubstrateID Substrate123
+    """
+    MessageServerInterface.sendSciCommand("VerifySubstrateID",SubstrateID)
+
+
+def VerifyProbecard(ProbeCard:str="", Touchdowns:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the ProbecardID and touchdowns that is
+    used for testing. The tester can respond with an error in case the Probecard is
+    not allowed for testing.
+    API Status: internal
+    Args:
+        ProbeCard:str = ""
+        Touchdowns:int = 0
+    Command Timeout: 30000
+    Example:VerifyProbecard Probecard123 10596
+    """
+    MessageServerInterface.sendSciCommand("VerifyProbecard",ProbeCard,Touchdowns)
+
+
+def VerifyUserID(User:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the User ID. The tester can respond with
+    an error in case the User ID is not allowed for testing.
+    API Status: internal
+    Args:
+        User:str = ""
+    Command Timeout: 30000
+    Example:VerifyUserID User123
+    """
+    MessageServerInterface.sendSciCommand("VerifyUserID",User)
+
+
+def TesterAbort():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that the job was aborted and no more test will
+    happen.
+    API Status: internal
+    Command Timeout: 30000
+    Example:TesterAbort
+    """
+    MessageServerInterface.sendSciCommand("TesterAbort")
+
+
+def VerifySOTReady():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that a wafer is ready for testing which will
+    immediately start. This command is sent in the recipe sequence "Verify
+    SOTReady".
+    API Status: internal
+    Command Timeout: 30000
+    Example:VerifySOTReady
+    """
+    MessageServerInterface.sendSciCommand("VerifySOTReady")
+
+
+def VerifyWaferStart(SubstrateID:str="", CassettePlace:str="", LotID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is sent in the VeloxPro recipe sequence "Verify Wafer Start" and
+    informs the tester about the current wafer on the chuck.
+    API Status: internal
+    Args:
+        SubstrateID:str = ""
+        CassettePlace:str = ""
+        LotID:str = ""
+    Command Timeout: 30000
+    Example:VerifyWaferStart Wafer01 1 Lot01
+    """
+    MessageServerInterface.sendSciCommand("VerifyWaferStart",SubstrateID,CassettePlace,LotID)
+
+
+def TesterCassetteInfo(CassetteCmd:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command will be sent after the user selected which wafers are to be tested.
+    It contains a string which represents the state of each wafer: 0 = empty, 1 =
+    full (and selected), 2 = error (e.g. double slotted), 3 = unknown, 4 =
+    deselected
+    API Status: internal
+    Args:
+        CassetteCmd:str = ""
+    Returns:
+        CassetteRsp:str
+    Command Timeout: 30000
+    Example:TesterCassetteInfo 0000001110000000010010111
+    """
+    rsp = MessageServerInterface.sendSciCommand("TesterCassetteInfo",CassetteCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def VerifyProject(ProjectName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is sent after selecting a project file in the VeloxPro product
+    setup page. The command sends the name of the project to tester for
+    verification.
+    API Status: internal
+    Args:
+        ProjectName:str = ""
+    Command Timeout: 30000
+    Example:VerifyProject C:/Users/Public/Documents/Velox/Projects/Test.spp
+    """
+    MessageServerInterface.sendSciCommand("VerifyProject",ProjectName)
+
+
+def TesterAbortWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that the test for the current wafer was aborted
+    and no more tests will happen with the current wafer. The job will continue
+    though.
+    API Status: internal
+    Command Timeout: 30000
+    Example:TesterAbortWafer
+    """
+    MessageServerInterface.sendSciCommand("TesterAbortWafer")
+
+
+def DoTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts execution of one test. It returns a bin number or multple bin numbers
+    when clusters are enabled in the WaferMap (one number for each die in a
+    cluster).  The command starts execution of one test. It returns a bin number or
+    multple bin numbers when clusters are enabled in the WaferMap (one number for
+    each die in a cluster).
+    API Status: internal
+    Returns:
+        BitNumber:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DoTTLTest")
+    return int(rsp[0])
+
+def StartTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts the test of a wafer. Depending on the cluster definitions queried from
+    the WaferMap, all clusters or all dies will be tested.  The command starts the
+    test of a wafer. Depending on the cluster definitions queried from the WaferMap
+    all clusters or all dies will be tested.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("StartTTLTest")
+
+
+def CancelTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the wafer test.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CancelTTLTest")
+
+
+def SetTTLLine(Line:int="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the selected line of PA port.
+    API Status: internal
+    Args:
+        Line:int = 0
+        Value:int = 0
+    Command Timeout: 10000
+    Example:SetTTLLine 2 0
+    """
+    MessageServerInterface.sendSciCommand("SetTTLLine",Line,Value)
+
+
+def GetTTLLines():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the I/O lines as bit array.
+    API Status: internal
+    Returns:
+        LineA:int
+        LineB:int
+        LineC:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTTLLines")
+    global GetTTLLines_Response
+    if not "GetTTLLines_Response" in globals(): GetTTLLines_Response = namedtuple("GetTTLLines_Response", "LineA,LineB,LineC")
+    return GetTTLLines_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetTTLStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns returns the error 914 if the test is in progress.
+    API Status: internal
+    Returns:
+        ErrCode:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTTLStatus")
+    return int(rsp[0])
+
+def StartScript(ScriptName:str=""):
+    """
+    Starts the script and returns the response immediately.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Command Timeout: 10000
+    Example:StartScript myscript
+    """
+    MessageServerInterface.sendSciCommand("StartScript",ScriptName)
+
+
+def GetRunStatus(ScriptName:str=""):
+    """
+    Command returns information about Communicator status.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Returns:
+        Running:int
+        LastError:int
+        Title:str
+    Command Timeout: 5000
+    Example:GetRunStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetRunStatus",ScriptName)
+    global GetRunStatus_Response
+    if not "GetRunStatus_Response" in globals(): GetRunStatus_Response = namedtuple("GetRunStatus_Response", "Running,LastError,Title")
+    return GetRunStatus_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def CloseCommunicator():
+    """
+    Command closes the program. Used during ProjectFile handling.
+    API Status: published
+    Command Timeout: 10000
+    Example:CloseCommunicator
+    """
+    MessageServerInterface.sendSciCommand("CloseCommunicator")
+
+
+def DoScript(ScriptName:str=""):
+    """
+    Executes the script and returns the response afterwards.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Command Timeout: 10000000
+    Example:DoScript myscript
+    """
+    MessageServerInterface.sendSciCommand("DoScript",ScriptName)
+
+
+def ReadKernelData(SilentMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads Kernel Data to KernelSetup (Left Program pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReadKernelData 0
+    """
+    MessageServerInterface.sendSciCommand("ReadKernelData",SilentMode)
+
+
+def SaveKernelDataAs(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves Kernel Data (Left Program pane) to File. An existing File will be
+    overwritten. If the Folder does not exist, it will be created
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:SaveKernelDataAs C:/Temp/RCConfigSample1.xml
+    """
+    MessageServerInterface.sendSciCommand("SaveKernelDataAs",FileName)
+
+
+def LoadConfigFile(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Loads File Data to KernelSetup (Right Program pane).
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:LoadConfigFile C:/Temp/RCConfigSample1.xml
+    """
+    MessageServerInterface.sendSciCommand("LoadConfigFile",FileName)
+
+
+def ReplaceKernelDataByFileData(SilentMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Replaces Kernel Data (Left pane) by File Data (Right pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReplaceKernelDataByFileData 0
+    """
+    MessageServerInterface.sendSciCommand("ReplaceKernelDataByFileData",SilentMode)
+
+
+def ReplaceFileTreeByKernelData(SilentMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Replaces File Tree (Right pane) by Kernel Data (Left pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReplaceFileTreeByKernelData 0
+    """
+    MessageServerInterface.sendSciCommand("ReplaceFileTreeByKernelData",SilentMode)
+
+
+def SaveFileTreeAs(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves File Tree (Right pane) to File. An existing File will be overwritten. If
+    the Folder does not exist, it will be created.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:SaveFileTreeAs C:/Temp/RCConfigSample2.xml
+    """
+    MessageServerInterface.sendSciCommand("SaveFileTreeAs",FileName)
+
+
+def HeatChuck(Temperature:Decimal="", Unit:str="", ReduceContact:int=""):
+    """
+    Sets a new target temperature and starts the heating or cooling of the chuck. An
+    answer to the command will be returned after reaching the given temperature and
+    waiting the soak time or an unexpected interrupt of the process. Given back is
+    the already reached temperature.
+    API Status: published
+    Args:
+        Temperature:Decimal = 25
+        Unit:str = "Celsius"
+        ReduceContact:int = 1
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 36000000
+    Example:HeatChuck 61.3 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("HeatChuck",Temperature,Unit,ReduceContact)
+    global HeatChuck_Response
+    if not "HeatChuck_Response" in globals(): HeatChuck_Response = namedtuple("HeatChuck_Response", "RespTemperature,RespUnit")
+    return HeatChuck_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetHeaterTemp(Temperature:Decimal="", Unit:str="", UseContactSafety:int=""):
+    """
+    Sets a new target temperature and starts the heating or cooling of the
+    temperature chuck. The new target temperature is returned immediately as the
+    command does not wait until heating is complete.
+    API Status: published
+    Args:
+        Temperature:Decimal = 25
+        Unit:str = "Celsius"
+        UseContactSafety:int = 1
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:SetHeaterTemp 55.5 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetHeaterTemp",Temperature,Unit,UseContactSafety)
+    global SetHeaterTemp_Response
+    if not "SetHeaterTemp_Response" in globals(): SetHeaterTemp_Response = namedtuple("SetHeaterTemp_Response", "RespTemperature,RespUnit")
+    return SetHeaterTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetHeaterTemp(Unit:str="", ExternalHeaterID:int=""):
+    """
+    Reads the current temperature of the chuck and determines the status of the
+    thermal system.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+        ExternalHeaterID:int = 0
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+        Status:str
+    Command Timeout: 60000
+    Example:GetHeaterTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHeaterTemp",Unit,ExternalHeaterID)
+    global GetHeaterTemp_Response
+    if not "GetHeaterTemp_Response" in globals(): GetHeaterTemp_Response = namedtuple("GetHeaterTemp_Response", "RespTemperature,RespUnit,Status")
+    return GetHeaterTemp_Response(Decimal(rsp[0]),str(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def EnableHeaterHoldMode(HoldMode:int=""):
+    """
+    Switches the Temperature Chuck devices hold mode on or off. In hold mode the
+    chuck is heated with a constant current to avoid noise from the temperature
+    control. The hold mode can be enabled only in HoldReady state.
+    API Status: published
+    Args:
+        HoldMode:int = 1
+    Returns:
+        RespHoldMode:int
+    Command Timeout: 60000
+    Example:EnableHeaterHoldMode 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("EnableHeaterHoldMode",HoldMode)
+    return int(rsp[0])
+
+def StopHeatChuck():
+    """
+    Stops a pending heating or cooling process. If the device is not at temperature,
+    the actual temperature is set as target temperature.
+    API Status: published
+    Command Timeout: 60000
+    Example:StopHeatChuck
+    """
+    MessageServerInterface.sendSciCommand("StopHeatChuck")
+
+
+def GetDewPointTemp(Unit:str=""):
+    """
+    Returns the current dew point temperature, if a dew point sensor is connected.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:GetDewPointTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDewPointTemp",Unit)
+    global GetDewPointTemp_Response
+    if not "GetDewPointTemp_Response" in globals(): GetDewPointTemp_Response = namedtuple("GetDewPointTemp_Response", "RespTemperature,RespUnit")
+    return GetDewPointTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetTemperatureChuckOptions():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the currently set temperature chuck options.
+    API Status: internal
+    Returns:
+        UseSoakTime:int
+        SyncTemp:int
+        CurrConnection:int
+        MinTemperature:Decimal
+        MaxTemperature:Decimal
+        UsePurge:int
+        UseDynamicSoakTime:int
+        UseFixedDieSoakTime:int
+        UseDynamicDieSoakTime:int
+        UseEcoMode:int
+        PurgeOnChamberDoor:int
+        ForceBypassPurge:int
+        DoorClosedTime:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTemperatureChuckOptions")
+    global GetTemperatureChuckOptions_Response
+    if not "GetTemperatureChuckOptions_Response" in globals(): GetTemperatureChuckOptions_Response = namedtuple("GetTemperatureChuckOptions_Response", "UseSoakTime,SyncTemp,CurrConnection,MinTemperature,MaxTemperature,UsePurge,UseDynamicSoakTime,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime")
+    return GetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]))
+
+def SetTemperatureChuckOptions(UseFixedWaferSoak:int="", SyncTemp:int="", CurrConnection:int="", UsePurge:int="", UseDynamicWaferSoak:int="", UseFixedDieSoakTime:int="", UseDynamicDieSoakTime:int="", UseEcoMode:int="", PurgeOnChamberDoor:int="", ForceBypassPurge:int="", DoorClosedTime:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is used to change the currently set temperature chuck options.
+    API Status: internal
+    Args:
+        UseFixedWaferSoak:int = -1
+        SyncTemp:int = -1
+        CurrConnection:int = -1
+        UsePurge:int = -1
+        UseDynamicWaferSoak:int = -1
+        UseFixedDieSoakTime:int = -1
+        UseDynamicDieSoakTime:int = -1
+        UseEcoMode:int = -1
+        PurgeOnChamberDoor:int = -1
+        ForceBypassPurge:int = -1
+        DoorClosedTime:int = -1
+    Returns:
+        UseFixedWaferSoakRsp:int
+        SyncTempRsp:int
+        CurrConnectionRsp:int
+        UsePurgeRsp:int
+        UseDynamicWaferSoakRsp:int
+        UseFixedDieSoakTimeRsp:int
+        UseDynamicDieSoakTimeRsp:int
+        UseEcoModeRsp:int
+        PurgeOnChamberDoorRsp:int
+        ForceBypassPurgeRsp:int
+        DoorClosedTimeRsp:int
+    Command Timeout: 300000
+    Example:SetTemperatureChuckOptions 1 0 1 1 1 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetTemperatureChuckOptions",UseFixedWaferSoak,SyncTemp,CurrConnection,UsePurge,UseDynamicWaferSoak,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime)
+    global SetTemperatureChuckOptions_Response
+    if not "SetTemperatureChuckOptions_Response" in globals(): SetTemperatureChuckOptions_Response = namedtuple("SetTemperatureChuckOptions_Response", "UseFixedWaferSoakRsp,SyncTempRsp,CurrConnectionRsp,UsePurgeRsp,UseDynamicWaferSoakRsp,UseFixedDieSoakTimeRsp,UseDynamicDieSoakTimeRsp,UseEcoModeRsp,PurgeOnChamberDoorRsp,ForceBypassPurgeRsp,DoorClosedTimeRsp")
+    return SetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]))
+
+def GetHeaterSoak():
+    """
+    Returns the current soak time values in seconds and the soaking status.
+    API Status: published
+    Returns:
+        FixedWaferSoakTime:int
+        FixedWaferSoakStatus:int
+        DynamicWaferSoakTime:Decimal
+        DynamicWaferSoakStatus:int
+        FixedDieSoakTime:Decimal
+        DynamicDieSoakTime:Decimal
+        FixedDieSoakStatus:int
+        DynamicDieSoakStatus:int
+    Command Timeout: 60000
+    Example:GetHeaterSoak
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHeaterSoak")
+    global GetHeaterSoak_Response
+    if not "GetHeaterSoak_Response" in globals(): GetHeaterSoak_Response = namedtuple("GetHeaterSoak_Response", "FixedWaferSoakTime,FixedWaferSoakStatus,DynamicWaferSoakTime,DynamicWaferSoakStatus,FixedDieSoakTime,DynamicDieSoakTime,FixedDieSoakStatus,DynamicDieSoakStatus")
+    return GetHeaterSoak_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),int(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def SetHeaterSoak(FixedWaferSoakTime:int="", DynamicWaferSoakTime:Decimal="", FixedDieSoakTime:Decimal="", DynamicDieSoakTime:Decimal=""):
+    """
+    Sets the new soak time values. The unit of the values is seconds. If soak time
+    is actually running, it may be affected by the change.
+    API Status: published
+    Args:
+        FixedWaferSoakTime:int = 60
+        DynamicWaferSoakTime:Decimal = -1
+        FixedDieSoakTime:Decimal = -1
+        DynamicDieSoakTime:Decimal = -1
+    Command Timeout: 60000
+    Example:SetHeaterSoak 60
+    """
+    MessageServerInterface.sendSciCommand("SetHeaterSoak",FixedWaferSoakTime,DynamicWaferSoakTime,FixedDieSoakTime,DynamicDieSoakTime)
+
+
+def EnableHeaterStandby(Standby:int=""):
+    """
+    Switches the power save (standby) mode of the device on or off. If the device is
+    in power save mode, setting and reading temperatures switches off the power save
+    mode automatically.
+    API Status: published
+    Args:
+        Standby:int = 1
+    Returns:
+        RespStandby:int
+    Command Timeout: 60000
+    Example:EnableHeaterStandby 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("EnableHeaterStandby",Standby)
+    return int(rsp[0])
+
+def ReadTemperatureChuckStatus():
+    """
+    Returns values of the temperature chuck status. The status byte gives
+    information about the current controller's action. The dew point sensor status
+    encapsulates information, if such a sensor is connected, and if the actual dew
+    point difference temperature is readable (active). It can be used for purge
+    control. Soak time left (in seconds) is used when soak time is actually running.
+    API Status: published
+    Returns:
+        Status:str
+        DPSensor:int
+        SoakTimeLeft:int
+        HasEcoMode:int
+    Command Timeout: 60000
+    Example:ReadTemperatureChuckStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTemperatureChuckStatus")
+    global ReadTemperatureChuckStatus_Response
+    if not "ReadTemperatureChuckStatus_Response" in globals(): ReadTemperatureChuckStatus_Response = namedtuple("ReadTemperatureChuckStatus_Response", "Status,DPSensor,SoakTimeLeft,HasEcoMode")
+    return ReadTemperatureChuckStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetTargetTemp(Unit:str=""):
+    """
+    Reads the target temperature of the chuck.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:GetTargetTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTargetTemp",Unit)
+    global GetTargetTemp_Response
+    if not "GetTargetTemp_Response" in globals(): GetTargetTemp_Response = namedtuple("GetTargetTemp_Response", "RespTemperature,RespUnit")
+    return GetTargetTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetThermoWindow(Window:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command sets the window for the target temperture which is the window in which a
+    station is assumed to be at temp. Only supported on Nucleus stations.
+    API Status: internal
+    Args:
+        Window:Decimal = 1
+    Returns:
+        RespWindow:Decimal
+    Command Timeout: 60000
+    Example:SetThermoWindow 2.0
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetThermoWindow",Window)
+    return Decimal(rsp[0])
+
+def GetThermoWindow():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command returns the current thermo window which is the window in which a station
+    is assumed to be at temp. Only supported on Nucleus stations.
+    API Status: internal
+    Returns:
+        RespWindow:Decimal
+    Command Timeout: 60000
+    Example:GetThermoWindow
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetThermoWindow")
+    return Decimal(rsp[0])
+
+def SendThermoCommand(Command:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends a command string to the thermal chuck using the thermal chuck protocol and
+    returns the thermal chucks response as command response. This command can be
+    used to access thermal chuck features that are not exposed as standalone SCI
+    commands. Command is currently implemented for ERS and ATT chucks.
+    API Status: internal
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 5000
+    Example:SendThermoCommand RH
+    """
+    rsp = MessageServerInterface.sendSciCommand("SendThermoCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadAuxStatus(AuxID:int=""):
+    """
+    Returns the status of a single AUX site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        FlagsMode:int
+        Comp:str
+        PresetHeight:str
+        AuxSiteType:str
+    Command Timeout: 10000
+    Example:ReadAuxStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxStatus",AuxID)
+    global ReadAuxStatus_Response
+    if not "ReadAuxStatus_Response" in globals(): ReadAuxStatus_Response = namedtuple("ReadAuxStatus_Response", "AuxIDEcho,FlagsMode,Comp,PresetHeight,AuxSiteType")
+    return ReadAuxStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ReadAuxPosition(AuxID:int="", Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the actual AUX sites position in X, Y and Z. With AUX ID set to 0, the
+    position is read for the chuck stage. If no AUX ID is given, it tries to read
+    the position from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        AuxIDEcho:int
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxPosition 1 Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxPosition",AuxID,Unit,PosRef,Comp)
+    global ReadAuxPosition_Response
+    if not "ReadAuxPosition_Response" in globals(): ReadAuxPosition_Response = namedtuple("ReadAuxPosition_Response", "AuxIDEcho,X,Y,Z")
+    return ReadAuxPosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadAuxHeights(AuxID:int="", Unit:str=""):
+    """
+    Returns the actual technology heights from an AUX site. If AUX ID is set to 0,
+    all response values are read from chuck stage. If no AUX ID is given, it tries
+    to read the heights from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxHeights 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxHeights",AuxID,Unit)
+    global ReadAuxHeights_Response
+    if not "ReadAuxHeights_Response" in globals(): ReadAuxHeights_Response = namedtuple("ReadAuxHeights_Response", "AuxIDEcho,Contact,Overtravel,AlignDist,SepDist")
+    return ReadAuxHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetAuxMode(AuxID:int="", Overtravel:int=""):
+    """
+    Modes manage the way a stage behaves when it is in contact height. AUX site mode
+    holds only a single flag. Flags can be turned on by using the value 1 or turned
+    off by using the value 0. If you do not want to change the flag - use the value
+    of 2. If AUX ID is set to 0, all flags are set for chuck stage. AUX site will
+    move an additional overtravel on every contact move.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Overtravel:int = 2
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxMode 1 2
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxMode",AuxID,Overtravel)
+    return int(rsp[0])
+
+def SetAuxHome(AuxID:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets the AUX sites Home position in X and Y. It defines the origin of the AUX
+    sites coordinate system for later movements. Usually this position is identical
+    to the die home position.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxHome 1 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxHome",AuxID,Mode,Unit,XValue,YValue)
+    return int(rsp[0])
+
+def SetAuxIndex(AuxID:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the AUX sites index size. If AUX ID is set to 0, index size is set for
+    chuck stage.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxIndex 1 1000. 1000. Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxIndex",AuxID,XValue,YValue,Unit)
+    return int(rsp[0])
+
+def SetAuxHeight(AuxID:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    Sets the AUX sites contact height and corresponding gaps for overtravel,
+    alignment and separation height. A contact height search gap for contact search
+    with edge sensor can also be set. This search gap is always identical for all
+    AUX sites. Without any optional parameters the command sets contact height to
+    the current position.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxHeight 1 C 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxHeight",AuxID,PresetHeight,Mode,Unit,Value)
+    return int(rsp[0])
+
+def ReadAuxIndex(AuxID:int="", Unit:str=""):
+    """
+    Returns the actual AUX sites index values. If AUX ID is set to 0, the index size
+    is read from chuck stage. If no AUX ID is given, it tries to read the index from
+    the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxIndex 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxIndex",AuxID,Unit)
+    global ReadAuxIndex_Response
+    if not "ReadAuxIndex_Response" in globals(): ReadAuxIndex_Response = namedtuple("ReadAuxIndex_Response", "AuxIDEcho,IndexX,IndexY")
+    return ReadAuxIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetAuxThetaHome(AuxID:int="", Mode:str="", Unit:str="", Position:Decimal=""):
+    """
+    Sets the AUX sites theta home position. It defines the origin of the AUX sites
+    theta coordinate system for later movements. If AUX ID is set to 0, theta home
+    position is set for chuck stage.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Position:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxThetaHome 1 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxThetaHome",AuxID,Mode,Unit,Position)
+    return int(rsp[0])
+
+def EnableOffset(Stage:str="", Enable:int="", Move:int=""):
+    """
+    Enables or disables the Offset XY compensation for the selected stage. If the
+    compensation holds an offset different from zero, the chuck is automatically
+    moved the distance of the offset. The chuck also moves automatically to a safe
+    height. The move can be disabled by the third parameter. This may put the stage
+    outside the software fence.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        Enable:int = 1
+        Move:int = 1
+    Command Timeout: 60000
+    Example:EnableOffset C 1
+    """
+    MessageServerInterface.sendSciCommand("EnableOffset",Stage,Enable,Move)
+
+
+def SetOffset(Stage:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+    """
+    Sets the offset values for the Offset XY compensation for the selected stage.
+    The changes take effect immediately. Note that the Offset XY compensation must
+    be enabled for the values to take effect. The compensation is enabled or
+    disabled using EnableOffset command.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        OffsetX:Decimal = 0
+        OffsetY:Decimal = 0
+    Command Timeout: 5000
+    Example:SetOffset C 100000.0 0.0
+    """
+    MessageServerInterface.sendSciCommand("SetOffset",Stage,OffsetX,OffsetY)
+
+
+def GetOffsetInfo(Stage:str=""):
+    """
+    Gets information about the Offset XY compensation of the selected stage,
+    including the stored offset values and whether the compensation is enabled or
+    disabled.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        Enable:int
+        OffsetX:Decimal
+        OffsetY:Decimal
+    Command Timeout: 5000
+    Example:GetOffsetInfo C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetOffsetInfo",Stage)
+    global GetOffsetInfo_Response
+    if not "GetOffsetInfo_Response" in globals(): GetOffsetInfo_Response = namedtuple("GetOffsetInfo_Response", "Enable,OffsetX,OffsetY")
+    return GetOffsetInfo_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetSwitchPosition(Stage:str="", AuxSite:int="", X:Decimal="", Y:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the switch position of a stage. This is the position to move to if an aux
+    site gets active. This is only supported for the chuck and it's aux sites. Aux
+    index 0 means wafer site, 1 means aux site 1 and so on.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxSite:int = 0
+        X:Decimal = 0
+        Y:Decimal = 0
+    Command Timeout: 5000
+    Example:SetSwitchPosition C 0 5000 5000
+    """
+    MessageServerInterface.sendSciCommand("SetSwitchPosition",Stage,AuxSite,X,Y)
+
+
+def MoveAuxSite(AuxID:int=""):
+    """
+    Moves the chuck to the position of a given AUX site. A safe height is used for
+    the move. If AUX ID is set to 0, the target of the move is the wafer site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 60000
+    Example:MoveAuxSite 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAuxSite",AuxID)
+    return int(rsp[0])
+
+def SetAuxSiteCount(AuxSiteCount:int=""):
+    """
+    Sets the number of available AUX sites. For preparing for example two cal
+    chucks, the count must be set to 2. For the changes to take effect the system
+    needs to be restarted.
+    API Status: published
+    Args:
+        AuxSiteCount:int = 0
+    Command Timeout: 10000
+    Example:SetAuxSiteCount 2
+    """
+    MessageServerInterface.sendSciCommand("SetAuxSiteCount",AuxSiteCount)
+
+
+def GetAuxSiteCount():
+    """
+    Reads the number of available AUX sites and the ID of the actual active AUX
+    site. If this is 0, the chuck stage is currently active.
+    API Status: published
+    Returns:
+        AuxSiteCount:int
+        ActualAuxSite:int
+    Command Timeout: 10000
+    Example:GetAuxSiteCount
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAuxSiteCount")
+    global GetAuxSiteCount_Response
+    if not "GetAuxSiteCount_Response" in globals(): GetAuxSiteCount_Response = namedtuple("GetAuxSiteCount_Response", "AuxSiteCount,ActualAuxSite")
+    return GetAuxSiteCount_Response(int(rsp[0]),int(rsp[1]))
+
+def SetAuxSiteName(AuxID:int="", AuxSiteName:str=""):
+    """
+    Sets the description of an AUX site. With AUX ID zero, the description of the
+    wafer site can be set.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        AuxSiteName:str = ""
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxSiteName 1 Aux site 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxSiteName",AuxID,AuxSiteName)
+    return int(rsp[0])
+
+def GetAuxSiteName(AuxID:int=""):
+    """
+    This command reads the description of an AUX site. If AUX ID is set to 0, the
+    description of the chuck stage is given back. If no AUX ID is given, it tries to
+    read from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        AuxSiteName:str
+    Command Timeout: 10000
+    Example:GetAuxSiteName 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAuxSiteName",AuxID)
+    global GetAuxSiteName_Response
+    if not "GetAuxSiteName_Response" in globals(): GetAuxSiteName_Response = namedtuple("GetAuxSiteName_Response", "AuxIDEcho,AuxSiteName")
+    return GetAuxSiteName_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def CleanProbeTip(AuxID:str=""):
+    """
+    Starts a probe tip cleaning on the given AUX site. The cleaning algorithm is
+    dependent from the type of the AUX site and from the duration and the cleaning
+    count that is set in configuration. The cleaning algorithm includes both a move
+    to the pad site and a move back to the source site.
+    API Status: published
+    Args:
+        AuxID:str = "-1"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 300000
+    Example:CleanProbeTip 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("CleanProbeTip",AuxID)
+    return int(rsp[0])
+
+def SetAuxSiteType(AuxID:int="", AuxSiteType:str=""):
+    """
+    Sets the type for a given AUX site. It depends on the type of the AUX site, if
+    there is a cleaning algorithm available. It is not possible to set the type of
+    the wafer site (AUX site 0).
+    API Status: published
+    Args:
+        AuxID:int = -1
+        AuxSiteType:str = "AuxUnknown"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxSiteType 1 G
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxSiteType",AuxID,AuxSiteType)
+    return int(rsp[0])
+
+def SetCleaningParams(AuxID:int="", Count:int="", Time:int=""):
+    """
+    Sets the cleaning parameters for a given AUX site. It is not possible to set the
+    cleaning parameters of the wafer site (AUX site 0). If no AUX ID is given, it
+    tries to set the parameters of the active site.     The cleaning count defines,
+    how much times the cleaning is performed repeatedly. The cleaning time defines,
+    how much     milliseconds the needles wait in cleaning position during each
+    cleaning cycle.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Count:int = 1
+        Time:int = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetCleaningParams 1 5 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetCleaningParams",AuxID,Count,Time)
+    return int(rsp[0])
+
+def GetCleaningParams(AuxID:int=""):
+    """
+    Reads the cleaning parameters of a given AUX site. It is not possible to read
+    cleaning parameters of the wafer site (AUX site 0).
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        Count:int
+        Time:int
+        Remaining:int
+    Command Timeout: 30000
+    Example:GetCleaningParams
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCleaningParams",AuxID)
+    global GetCleaningParams_Response
+    if not "GetCleaningParams_Response" in globals(): GetCleaningParams_Response = namedtuple("GetCleaningParams_Response", "AuxIDEcho,Count,Time,Remaining")
+    return GetCleaningParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def UpdateAuxSitePositions(AuxID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Rotate the switch, home, and fence positions to match the current chuck theta
+    angle and adjust Home/Switch by XY offset. Should only be used for Aux sites
+    that don't move theta.
+    API Status: internal
+    Args:
+        AuxID:int = -1
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 5000
+    Example:UpdateAuxSitePositions 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("UpdateAuxSitePositions",AuxID,XOffset,YOffset)
+    return int(rsp[0])
+
+def ResetCleaningPosition(AuxID:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+    """
+    Resets the cleaning position to the beginning of the cleaning aux site (home).
+    API Status: published
+    Args:
+        AuxID:str = "-1"
+        OffsetX:Decimal = 0
+        OffsetY:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:ResetCleaningPosition 5
+    """
+    rsp = MessageServerInterface.sendSciCommand("ResetCleaningPosition",AuxID,OffsetX,OffsetY)
+    return int(rsp[0])
+
+def BnR_EchoData(ControllerID:int="", TestCmd:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Test Command for the Kernel Communication. It is like a ping command. The given
+    text string is returned unchanged.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        TestCmd:str = "Test"
+    Returns:
+        TestRsp:str
+    Command Timeout: 5000
+    Example:BnR_EchoData 1 Hello World
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_EchoData",ControllerID,TestCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_ReportKernelVersion(ControllerID:int="", Module:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual version information of the controller software.
+    The 'Version' value contains version number and revision level of the actual
+    implementation.                                    The text string contains a
+    code description, version number and the revision date.
+    The 'Module' byte is optional (default is K).
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Module:str = "K"
+    Returns:
+        Version:Decimal
+        Description:str
+    Command Timeout: 5000
+    Example:BnR_ReportKernelVersion 1 K
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReportKernelVersion",ControllerID,Module)
+    global BnR_ReportKernelVersion_Response
+    if not "BnR_ReportKernelVersion_Response" in globals(): BnR_ReportKernelVersion_Response = namedtuple("BnR_ReportKernelVersion_Response", "Version,Description")
+    return BnR_ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetStationType(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns information about the connected station.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        StationType:str
+        Type:str
+    Command Timeout: 5000
+    Example:BnR_GetStationType 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetStationType",ControllerID)
+    global BnR_GetStationType_Response
+    if not "BnR_GetStationType_Response" in globals(): BnR_GetStationType_Response = namedtuple("BnR_GetStationType_Response", "StationType,Type")
+    return BnR_GetStationType_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_ResetController(ControllerID:int="", Mode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Restarts the BnR controller.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Mode:str = "X"
+    Command Timeout: 10000
+    Example:BnR_ResetController 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_ResetController",ControllerID,Mode)
+
+
+def BnR_SetOutput(ControllerID:int="", Channel:str="", State:int="", CycleTime:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Controls the Velox output channel signals. It can be used to activate/deactivate
+    outputs.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DO_WaferVacuum"
+        State:int = 0
+        CycleTime:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetOutput 1 1000 1 2000
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetOutput",ControllerID,Channel,State,CycleTime)
+
+
+def BnR_GetOutput(ControllerID:int="", Channel:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the state of an output channel. By using the string identifier DO_ALL, a
+    string list of all outputs is returned in addition
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DO_WaferVacuum"
+    Returns:
+        State:int
+        AllOutputs:str
+    Command Timeout: 5000
+    Example:BnR_GetOutput 1 DO_WaferVacuum
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetOutput",ControllerID,Channel)
+    global BnR_GetOutput_Response
+    if not "BnR_GetOutput_Response" in globals(): BnR_GetOutput_Response = namedtuple("BnR_GetOutput_Response", "State,AllOutputs")
+    return BnR_GetOutput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetInput(ControllerID:int="", Channel:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the state of an input channel. By using the string identifier DI_ALL, a
+    string list of all outputs is returned in addition
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DI_MotorPower"
+    Returns:
+        State:int
+        AllInputs:str
+    Command Timeout: 5000
+    Example:BnR_GetInput 1 DI_MotorPower
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetInput",ControllerID,Channel)
+    global BnR_GetInput_Response
+    if not "BnR_GetInput_Response" in globals(): BnR_GetInput_Response = namedtuple("BnR_GetInput_Response", "State,AllInputs")
+    return BnR_GetInput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_SetAnalogOutput(ControllerID:int="", Channel:str="", OutputPercent:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets an analog output channel to a given value.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "AO_PurgeDewPoint"
+        OutputPercent:Decimal = 50
+    Command Timeout: 5000
+    Example:BnR_SetAnalogOutput 1 AO_PurgeDewPoint 50
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetAnalogOutput",ControllerID,Channel,OutputPercent)
+
+
+def BnR_GetAnalogIO(ControllerID:int="", Channel:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current value of an analog output or input.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "AO_PurgeDewPoint"
+    Returns:
+        Value:Decimal
+        UnderOverflow:int
+    Command Timeout: 5000
+    Example:BnR_GetAnalogIO 1 AO_PurgeDewPoint
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAnalogIO",ControllerID,Channel)
+    global BnR_GetAnalogIO_Response
+    if not "BnR_GetAnalogIO_Response" in globals(): BnR_GetAnalogIO_Response = namedtuple("BnR_GetAnalogIO_Response", "Value,UnderOverflow")
+    return BnR_GetAnalogIO_Response(Decimal(rsp[0]),int(rsp[1]))
+
+def BnR_GetStartupStatus(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the startup status of the BnR controller to determine if the controller
+    is properly booted or still starting.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        StartupStatus:str
+        AdditionalStatusInfo:str
+    Command Timeout: 5000
+    Example:BnR_GetStartupStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetStartupStatus",ControllerID)
+    global BnR_GetStartupStatus_Response
+    if not "BnR_GetStartupStatus_Response" in globals(): BnR_GetStartupStatus_Response = namedtuple("BnR_GetStartupStatus_Response", "StartupStatus,AdditionalStatusInfo")
+    return BnR_GetStartupStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_CreateSdmSystemDump(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Creates a Sdm System Dump file on the B&R flash
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Command Timeout: 60000
+    Example:BnR_CreateSdmSystemDump
+    """
+    MessageServerInterface.sendSciCommand("BnR_CreateSdmSystemDump",ControllerID)
+
+
+def BnR_GetControllerData(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets controller data from the B&R controller. Currently used for init
+    information.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Command Timeout: 10000
+    Example:BnR_GetControllerData 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_GetControllerData",ControllerID)
+
+
+def BnR_WriteMessage(ControllerID:int="", MessageType:str="", Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to write a (native) message to Controller
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        MessageType:str = "mtCryoLoader"
+        Message:str = ""
+    Command Timeout: 5000
+    Example:BnR_WriteMessage 1 mtCryoLoader SampleMessage
+    """
+    MessageServerInterface.sendSciCommand("BnR_WriteMessage",ControllerID,MessageType,Message)
+
+
+def BnR_ReadMessage(ControllerID:int="", MessageType:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to read a (native) message from Controller
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        MessageType:str = "mtCryoLoader"
+    Returns:
+        Message:str
+    Command Timeout: 5000
+    Example:BnR_ReadMessage 1 mtCryoLoader
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReadMessage",ControllerID,MessageType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetDataIterator(ControllerID:int="", ShowAll:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a data stream handle which represents a data stream of setup parameters
+    and requires the BnR_GetNextDatum command.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        ShowAll:int = 0
+    Returns:
+        IdentityToken:int
+        SizeNoAll:int
+    Command Timeout: 5000
+    Example:BnR_GetDataIterator 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetDataIterator",ControllerID,ShowAll)
+    global BnR_GetDataIterator_Response
+    if not "BnR_GetDataIterator_Response" in globals(): BnR_GetDataIterator_Response = namedtuple("BnR_GetDataIterator_Response", "IdentityToken,SizeNoAll")
+    return BnR_GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def BnR_GetNextDatum(ControllerID:int="", IdentityToken:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the next parameter from the data stream. Fields are separated by a
+    colon. Structure of the response parameter Value:
+    Path_Path:Name:Description:Value
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        IdentityToken:int = 0
+    Returns:
+        IsLastDatum:int
+        DatumCode:int
+        PathNameDescrValue:str
+    Command Timeout: 10000
+    Example:BnR_GetNextDatum 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetNextDatum",ControllerID,IdentityToken)
+    global BnR_GetNextDatum_Response
+    if not "BnR_GetNextDatum_Response" in globals(): BnR_GetNextDatum_Response = namedtuple("BnR_GetNextDatum_Response", "IsLastDatum,DatumCode,PathNameDescrValue")
+    return BnR_GetNextDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def BnR_SetDatum(ControllerID:int="", PathNameAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        PathNameAndValue:str = ""
+    Command Timeout: 20000
+    Example:BnR_SetDatum 1 Chuck_XAxisData:CurrentMaximal:70
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetDatum",ControllerID,PathNameAndValue)
+
+
+def BnR_GetDatum(ControllerID:int="", PathName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a value string. The Value string consists of the value and the
+    description. The Locator only consists of the path and the name. All fields are
+    separated by a colon.  Structure of the command parameter Locator:
+    Path_Path:Name Structure of the response parameter Value: Value:Description
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        PathName:str = ""
+    Returns:
+        DatumCode:int
+        ValueDesc:str
+    Command Timeout: 5000
+    Example:BnR_GetDatum 1 Chuck_XAxisData:CurrentMaximal
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetDatum",ControllerID,PathName)
+    global BnR_GetDatum_Response
+    if not "BnR_GetDatum_Response" in globals(): BnR_GetDatum_Response = namedtuple("BnR_GetDatum_Response", "DatumCode,ValueDesc")
+    return BnR_GetDatum_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_DoInternalTask(ControllerID:int="", Task:str="", PCmdInt1:int="", PCmdInt2:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes an internal BnR Task
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Task:str = ""
+        PCmdInt1:int = 0
+        PCmdInt2:int = 0
+    Returns:
+        RspInt:int
+        RspString:str
+    Command Timeout: 10000
+    Example:BnR_DoInternalTask 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_DoInternalTask",ControllerID,Task,PCmdInt1,PCmdInt2)
+    global BnR_DoInternalTask_Response
+    if not "BnR_DoInternalTask_Response" in globals(): BnR_DoInternalTask_Response = namedtuple("BnR_DoInternalTask_Response", "RspInt,RspString")
+    return BnR_DoInternalTask_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetPosition(Stage:str="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current positions for the X,Y,Z (or T) axis for the specified stage
+    as well as the commanded positions.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Unit:str = "Microns"
+    Returns:
+        XorT:Decimal
+        Y:Decimal
+        Z:Decimal
+        CommandedXorT:Decimal
+        CommandedY:Decimal
+        CommandedZ:Decimal
+    Command Timeout: 5000
+    Example:BnR_GetPosition 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetPosition",Stage,Unit)
+    global BnR_GetPosition_Response
+    if not "BnR_GetPosition_Response" in globals(): BnR_GetPosition_Response = namedtuple("BnR_GetPosition_Response", "XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ")
+    return BnR_GetPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def BnR_Move(Stage:str="", XValue:Decimal="", YValue:Decimal="", VelX:Decimal="", VelY:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command executes a XY movement for a specified stage. This can be either a
+    blocking or non blocking move.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        VelX:Decimal = 0
+        VelY:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 60000
+    Example:BnR_Move 1 C 5000 5000 Z 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_Move",Stage,XValue,YValue,VelX,VelY,WaitFinished)
+    global BnR_Move_Response
+    if not "BnR_Move_Response" in globals(): BnR_Move_Response = namedtuple("BnR_Move_Response", "X,Y")
+    return BnR_Move_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def BnR_MoveZ(Stage:str="", ZValue:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the stage Z axis to a new position.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZValue:Decimal = 0
+        Vel:Decimal = 0
+        Dec:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        Z:Decimal
+    Command Timeout: 600000
+    Example:BnR_MoveZ 1 C 12000 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveZ",Stage,ZValue,Vel,Dec,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_ScanMoveZ(ControllerID:int="", Stage:str="", ZDistance:Decimal="", TriggerEveryNthCycle:int="", Vel:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command executes a scan movement of the Z axis that sets a digital output
+    every couple microns to trigger e.g. a camera. After the move is finished, the
+    command returns a list of Z heights at which the digital output was set.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Stage:str = "Chuck"
+        ZDistance:Decimal = 1000
+        TriggerEveryNthCycle:int = 2
+        Vel:Decimal = 10
+    Command Timeout: 300000
+    Example:BnR_ScanMoveZ 1 C 1000 6 10
+    """
+    MessageServerInterface.sendSciCommand("BnR_ScanMoveZ",ControllerID,Stage,ZDistance,TriggerEveryNthCycle,Vel)
+
+
+def BnR_MoveT(TValue:Decimal="", Vel:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes a movement of the theta axis, either blocking or non blocking
+    API Status: internal
+    Args:
+        TValue:Decimal = 0
+        Vel:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        T:Decimal
+    Command Timeout: 60000
+    Example:BnR_MoveT 1 1.003 10 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveT",TValue,Vel,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_StopAxis(Stage:str="", FlagsStop:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops 1... all axes of a stage
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        FlagsStop:int = 15
+    Command Timeout: 5000
+    Example:BnR_StopAxis 1 C 7
+    """
+    MessageServerInterface.sendSciCommand("BnR_StopAxis",Stage,FlagsStop)
+
+
+def BnR_InitAxis(Stage:str="", FlagsInit:int="", FlagsDirection:int="", FlagsInitInPlace:int="", LowLimitX:Decimal="", LowLimitY:Decimal="", LowLimitZ:Decimal="", LowLimitTh:Decimal="", InitInPlaceMoveRangeX:Decimal="", InitInPlaceMoveRangeY:Decimal="", InitInPlaceMoveRangeZ:Decimal="", InitInPlaceMoveRangeTh:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Machine Coordinate System: X Y Z Theta  - _FlagsInit_: X, Y, Z, Theta -
+    _FlagsDirection_: X, Y, Z, Theta (true means plus direction) -
+    _FlagsInitInPlace_: X, Y, Z, Theta   All flags can be accessed by indirect
+    members. Initializes the stage and resets current coordinate system. Should be
+    used only in cases when the reported coordinates do not correspond to real
+    position of mechanics. Init in Place performs the initialization without any
+    movements.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsInitInPlace:int = 0
+        LowLimitX:Decimal = 0
+        LowLimitY:Decimal = 0
+        LowLimitZ:Decimal = 0
+        LowLimitTh:Decimal = 0
+        InitInPlaceMoveRangeX:Decimal = 0
+        InitInPlaceMoveRangeY:Decimal = 0
+        InitInPlaceMoveRangeZ:Decimal = 0
+        InitInPlaceMoveRangeTh:Decimal = 0
+    Command Timeout: 300000
+    Example:BnR_InitAxis 1 C 7
+    """
+    MessageServerInterface.sendSciCommand("BnR_InitAxis",Stage,FlagsInit,FlagsDirection,FlagsInitInPlace,LowLimitX,LowLimitY,LowLimitZ,LowLimitTh,InitInPlaceMoveRangeX,InitInPlaceMoveRangeY,InitInPlaceMoveRangeZ,InitInPlaceMoveRangeTh)
+
+
+def BnR_GetAxisState(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns the state of an axis (disabled/standstill/errorstop/stoppin
+    g/homing/continuousmotion/discretemotion/synchronizedmotion)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        State:str
+        AdditionalStateInfo:str
+    Command Timeout: 5000
+    Example:BnR_GetAxisState 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisState",Stage,Axis)
+    global BnR_GetAxisState_Response
+    if not "BnR_GetAxisState_Response" in globals(): BnR_GetAxisState_Response = namedtuple("BnR_GetAxisState_Response", "State,AdditionalStateInfo")
+    return BnR_GetAxisState_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetAxisStatus(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns some axis status information
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        Initialized:int
+        PositiveEndlimit:int
+        NegativeEndlimit:int
+    Command Timeout: 5000
+    Example:BnR_GetAxisStatus 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisStatus",Stage,Axis)
+    global BnR_GetAxisStatus_Response
+    if not "BnR_GetAxisStatus_Response" in globals(): BnR_GetAxisStatus_Response = namedtuple("BnR_GetAxisStatus_Response", "Initialized,PositiveEndlimit,NegativeEndlimit")
+    return BnR_GetAxisStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def BnR_SetQuietMode(Stage:str="", QuietMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to enable the quiet mode for a stage (quiet turns motors powerless)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        QuietMode:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetQuietMode 1 C 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetQuietMode",Stage,QuietMode)
+
+
+def BnR_GetQuietMode(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to query the quiet mode for a stage
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        QuietMode:int
+    Command Timeout: 5000
+    Example:BnR_GetQuietMode 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetQuietMode",Stage)
+    return int(rsp[0])
+
+def BnR_GetInternalAxisInfo(Stage:str="", Axis:str="", InfoType:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns various axis information, dependent on the InfoType
+    parameter
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        InfoType:str = "StallInfo"
+    Returns:
+        RspString:str
+    Command Timeout: 5000
+    Example:BnR_GetInternalAxisInfo 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetInternalAxisInfo",Stage,Axis,InfoType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetWiringTesterData(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to get various information required for the BnR wiring tester tool.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        STIn_ModuleOK:int
+        STIn_LifeCnt:int
+        STIn_DrvOK:int
+        STIn_OvertemperatureError:int
+        STIn_CurrentError:int
+        STIn_OvercurrentError:int
+        STIn_RefPulsePos:int
+        STIn_RefPulseCnt:int
+        STIn_ModulePowerSupplyError:int
+        STOut_SetTime:int
+        STOut_MotorStep0:int
+        STOut_DriveEnable:int
+        STOut_BoostCurrent:int
+        STOut_StandStillCurrent:int
+        STOut_ClearError:int
+        CMIn_ModuleOK:int
+        CMIn_SDCLifeCount:int
+        CMIn_Encoder:int
+        CMIn_EncoderTimeValid:int
+        CMIn_DigitalInput1:int
+        CMIn_DigitalInput2:int
+        CMIn_BWChannelA:int
+        CMIn_BWChannelB:int
+        CMIn_PowerSupply2:int
+        CMOut_QuitChannelA:int
+        CMOut_QuitChannelB:int
+        SWAxisErrorID:int
+        SWAxisErrorDesc:str
+    Command Timeout: 5000
+    Example:BnR_GetWiringTesterData 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetWiringTesterData",Stage,Axis)
+    global BnR_GetWiringTesterData_Response
+    if not "BnR_GetWiringTesterData_Response" in globals(): BnR_GetWiringTesterData_Response = namedtuple("BnR_GetWiringTesterData_Response", "STIn_ModuleOK,STIn_LifeCnt,STIn_DrvOK,STIn_OvertemperatureError,STIn_CurrentError,STIn_OvercurrentError,STIn_RefPulsePos,STIn_RefPulseCnt,STIn_ModulePowerSupplyError,STOut_SetTime,STOut_MotorStep0,STOut_DriveEnable,STOut_BoostCurrent,STOut_StandStillCurrent,STOut_ClearError,CMIn_ModuleOK,CMIn_SDCLifeCount,CMIn_Encoder,CMIn_EncoderTimeValid,CMIn_DigitalInput1,CMIn_DigitalInput2,CMIn_BWChannelA,CMIn_BWChannelB,CMIn_PowerSupply2,CMOut_QuitChannelA,CMOut_QuitChannelB,SWAxisErrorID,SWAxisErrorDesc")
+    return BnR_GetWiringTesterData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),int(rsp[14]),int(rsp[15]),int(rsp[16]),int(rsp[17]),int(rsp[18]),int(rsp[19]),int(rsp[20]),int(rsp[21]),int(rsp[22]),int(rsp[23]),int(rsp[24]),int(rsp[25]),int(rsp[26]),str("" if len(rsp) < 28 else ' '.join(rsp[27:])))
+
+def BnR_MoveAxis(Stage:str="", Axis:str="", Value:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows moving a single axis to and e.g. in case of X does not
+    trigger a Y movement
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        Value:Decimal = 0
+        Vel:Decimal = 0
+        Dec:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        PositionAfterMove:Decimal
+    Command Timeout: 60000
+    Example:BnR_MoveAxis 1 C X 20000 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveAxis",Stage,Axis,Value,Vel,Dec,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_MoveZCombined(ChuckTargetZ:Decimal="", WaitFinished:int="", ForcedAbsVelocity:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move Chuck-Z and (by fixed factor) Scope X, Y and Z
+    API Status: internal
+    Args:
+        ChuckTargetZ:Decimal = 0
+        WaitFinished:int = 1
+        ForcedAbsVelocity:int = 0
+    Returns:
+        ChuckZ:Decimal
+        ScopeX:Decimal
+        ScopeY:Decimal
+        ScopeZ:Decimal
+    Command Timeout: 600000
+    Example:BnR_MoveZCombined 1 17592.5 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveZCombined",ChuckTargetZ,WaitFinished,ForcedAbsVelocity)
+    global BnR_MoveZCombined_Response
+    if not "BnR_MoveZCombined_Response" in globals(): BnR_MoveZCombined_Response = namedtuple("BnR_MoveZCombined_Response", "ChuckZ,ScopeX,ScopeY,ScopeZ")
+    return BnR_MoveZCombined_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def BnR_StepMove(Stage:str="", ZDown:Decimal="", XValue:Decimal="", YValue:Decimal="", ZUp:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command does a combined Z-XY-Z- move completely on the BnR-controller
+    without WinKernel interaction. This is a part of an ongoing optimization.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZDown:Decimal = 0
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        ZUp:Decimal = 0
+    Command Timeout: 60000
+    Example:BnR_StepMove 1 C 250 1000 1000 250
+    """
+    MessageServerInterface.sendSciCommand("BnR_StepMove",Stage,ZDown,XValue,YValue,ZUp)
+
+
+def BnR_SearchEdgeSensor(SearchEndPos:Decimal="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a search move until the search end position is reached or the edge
+    sensor triggers. If the edge sensor triggers during the move, the trigger
+    position is returned.Otherwise, an edge sensor not found error is returned.
+    API Status: internal
+    Args:
+        SearchEndPos:Decimal = 0
+        Velocity:Decimal = 0
+    Returns:
+        EdgeSensorTriggerPos:Decimal
+    Command Timeout: 300000
+    Example:BnR_SearchEdgeSensor 3000 10
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_SearchEdgeSensor",SearchEndPos,Velocity)
+    return Decimal(rsp[0])
+
+def BnR_GetTraceData(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a collection of trace data
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 5000
+    Example:BnR_GetTraceData 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetTraceData",ControllerID)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_SetTraceMode(ControllerID:int="", Mode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Commands sets the trace mode
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Mode:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetTraceMode 1 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetTraceMode",ControllerID,Mode)
+
+
+def BnR_WriteAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Development command to change a module register value without controller restart
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        MotorModule:int = 0
+        RegisterName:str = ""
+        Value:int = 0
+    Command Timeout: 5000
+    Example:BnR_WriteAxisModuleRegister 1 C X 1 ConfigOutput03 70
+    """
+    MessageServerInterface.sendSciCommand("BnR_WriteAxisModuleRegister",Stage,Axis,MotorModule,RegisterName,Value)
+
+
+def BnR_ReadAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Development command to get any desired module register value
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        MotorModule:int = 0
+        RegisterName:str = ""
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:BnR_ReadAxisModuleRegister 1 C X 1 ConfigOutput03
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReadAxisModuleRegister",Stage,Axis,MotorModule,RegisterName)
+    return int(rsp[0])
+
+def ProcessStationGetStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns process station status (UNKNOWN, IDLE, BUSY, ERROR, PAUSED, Not
+    Initialized) and error code with error message when error.
+    API Status: internal
+    Returns:
+        Status:str
+        SubstratePresent:int
+        LastError:int
+        UseLoaderModule:int
+        WaferSizes:str
+        StatusMessage:str
+        IsLoaderJobRunning:int
+    Command Timeout: 25000
+    Example:ProcessStationGetStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationGetStatus")
+    global ProcessStationGetStatus_Response
+    if not "ProcessStationGetStatus_Response" in globals(): ProcessStationGetStatus_Response = namedtuple("ProcessStationGetStatus_Response", "Status,SubstratePresent,LastError,UseLoaderModule,WaferSizes,StatusMessage,IsLoaderJobRunning")
+    return ProcessStationGetStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ProcessStationInit():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initialize process station machine. This is not the prober init it is a fast
+    program initialization. Only applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 2400000
+    Example:ProcessStationInit
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationInit")
+
+
+def ProcessStationFinish():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Finishes a process station process. This resets some internal test information
+    for the probe station. Some data is only reset in case this command is sent
+    after the last wafer in the job was tested. Only applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 7500000
+    Example:ProcessStationFinish
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationFinish")
+
+
+def ProcessStationPrepareForLoad():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command moves the chuck of the probe station to the secondary load position and
+    if available also checks the table level sensor. Only applies to fully auto
+    systems.
+    API Status: internal
+    Command Timeout: 120000
+    Example:ProcessStationPrepareForLoad
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPrepareForLoad")
+
+
+def ProcessStationLoadComplete():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck out of the load position and checks if a wafer is placed. Only
+    applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationLoadComplete
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationLoadComplete")
+
+
+def ProcessStationPrepareForUnLoad():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The module should do whatever is necessary to prepare the current wafer for
+    unload. Typically this includes things such as moving lift pins and opening
+    doors.
+    API Status: internal
+    Command Timeout: 1000000
+    Example:ProcessStationPrepareForUnLoad
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPrepareForUnLoad")
+
+
+def ProcessStationUnLoadComplete():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The module should so whatever is necessary after a wafer is unloaded. This may
+    for example include closing doors.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationUnLoadComplete
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationUnLoadComplete")
+
+
+def ProcessStationLoadRecipe(ForceReOpenProject:int="", ProjectFileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The recipe is a zipped archive that includes all project data. This command
+    tells the device to load the recipe.
+    API Status: internal
+    Args:
+        ForceReOpenProject:int = 0
+        ProjectFileName:str = ""
+    Command Timeout: 60000
+    Example:ProcessStationLoadRecipe 1 SampleProject.spp
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationLoadRecipe",ForceReOpenProject,ProjectFileName)
+
+
+def ProcessStationVerifyRecipe(ProjectFileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Requests that the device verify that the recipe given can be executed on the
+    device. It should check that the recipe is correctly formed and conforms to the
+    hardware of the device. It should not check for transient things such as whether
+    there is sufficient media or facilities available. those kinds of checks should
+    be done in PrepareForProcess
+    API Status: internal
+    Args:
+        ProjectFileName:str = ""
+    Returns:
+        Verified:int
+        ErrorDescription:str
+    Command Timeout: 60000
+    Example:ProcessStationVerifyRecipe SampleProject.spp
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationVerifyRecipe",ProjectFileName)
+    global ProcessStationVerifyRecipe_Response
+    if not "ProcessStationVerifyRecipe_Response" in globals(): ProcessStationVerifyRecipe_Response = namedtuple("ProcessStationVerifyRecipe_Response", "Verified,ErrorDescription")
+    return ProcessStationVerifyRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ProcessStationStartRecipe(CurrentWaferInJob:int="", TotalWafersInJob:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells VeloxPro to start the current recipe. The station will switch to error if
+    an error occurs. If VeloxPro recipe execution is currently paused, this command
+    tells the system to continue execution.
+    API Status: internal
+    Args:
+        CurrentWaferInJob:int = -1
+        TotalWafersInJob:int = -1
+    Command Timeout: 25000
+    Example:ProcessStationStartRecipe 1
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationStartRecipe",CurrentWaferInJob,TotalWafersInJob)
+
+
+def ProcessStationStopRecipe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells the device to stop the current recipe. The station will switch to error if
+    an error occurs.
+    API Status: internal
+    Command Timeout: 25000
+    Example:ProcessStationStopRecipe
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationStopRecipe")
+
+
+def ProcessStationRecoverError():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells the module to do whatever is necessary to recover from an error condition.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationRecoverError
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationRecoverError")
+
+
+def ProcessStationGetWaferResult():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get substrate information from process station controller application.
+    API Status: internal
+    Returns:
+        Result:str
+        PercentDone:Decimal
+        AllowSkipWafer:int
+        TestInformation:str
+    Command Timeout: 25000
+    Example:ProcessStationGetWaferResult
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationGetWaferResult")
+    global ProcessStationGetWaferResult_Response
+    if not "ProcessStationGetWaferResult_Response" in globals(): ProcessStationGetWaferResult_Response = namedtuple("ProcessStationGetWaferResult_Response", "Result,PercentDone,AllowSkipWafer,TestInformation")
+    return ProcessStationGetWaferResult_Response(str(rsp[0]),Decimal(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def QueryWaferInfo():
+    """
+    Returns information about the wafer that is currently on the probe station. It
+    will return an error when there is no wafer currently on the chuck.
+    API Status: published
+    Returns:
+        Size:int
+        Angle:Decimal
+        ID:str
+        LotID:str
+        ProductID:str
+    Command Timeout: 25000
+    Example:QueryWaferInfo
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryWaferInfo")
+    global QueryWaferInfo_Response
+    if not "QueryWaferInfo_Response" in globals(): QueryWaferInfo_Response = namedtuple("QueryWaferInfo_Response", "Size,Angle,ID,LotID,ProductID")
+    return QueryWaferInfo_Response(int(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ProcessStationPauseRecipe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the process station to PAUSE mode
+    API Status: internal
+    Command Timeout: 25000
+    Example:ProcessStationPauseRecipe
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPauseRecipe")
+
+
+def GetProbingStatus():
+    """
+    Retrieves the current status of the prober. If probing status is AtFirstDie the
+    tester can take control.
+    API Status: published
+    Returns:
+        Status:str
+    Command Timeout: 25000
+    Example:GetProbingStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProbingStatus")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedProbing():
+    """
+    Tells the prober to proceed the recipe when current status is AtFirstDie.
+    API Status: published
+    Command Timeout: 25000
+    Example:ProceedProbing
+    """
+    MessageServerInterface.sendSciCommand("ProceedProbing")
+
+
+def GetCassetteStatus(Cassette:int=""):
+    """
+    Provides all available wafer information. It returns a set of data for each
+    wafer in either cassette. The data contains the cassette and the slot number
+    where the wafer is located, the status of the wafer, and identification
+    information.
+    API Status: published
+    Args:
+        Cassette:int = 0
+    Returns:
+        CassetteStatus:str
+    Command Timeout: 25000
+    Example:GetCassetteStatus 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCassetteStatus",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def QueryWaferID(Module:str="", Slot:int=""):
+    """
+    Queries the wafer ID of a given module and slot.
+    API Status: published
+    Args:
+        Module:str = "Robot"
+        Slot:int = 0
+    Returns:
+        ID:str
+    Command Timeout: 25000
+    Example:QueryWaferID Cassette1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryWaferID",Module,Slot)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def UpdateWaferID(Module:str="", Slot:int="", ID:str=""):
+    """
+    Overrides the wafer ID of the given module and slot. If the wafer id is empty
+    and the module is a Loadport, the id will be read by the idreader if possible.
+    This process behaves as follows:  - the current wafer id is reset - if the read-
+    wafer-process would be delayed (e.g. there is already a   wafer on the idreader)
+    the process will be aborted and an error         will be returned - if the id-
+    reading fails, the process behaves like a normal inventory  triggered by the UI:
+    skip (returns success), abort (returns error)      or "ask user". It is
+    recomended to use either skip or abort for         remote id reading.  If the
+    module is a Loadport and the slot is set to -1, a regular inventory will be
+    triggered. This behaves similar to an inventory triggered by the UI: The ID
+    won't be reset and already scanned wafers won't be reset. Setting an ID
+    explicitly with slot -1 is an error:  - Okay, read id of wafer in slot 3 even if
+    it is already set: UpdateWaferID Cassette1 3 - Okay, set id of wafer in slot 3
+    to XYZ123: UpdateWaferID Cassette1 3 XYZ123 - Okay, start full inventory:
+    UpdateWaferID Cassette1 -1  - Error: UpdateWaferID Cassette1 -1 XYZ123
+    API Status: published
+    Args:
+        Module:str = "Robot"
+        Slot:int = 0
+        ID:str = ""
+    Command Timeout: 1500000
+    Example:UpdateWaferID Cassette1 1 Wafer01
+    """
+    MessageServerInterface.sendSciCommand("UpdateWaferID",Module,Slot,ID)
+
+
+def ConfirmRecipe(ProjectFileName:str=""):
+    """
+    Queries whether the given project/flow name is a valid project/flow at the probe
+    station.  Using file and folder names without white spaces is recommended. For
+    folders and files whith white spaces use quotation marks for the path.  Example
+    for using white spaces:  ConfirmRecipe
+    "C:/Users/Public/Documents/Velox/Projects/White Spaces.spp"
+    API Status: published
+    Args:
+        ProjectFileName:str = ""
+    Returns:
+        Verified:int
+        ErrorDescription:str
+    Command Timeout: 25000
+    Example:ConfirmRecipe C:/Temp/Test.spp
+    """
+    rsp = MessageServerInterface.sendSciCommand("ConfirmRecipe",ProjectFileName)
+    global ConfirmRecipe_Response
+    if not "ConfirmRecipe_Response" in globals(): ConfirmRecipe_Response = namedtuple("ConfirmRecipe_Response", "Verified,ErrorDescription")
+    return ConfirmRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def StartWaferJob(RecipeName:str="", WaferIDs:str=""):
+    """
+    Creates and starts a new job by specifying the flow/spp file and the wafers to
+    be included in the job.
+    API Status: published
+    Args:
+        RecipeName:str = ""
+        WaferIDs:str = ""
+    Returns:
+        JobID:str
+    Command Timeout: 25000
+    Example:StartWaferJob C:/Users/Public/Documents/Velox/Test.flow 1;1 2;1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StartWaferJob",RecipeName,WaferIDs)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetJobParams(JobID:str=""):
+    """
+    Get job information for a specific job ID including the flow file and the list
+    of wafers.
+    API Status: published
+    Args:
+        JobID:str = ""
+    Returns:
+        RecipeName:str
+        WaferIDs:str
+    Command Timeout: 25000
+    Example:GetJobParams 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetJobParams",JobID)
+    global GetJobParams_Response
+    if not "GetJobParams_Response" in globals(): GetJobParams_Response = namedtuple("GetJobParams_Response", "RecipeName,WaferIDs")
+    return GetJobParams_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def JobStatus(JobID:str=""):
+    """
+    Retrieves the status of a specific job by its ID. If the status is ErrorWaiting,
+    an error string is returned.
+    API Status: published
+    Args:
+        JobID:str = ""
+    Returns:
+        Status:str
+        JobStatusInfo:str
+    Command Timeout: 25000
+    Example:JobStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("JobStatus",JobID)
+    global JobStatus_Response
+    if not "JobStatus_Response" in globals(): JobStatus_Response = namedtuple("JobStatus_Response", "Status,JobStatusInfo")
+    return JobStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AbortJob(JobID:str="", Unload:int=""):
+    """
+    Aborts the job given by the job ID. The status of the job will be set to
+    "Aborted". The "Unload" parameter defines whether the wafer remains on the chuck
+    or not.
+    API Status: published
+    Args:
+        JobID:str = ""
+        Unload:int = 0
+    Command Timeout: 25000
+    Example:AbortJob 2 1
+    """
+    MessageServerInterface.sendSciCommand("AbortJob",JobID,Unload)
+
+
+def ProcessStationCloseApplication(NoUserPrompt:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the VeloxPro application.
+    API Status: internal
+    Args:
+        NoUserPrompt:int = 0
+    Command Timeout: 25000
+    Example:ProcessStationCloseApplication
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationCloseApplication",NoUserPrompt)
+
+
+def UnloadWafer():
+    """
+    Unolads a Wafer from the chuck to its origin. If no origin is known, the first
+    free Slot of a loadport will be chosen. A Wafer should be on the chuck.
+    API Status: published
+    Command Timeout: 600000
+    Example:UnloadWafer
+    """
+    MessageServerInterface.sendSciCommand("UnloadWafer")
+
+
+def GetJobList(JobType:str=""):
+    """
+    Returns a string for the relevant JobIDs.
+    API Status: published
+    Args:
+        JobType:str = "Probing"
+    Returns:
+        GetJobList:str
+    Command Timeout: 25000
+    Example:GetJobList
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetJobList",JobType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedJob(ProceedJob:str=""):
+    """
+    Continues a job that is waiting on an error (Job Status ErrorWaiting). The mode
+    determines how the job continues.
+    API Status: published
+    Args:
+        ProceedJob:str = "AbortJob"
+    Command Timeout: 25000
+    Example:ProceedJob AbortJob
+    """
+    MessageServerInterface.sendSciCommand("ProceedJob",ProceedJob)
+
+
+def QueryCassetteID(Cassette:int=""):
+    """
+    Returns the ID of a cassette that is placed on the load port. The loadport and
+    the cassette must support RFID reading (additional hardware needed).
+    API Status: published
+    Args:
+        Cassette:int = 1
+    Returns:
+        ID:str
+    Command Timeout: 25000
+    Example:QueryCassetteID 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryCassetteID",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DockCassette(LoadPortId:int="", DockUndock:int=""):
+    """
+    Docks or undocks a cassette which is placed on a LoadPort (CM300 only). It will
+    return an error if no cassette is placed: the LoadPort is not ready/available or
+    the docking failed. The command will do the docking/undocking and return when
+    this is done.
+    API Status: published
+    Args:
+        LoadPortId:int = 0
+        DockUndock:int = 0
+    Command Timeout: 60000
+    Example:DockCassette 1 1
+    """
+    MessageServerInterface.sendSciCommand("DockCassette",LoadPortId,DockUndock)
+
+
+def LoadWafer(LoadportID:int="", SlotID:int="", AlignmentAngle:Decimal=""):
+    """
+    Load a wafer from a given loadport onto the prober. If no slot id is defined,
+    the first available wafer with the lowest slot id will be loaded. If no loadport
+    is defined, it will try to use the first loadport. If there is no suitable
+    wafer, it will try the second.  Returns an error if the loading process fails or
+    no suitable wafer is found.  To define an alignment angle and still use the
+    "autoselect" behaviour, use -1 for loadport and slot.
+    API Status: published
+    Args:
+        LoadportID:int = -1
+        SlotID:int = -1
+        AlignmentAngle:Decimal = 0
+    Command Timeout: 600000
+    Example:LoadWafer 1 1
+    """
+    MessageServerInterface.sendSciCommand("LoadWafer",LoadportID,SlotID,AlignmentAngle)
+
+
+def UpdateCassetteStatus(Cassette:int=""):
+    """
+    Updates the cassette status with a simple scan.
+    API Status: published
+    Args:
+        Cassette:int = 0
+    Returns:
+        CassetteStatus:str
+    Command Timeout: 1200000
+    Example:UpdateCassetteStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("UpdateCassetteStatus",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def TransportWafer(SourceLocation:str="", SourceSlot:int="", DestinationLocation:str="", DestinationSlot:int=""):
+    """
+    Transport a wafer from one location to another. This command behaves like the
+    wafer-transport inside the LoaderModule. The Slot must always be set.
+    API Status: published
+    Args:
+        SourceLocation:str = "Cassette1"
+        SourceSlot:int = 1
+        DestinationLocation:str = "Cassette1"
+        DestinationSlot:int = 1
+    Command Timeout: 600000
+    Example:TransportWafer Cassette1 1 PreAligner 1
+    """
+    MessageServerInterface.sendSciCommand("TransportWafer",SourceLocation,SourceSlot,DestinationLocation,DestinationSlot)
+
+
+def ProcessWafer(Module:str="", ProcessParam:str=""):
+    """
+    "Process" a wafer on a given location. What is done depends on the current
+    station:  - IDReader: read ID - PreAligner: align wafer (alignment angle
+    mandatory) - Prober: Perform current recipe
+    API Status: published
+    Args:
+        Module:str = "Cassette1"
+        ProcessParam:str = ""
+    Command Timeout: 100000
+    Example:ProcessWafer PreAligner 90.0
+    """
+    MessageServerInterface.sendSciCommand("ProcessWafer",Module,ProcessParam)
+
+
+def GetIDReaderPos():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the IDReader
+    API Status: internal
+    Returns:
+        IDReaderPos:str
+    Command Timeout: 2000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetIDReaderPos")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetIDReaderPos(IDReaderPos:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the current position of the IDReader
+    API Status: internal
+    Args:
+        IDReaderPos:str = "Bottom"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetIDReaderPos",IDReaderPos)
+
+
+def CryoCommand(Process:str=""):
+    """
+    CryoCommand controls automatic cooling and warm up.
+    API Status: published
+    Args:
+        Process:str = "CD"
+    Command Timeout: 60000
+    Example:CryoCommand CD
+    """
+    MessageServerInterface.sendSciCommand("CryoCommand",Process)
+
+
+def CryoReadTemperature(Stage:str=""):
+    """
+    Reads the current temperature from sensor chuck or shield.
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Returns:
+        Temp:Decimal
+    Command Timeout: 10000
+    Example:CryoReadTemperature C
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadTemperature",Stage)
+    return Decimal(rsp[0])
+
+def CryoSetTemperature(Stage:str="", Temp:Decimal=""):
+    """
+    Sets temperature value for TIC chuck or shield. (Only available in process state
+    'Idle' or 'Cold'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+        Temp:Decimal = 320
+    Command Timeout: 10000
+    Example:CryoSetTemperature C 70.5
+    """
+    MessageServerInterface.sendSciCommand("CryoSetTemperature",Stage,Temp)
+
+
+def CryoStartRefill(Stage:str=""):
+    """
+    Enables refill. (Only available in process state 'Idle'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Command Timeout: 10000
+    Example:CryoStartRefill C
+    """
+    MessageServerInterface.sendSciCommand("CryoStartRefill",Stage)
+
+
+def CryoStopRefill(Stage:str=""):
+    """
+    Disables refill. (Only available in process state 'Idle'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Command Timeout: 10000
+    Example:CryoStopRefill C
+    """
+    MessageServerInterface.sendSciCommand("CryoStopRefill",Stage)
+
+
+def CryoReadState():
+    """
+    Reads current state.
+    API Status: published
+    Returns:
+        State:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CryoMoveBBPark():
+    """
+    Moves the black body to parking position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveBBPark")
+
+
+def CryoMoveBBWork(NbrPosition:int=""):
+    """
+    Moves the black body to working position.
+    API Status: published
+    Args:
+        NbrPosition:int = 1
+    Command Timeout: 60000
+    Example:CryoMoveBBWork 1
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveBBWork",NbrPosition)
+
+
+def CryoMoveShutter(Position:str="", Shutter:int=""):
+    """
+    Moves one of the two shutters.
+    API Status: published
+    Args:
+        Position:str = "C"
+        Shutter:int = 1
+    Command Timeout: 60000
+    Example:CryoMoveShutter F 1
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveShutter",Position,Shutter)
+
+
+def CryoMoveScopeWork():
+    """
+    Moves the microscope to working position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveScopeWork")
+
+
+def CryoMoveScopePark():
+    """
+    Moves the microscope to parking position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveScopePark")
+
+
+def CryoReadPressure():
+    """
+    Reads the current pressure of the vacuum chamber.
+    API Status: published
+    Returns:
+        Pressure:Decimal
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadPressure")
+    return Decimal(rsp[0])
+
+def MoveZCombined(Height:Decimal="", Percent:Decimal="", Async:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move both Chuck and Scope to a new absolute z-Height. The position must be
+    within 0 and a predefined maximum height (e.g. 3000um). Moves are performed with
+    maximum velocity for now
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        Percent:Decimal = 0
+        Async:int = 0
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombined",Height,Percent,Async)
+
+
+def GetSoftwareStop():
+    """
+    Get the state of the software stop.
+    API Status: published
+    Returns:
+        StopState:int
+    Command Timeout: 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwareStop")
+    return int(rsp[0])
+
+def MoveZCombinedSetStatus(Status:str="", Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Used to set the system either in off, on, error or locked state.  For lock, a
+    key is required. To unlock this key, doe a 'SetStatus' with the same key. So,
+    SetStatus without message means enable/ recover from error, with message it
+    means unlock. If the system wasn't enabled or in error state before an unlock,
+    it will remain in this state after the unlock.
+    API Status: internal
+    Args:
+        Status:str = "Off"
+        Message:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombinedSetStatus",Status,Message)
+
+
+def GetScopeWorkingStage():
+    """
+    Get the currently active ScopeWorkingStage or -1 if unknown. Normally, this
+    should be the same as the currently active ScopeSilo
+    API Status: published
+    Returns:
+        ScopeWorkingStage:int
+    Command Timeout: 5000
+    Example:GetScopeWorkingStage
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetScopeWorkingStage")
+    return int(rsp[0])
+
+def SetPerformanceMode(Mode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the performance mode in use by remote command. If this feature is not
+    supported and the mode is anything but Standard, an error is returned.
+    API Status: internal
+    Args:
+        Mode:str = "Standard"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SetPerformanceMode",Mode)
+
+
+def SetScopeWorkingStage(ScopeWorkingStage:int=""):
+    """
+    Move to the target working stage
+    API Status: published
+    Args:
+        ScopeWorkingStage:int = -1
+    Command Timeout: 30000
+    Example:SetScopeWorkingStage 1
+    """
+    MessageServerInterface.sendSciCommand("SetScopeWorkingStage",ScopeWorkingStage)
+
+
+def GetPerformanceMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the currently configured performance mode. If this feature is not supported
+    on a station, Standard will be returned
+    API Status: internal
+    Returns:
+        Mode:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPerformanceMode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def MoveZCombinedGetStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the current status of the combined-z-move-system
+    API Status: internal
+    Returns:
+        Status:str
+        PlatenSafe:int
+        Height:Decimal
+        HeightMax:Decimal
+        HeightRelative:Decimal
+        SafeHeight:Decimal
+        Message:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveZCombinedGetStatus")
+    global MoveZCombinedGetStatus_Response
+    if not "MoveZCombinedGetStatus_Response" in globals(): MoveZCombinedGetStatus_Response = namedtuple("MoveZCombinedGetStatus_Response", "Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message")
+    return MoveZCombinedGetStatus_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str("" if len(rsp) < 7 else ' '.join(rsp[6:])))
+
+def LoadScopeFenceConfiguration(Enable:int="", Path:str=""):
+    """
+    Load a previously saved Scope-Fence-configuration or remove the current
+    configuration
+    API Status: published
+    Args:
+        Enable:int = 0
+        Path:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LoadScopeFenceConfiguration",Enable,Path)
+
+
+def SetSoftwareStop(StopState:int=""):
+    """
+    Set the state of the software stop.
+    API Status: published
+    Args:
+        StopState:int = 0
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("SetSoftwareStop",StopState)
+
+
+#End of module
+def trace(frame, event, arg):
+    print("%s, %s:%d" % (event, frame.f_code.co_filename, frame.f_lineno))
+    return trace
+
+
+class MessageServerInterface(object):
+    # For storing things
+    current_die = 1
+    current_die_coords = [0, 0]
+
+    chuck_home = [0, 0]
+    current_chuck_position = {'x': 0, 'y': 0, 'z': 0}
+    map_home = [0, 0]
+
+    contact_height = -10
+    # constants
+    dies = {
+            "1": [-6,4],
+            "2":  [-5,4],
+            "3":  [-4,4],
+            "4":  [-3,4],
+            "5":  [-2,4],
+            "6":  [-8,3],
+            "7":  [-7,3],
+            "8":  [-6,3],
+            "9":  [-5,3],
+            "10":  [-4,3],
+            "11":  [-3,3],
+            "12":  [-2,3],
+            "13":  [-1,3],
+            "14":  [-9,2],
+            "15":  [-8,2],
+            "16":  [-7,2],
+            "17":  [-6,2],
+            "18":  [-5,2],
+            "19":  [-4,2],
+            "20":  [-3,2],
+            "21":  [-2,2],
+            "22":  [-1,2],
+            "23":  [0,2],
+            "24":  [-9,1],
+            "25":  [-8,1],
+            "26":  [-7,1],
+            "27":  [-6,1],
+            "28":  [-5,1],
+            "29":  [-2,1],
+            "30":  [-3,1],
+            "31":  [-2,1],
+            "32":  [-1,1],
+            "33":  [0,1],
+            "34":  [-9,0],
+            "35":  [-8,0],
+            "36":  [-7,0],
+            "37":  [-6,0],
+            "38":  [-5,0],
+            "39":  [-4,0],
+            "40":  [-3,0],
+            "41":  [-2,0],
+            "42":  [-1,0],
+            "43":  [0,0],
+            "44":  [-9,-1],
+            "45":  [-8,-1],
+            "46":  [-7,-1],
+            "47":  [-6,-1],
+            "48":  [-5,-1]
+        }
+
+    def __init__(self):
+        print ("MessageServerInterface: initializing")
+
+    def __enter__(self):
+        #-uc-# print ("MessageServerInterface: entering")
+        return self
+
+    def __exit__(self, *args, **kwargs):
+        print ("MessageServerInterface: closed %s %s %s" % (args, kwargs, self))
+
+    @staticmethod
+    def generate_powermeter_values(weights=[10, 10, 20, 10, 35]):
+
+        power = [0, 0]
+        for i in [0, 1]:# generate a random values between -75 and -22 dBm
+            power_75_70 = round(random.randint(-75, -70) + random.random(), 4)
+            power_70_65 = round(random.randint(-70, -65) + random.random(), 4)
+            power_65_55 = round(random.randint(-65, -60) + random.random(), 4)
+            power_30_25 = round(random.randint(-30, -25) + random.random(), 4)
+            power_25_20 = round(random.randint(-25, -20) + random.random(), 4)
+            # Choose randomly between the values, but weighted
+            data_list = [power_75_70] * weights[0] + [power_70_65] * weights[1] + [power_65_55] * weights[2] + [power_30_25] * weights[3] + [power_25_20] * weights[4]
+            power[i] = random.choice(data_list)
+
+        return power[0], power[1]
+
+    @staticmethod
+    def sendSciCommand(*args, **kwargs):
+
+        try:
+            #-uc-# print (">> [SENDING SCI COMMAND static] args: %s, kwargs: %s" % (args, kwargs))
+            if len(kwargs) > 0:
+                args_split = str(kwargs['rparams']).split()
+                func = getattr(MessageServerInterface, args[0])
+                return func(*args_split)
+            else:
+                func = getattr(MessageServerInterface, args[0])
+                return func(*args[1:])
+        except Exception as e:
+            print(">> [SENDING SCI COMMAND static] Exception: %s" % e)
+            return None
+
+    @staticmethod
+    def MoveOpticalProbe(probe, x, y, PosRef = "C"):
+        ''' Move selected probe motor in XY.
+            Input Parameter
+            probe 0=Input, 1=Output (I)
+            x motor command [um] (D)
+            y motor command [um] (D)
+            PosRef R=Relative, H=Home, Z=Zero (C)
+            Output Parameter
+            x motor position [um] (D)
+            y motor position [um] (D)
+            z motor position [um] (D)
+        '''
+        #-uc-# print ("  |-> [MoveOpticalProbe] probe: %s x: %s y: %s PosRef: %s:  " % (probe, x, y, PosRef))
+        z = 500
+        return x, y, z
+
+    @staticmethod
+    def SetOpticalProbeHome(probe):
+        z = 500
+        return 0, 0, 0, 1, 1, 1
+
+
+    @staticmethod
+    def ReadOpticalProbePowerMeter(channel):
+        '''Read computed power level from probe control.
+
+        API Status:
+            dummy testing
+        Parameters:
+            channel:  (Optional) analog input channel (I)
+        Returns:
+            power: calibrated power meter value [dBm] (D)
+        '''
+        #-uc-# print ("  |-> [ReadOpticalProbePowerMeter] channel: %s" % (channel))
+        # return a value between -75 and -22 dBm
+
+        # generate a random values between -75 and -22 dBm
+        power, _ = MessageServerInterface.generate_powermeter_values()
+        return power
+
+    @staticmethod
+    def FindOpticalProbeHeight(probe, height, tracking_on=False):
+        '''Find motor and PZT positions to set desired fiber height above wafer.
+
+        Parameters:
+            probe:          0=Input, 1=Output (I)
+            height:         Fiber height [um] (D)
+            tracking on:    (Optional) Enable fly height control (B)
+        Returns:
+            height: fiber height [um] (D)
+            Z sensor: Z sensor value (D)
+            motorZ: motor Z position [um] (D)
+            PZTZ: PZT Z position [um] (D)
+        '''
+        #-uc-# print ("  |-> [FindOpticalProbeHeight] channel: probe %s, height %s, tracking_on %s" % (probe, height, tracking_on))
+        # Add a small delay, to simulate a real measurement up to 1 sec
+        time.sleep(random.random())
+        return height, 0, 0, 0
+
+    @staticmethod
+    def RecenterOpticalProbe(probe):
+        '''Recenter XYZ motor position by the distance PZT is off center and recenter PZT
+
+        Parameters:
+            probe:          0=Input, 1=Output (I)
+        '''
+        #-uc-# print ("  |-> [RecenterOpticalProbe] probe: %s +" % (probe))
+        # Add a small delay, to simulate a real measurement up to 0,25 sec
+        time.sleep(random.random()*0.25)
+
+    @staticmethod
+    def AreaScan(input, output, filename = None):
+        '''Perform Area ScanPerform.
+        Parameters:
+            Input: Input scan enabled (B)
+            Output: Output scan enabled (B)
+            Filename: (Optional) Data file name (S)
+        Returns:
+            x: x Input PZT position [um] (D)
+            y: y Input PZT position [um] (D)
+            x: x Output PZT position [um] (D)
+            y: y Output PZT position [um] (D)
+            InputPower: Input scan power [dBm] (D)
+            OutputPower: Output scan power [dBm] (D)
+        '''
+        #-uc-# print ("  |-> [AreaScan] input %s, output %s, filename %s" % (input, output, filename))
+        # Add a small delay, to simulate a real measurement up to 4 sec
+        #time.sleep(3)
+        #time.sleep(random.random())
+        power_in, power_out = MessageServerInterface.generate_powermeter_values(weights=[30, 0, 0, 20, 50])
+        #power_in, power_out = MessageServerInterface.generate_powermeter_values(weights=[0, 0, 0, 0, 100])
+
+        return 0, 0, 0, 0, power_in, power_out
+
+    @staticmethod
+    def ReadOpticalProbePos(probe, posRef = "C"):
+        '''Read optical probe position.
+
+        Parameters:
+            probe:   0=Input, 1=Output (I)
+            PosRef:  H=Home, Z=Zero (C)
+        Returns:
+            x: x motor position [um] (D)
+            y: y motor position [um] (D)
+            z: z motor position [um] (D)
+            x: x PZT position [um] (D)
+            y: y PZT position [um] (D)
+            z: z PZT position [um] (D)
+        '''
+        #-uc-# print ("  |-> [ReadOpticalProbePos] probe: %s %s" % (probe, posRef))
+        # Add a small delay, to simulate a real measurement up to 1 sec
+        time.sleep(random.random())
+        return 0, 0, 0, 0, 0, 0
+
+    @staticmethod
+    def EchoData(string):
+        '''
+        Args:
+            TestCmd:str = "Test"
+        Returns:
+            TestRsp: str
+            '''
+        #-uc-# print ("  |-> [EchoData] string: %s" % (string))
+        return string
+
+    @staticmethod
+    def ReportKernelVersion(module):
+        #-uc-# print ("  |-> [ReportKernelVersion] module: %s" % (module))
+        return "1.0 Velox Simulator "
+
+    @staticmethod
+    def TrackOpticalProbeHeight(probe, enable):
+        '''Track current fiber height.
+        Parameters:
+            probe: 0=Input, 1=Output (I)
+            enable: enable fly height control (B)
+        '''
+        #-uc-# print ("  |-> [TrackOpticalProbeHeight] probe: %s enable: %s" % (probe, enable))
+        # Add a small delay, to simulate a real measurement up to 1 sec
+        time.sleep(random.random())
+
+    @staticmethod
+    def StepToDie(die_number:int="", site:int=""):
+        """
+            Steps the chuck to the die location specified by the die number of the wafer
+            map. If no command data is passed, the chuck automatically steps to the next
+            logical wafer map die location. Returns the row and column number of the actual
+            die location after the move is completed. In addition, the SubDie location, and
+            total number of SubDies is also returned.
+            API Status: published
+            Args:
+                die_number:int = -1
+                site:int = 0
+            Returns:
+                RDieX:int
+                RDieY:int
+                CurSite:int
+                LastSiteIndex:int
+            Command Timeout: 6000000
+        """
+
+
+        #-uc-# print ("  |-> [StepToDie] die_number: %s, site:%s" % (die_number, site))
+        # Step to this die
+        MessageServerInterface.current_die = die_number
+        # Set the coordinates accordingly
+        MessageServerInterface.current_die_coords = [MessageServerInterface.dies[str(die_number)][0], MessageServerInterface.dies[str(die_number)][1]]
+        # Add a small delay, to simulate a real measurement up to 1 sec
+        time.sleep(random.random())
+        return MessageServerInterface.current_die_coords[0], MessageServerInterface.current_die_coords[1], 0, 0
+
+    @staticmethod
+    def GetDieDataAsColRow(c_die_x="", c_die_y=""):
+        """
+        Returns the Die Information in the Row Column format. If the Die Number is
+        invalid it returns an error. If the Die Column and Row are absent it uses the
+        current die on the wafer.
+        API Status: published
+        Args:
+            CDieX:int = 0
+            CDieY:int = 0
+        Returns:
+            DieIndex:int
+            RDieX:int
+            RDieY:int
+            Bin:int
+            Result:str
+        Command Timeout: 10000
+        """
+        #-uc-# print ("  |-> [GetDieDataAsColRow] c_die_x: %s, c_die_y:%s" % (c_die_x, c_die_y))
+        if c_die_x == "" and c_die_y == "":
+           return MessageServerInterface.current_die, MessageServerInterface.current_die_coords[0], MessageServerInterface.current_die_coords[1], 0, "OK"
+
+        for die in  MessageServerInterface.dies:
+            if MessageServerInterface.dies[die][0] == c_die_x and  MessageServerInterface.dies[die][1] == c_die_y:
+                return int(die),  MessageServerInterface.dies[die][0],  MessageServerInterface.dies[die][1], 0, "OK"
+
+    @staticmethod
+    def SetChuckHome(mode="0", unit="Microns", x_value="0", y_value="0"):
+        """
+            Sets wafer and die home position, which can be used later as coordinate system
+            for movements.
+            API Status: published
+            Args:
+                Mode:str = "0"
+                Unit:str = "Microns"
+                XValue:Decimal = 0
+                YValue:Decimal = 0
+            Command Timeout: 5000
+            Example:SetChuckHome 0 Y
+        """
+        #-uc-# print ("  |-> [SetChuckHome] mode %s, unit %s, x_value %s, y_value %s" % (mode, unit, x_value, y_value))
+        MessageServerInterface.current_cuck_position = {'x': 0, 'y': 0, 'z': -500}
+        if mode == 0:
+            MessageServerInterface.chuck_home = []
+
+    @staticmethod
+    def SetMapHome(die_x = "", die_y = ""):
+        """
+        If the command has no parameters it sets the current position as home position
+        both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+        home position using the given die coordinates.
+        API Status: published
+        Args:
+            DieX:int = 0
+            DieY:int = 0
+        Command Timeout: 10000
+        """
+        MessageServerInterface.map_home = [die_x, die_y]
+        #-uc-# print ("  |-> [SetMapHome] die_x %s, die_y %s" % (die_x, die_y))
+
+    def ReadChuckPosition(Unit="Microns", PosRef="Home", Comp="Default"):
+        """
+        Returns the current chuck stage position in X, Y and Z.
+        API Status: published
+        Args:
+            Unit:str = "Microns"
+            PosRef:str = "Home"
+            Comp:str = "Default"
+        Returns:
+            X:Decimal
+            Y:Decimal
+            Z:Decimal
+        Command Timeout: 5000
+        Example:ReadChuckPosition Y Z
+        """
+        #-uc-# print ("  |-> [ReadChuckPosition] unit %s, pos_ref %s, comp %s" % (Unit, PosRef, Comp))
+        return (
+                MessageServerInterface.current_chuck_position['x'],
+                MessageServerInterface.current_chuck_position['y'],
+                MessageServerInterface.current_chuck_position['z']
+        )
+
+    @staticmethod
+    def ReadChuckHeights(Unit=""):
+        """
+        Returns the current settings used for the chuck Z movement. `Contact` is the
+        contact-height from zero in default compensation. The other heights are relative
+        to this. If no contact is set, the value will be -1.
+        API Status: published
+        Args:
+            Unit:str = "Microns"
+        Returns:
+            Contact:Decimal
+            Overtravel:Decimal
+            AlignDist:Decimal
+            SepDist:Decimal
+            SearchGap:Decimal
+        Command Timeout: 5000
+        Example:ReadChuckHeights Y
+        """
+        print("  |-> [ReadChuckHeights] unit %s" % (Unit))
+        #print("  |-> [ReadChuckHeights] unit")
+        #print("  |<- [ReadChuckHeights] return %" % (res))
+        return -20, 0, 0, 0, 0
+
+    @staticmethod
+    def MoveChuck(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+        """
+        Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+        height or higher, Interlock and Auto Z flags will be analyzed and stage will
+        behave correspondingly - can move to separation first or return an error:
+        API Status: published
+        Args:
+            XValue:Decimal = 0
+            YValue:Decimal = 0
+            PosRef:str = "Home"
+            Unit:str = "Microns"
+            Velocity:Decimal = 100
+            Comp:str = "Default"
+        Command Timeout: 30000
+        Example:MoveChuck 5000. 5000. R Y 100
+        """
+        #-uc-# print ("  |-> [MoveChuck] XValue %s, YValue %s, PosRef %s, Unit %s, Velocity %s, Comp %s" % (XValue, YValue, PosRef, Unit, Velocity, Comp))
+        MessageServerInterface.current_chuck_position = {'x': XValue, 'y': YValue, 'z': MessageServerInterface.contact_height}
+
+    @staticmethod
+    def SnapImage(MountPos:str="", FullPath:str="", SnapShotMode:int=""):
+        """
+        Saves the currently displayed image to the specified file. The image is stored
+        in the requested file format (bmp, jpg or png). By default. it will save the raw
+        camera image and an image with the overlays that are currently visible on the
+        camera view. Using a parameter, one can decide to only save either raw image,
+        overlay image or both. By Specifying 'ALL' as the mount position, the captured
+        screenshot will consist of the currently selected camera layout without
+        providing the raw image. If MountPos and FullPath are empty then the current
+        camera view with overlays is copied to the clipboard.
+        API Status: published
+        Args:
+            MountPos:str = "Scope"
+            FullPath:str = "Image.bmp"
+            SnapShotMode:int = 2
+        Command Timeout: 60000
+        Example:SnapImage Scope C:/Temp/Image.bmp
+        """
+        #-uc-# print ("  |-> [SnapImage] MountPos: %s, FullPath %s, SnapShotMode%s" % (MountPos, FullPath, SnapShotMode))
diff --git a/src/FlexSensor/Prober/velox_api/velox/__init__.py b/src/FlexSensor/Prober/velox_api/velox/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..82d8e1f77fd39d9732964623ec949c196623afbb
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/__init__.py
@@ -0,0 +1,9 @@
+
+"""Determines the version of the sci module to import"""
+from sys import version_info
+from Prober.velox_api.velox.vxmessageserver import *
+
+if (version_info[0] > 2 and version_info[1] >= 5):
+    from Prober.velox_api.velox.sci35 import *
+else:
+    from Prober.velox_api.velox.sci27 import *
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/1-SynchronousCommand.py b/src/FlexSensor/Prober/velox_api/velox/samples/1-SynchronousCommand.py
new file mode 100644
index 0000000000000000000000000000000000000000..f4eb99eecf0d2ef248dc343843e894763e5d7763
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/1-SynchronousCommand.py
@@ -0,0 +1,10 @@
+# Demonstrate simple synchronous commands
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+    response = velox.IsAppRegistered('Kernel')
+    if response < 0 :
+        print('Could not register application.')
+
+    x,y,z = velox.ReadChuckPosition("Microns")
+    print(x,y,z)
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/2-AsynchronousCommand.py b/src/FlexSensor/Prober/velox_api/velox/samples/2-AsynchronousCommand.py
new file mode 100644
index 0000000000000000000000000000000000000000..674e47292f2f15491642df41f481c57b63ae79ff
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/2-AsynchronousCommand.py
@@ -0,0 +1,3 @@
+# Asyncronous commands require the user to implement async Python routines
+# There is no special support for asynchronous commands biult in to the 
+# velox Python libraries.
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/3-Notifications.py b/src/FlexSensor/Prober/velox_api/velox/samples/3-Notifications.py
new file mode 100644
index 0000000000000000000000000000000000000000..537df71bfad7233afc12b42c198197b14fb8dc3e
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/3-Notifications.py
@@ -0,0 +1,4 @@
+# There is no support for SCI Notifications in the velox Python 
+# library. If notification handling is required, consider the 
+# C, C++, or C# libraires of the Velox Integration Toolkit.
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/4-CustomCommands.py b/src/FlexSensor/Prober/velox_api/velox/samples/4-CustomCommands.py
new file mode 100644
index 0000000000000000000000000000000000000000..0a612fe5229cea34af9e68e1bc67ddb357933357
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/4-CustomCommands.py
@@ -0,0 +1,26 @@
+# Demonstrate Custom User Commands
+#
+# Custom commands are commands added to the commands.user.txt file.
+# See the Velox Integration Toolkit documentation for details
+#
+# Because custom user commands are not part of the velox Python library,
+# use the generic sendSciCommand of the MessageServer class to send the command.
+#
+# The code below shows two ways to call sendSciCommand: one using the msgServer
+# object from the 'with' statement on the second line of code, and one using the
+# full path velox.MessageServerInterface.sendSciCommand()
+#
+# The parameters are a string containing the name of the command and a string 
+# containing any arguemnts that should be sent to the command.
+# 
+# rsp = msgServer.sendSciCommand('commandName', 'arguments separated by spaces')
+#
+# The example blow does not use a custom command, but demonstrates calling the 
+# echodata test commmd to demonstrate the use os sendSciCommand
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+    rsp = msgServer.sendSciCommand('EchoData', 'Hello')
+    print(rsp)
+    rsp = velox.MessageServerInterface.sendSciCommand('echodata', 'World')
+    print(rsp)
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/5-WaferStepping.py b/src/FlexSensor/Prober/velox_api/velox/samples/5-WaferStepping.py
new file mode 100644
index 0000000000000000000000000000000000000000..794e07a013322ea6b8d15f72fc33efffb719d8b9
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/5-WaferStepping.py
@@ -0,0 +1,38 @@
+# Demonstrate Die Stepping in WaferMap
+
+import velox
+
+def perform_measurement(die):
+    if die.CurSite > 0:
+        print(f'Measure at die <{die[0], die[1]}> subdie {die.CurSite} of {die.LastSiteIndex}')
+    else:
+        print(f'Measure at die <{die[0], die[1]}>')
+
+with velox.MessageServerInterface() as msgServer:
+    try:
+        rsp = velox.IsAppRegistered('Kernel')
+        print('IsAppRegistered Kernel: %s' % rsp)
+
+
+        rsp = velox.StepFirstDie()
+        perform_measurement(rsp)
+
+        while(True):
+            rsp = velox.StepNextDie()
+            perform_measurement(rsp)
+
+        x,y,z = velox.ReadChuckPosition('Y','H', 'D')
+        print('The Chuck is at <%s,%s,%s>'% (x, y, z))
+
+    except velox.SciException as e:
+        if (e.code == '703'):
+            print('Die Stepping Completed')
+        elif e.code == '512':
+            print('There was an error. The error code was %s.' % e.code)
+            print('This may mean that the WaferMAp application is not running.')
+            print('Make sure that the WaferMap application is running and try again.')
+            print(e)
+        else:
+            print('We caught an exception with error code %s as:' % e.code)
+            print(e)
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/6-TesterInterface.py b/src/FlexSensor/Prober/velox_api/velox/samples/6-TesterInterface.py
new file mode 100644
index 0000000000000000000000000000000000000000..03448e3546a50092e476414243278b3be17ef625
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/6-TesterInterface.py
@@ -0,0 +1,3 @@
+# The velox Python library does not support incomming SCI
+# Commands at this time. To implement incomming command functionality, 
+# see the examples for C++ and C# in the Vlox Integration Toolkit.
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/7-TesterControl.py b/src/FlexSensor/Prober/velox_api/velox/samples/7-TesterControl.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c45e935dbe8161e0ba4c068c5eaddf0e05758e4
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/7-TesterControl.py
@@ -0,0 +1 @@
+# There is no specific Python example for Tester Control
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/8-SimpleUIExample.py b/src/FlexSensor/Prober/velox_api/velox/samples/8-SimpleUIExample.py
new file mode 100644
index 0000000000000000000000000000000000000000..537c80d6897058660138fd5f8b0cc38e4837e061
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/8-SimpleUIExample.py
@@ -0,0 +1,3 @@
+# User interface applications in Python often use TKinter 
+# or some other GUI framework. Users should see Python UI 
+# Dccumentstion for examples.
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/SiPTools_test.py b/src/FlexSensor/Prober/velox_api/velox/samples/SiPTools_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..2cfe247894d61359ff5edd41c76e614f95af714c
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/SiPTools_test.py
@@ -0,0 +1,88 @@
+# import velox will choose the correct version of the library 
+# based on the version of Python being executed
+import velox
+import inspect
+
+# import sys for this example, but it is not required for VPI
+import sys
+
+
+
+# print the version of Python that is running, just to see that it is working
+print('Using Python Version ' + sys.version)
+
+# Connect to the message server using a 'with' statement.
+# The application name registered with the Velox Message Server 
+# will be the name of our script. Keep a reference to 
+# the object returned by velox.MessageServerInterface 
+# - in this example, we call it msgServer
+
+# the parameters to MessageServerInterface are optional. 
+# For a local connection, you can leave them blank. If 
+# connecting to a remote machine, add keyword parameters and set the 
+# address and socket
+# velox.MessageServerInterface(ipaddr='localhost',targetSocket=1412)
+
+with velox.MessageServerInterface() as msgServer:
+    # as long as the connection was successful, we can send some commands.
+    # if it was not successful, an exception is thrown.
+
+    
+    # try some SCI Command Examples
+
+    # The SCI commands in the velox module have docstrings to describe 
+    # their function, inputs, and outputs. 
+    # You can print them from a Python command to see what the function does. 
+
+    # print the docstring for the ReportKernelVersion command
+    # ReportKernelVersion returns 2 values. 
+    # here is the description of the command
+    
+    print(velox.ReportKernelVersion.__doc__)
+
+    # SCI commands return a namedtuple if multiple values are returned. 
+    # ReportKernelVersion returns a version number and a description. 
+    # You can acess the return values by name or by indexing the tuple.
+
+    v = velox.ReportKernelVersion()
+    print('The kernel version is', v.Version, 'and', v.Description)
+    print('The kernel version array is', v[0], 'and', v[1])
+
+    # a more convenient example is to unpack the tuple into variables 
+    # as part of the function call.
+    # here we get variables named ver and desc and use them directly
+    ver, desc = velox.ReportKernelVersion()
+    print('Got ', ver, 'and', desc)
+
+    # The Echo Data command just returns its own first input.  
+    # Echo data only returns the first string in the parameter list.
+    # To get a string with spaces to display, we need to add double quotes.
+    # Try it both ways to see the difference. The first one below does 
+    # what we expect. The second only prints the first word. 
+    # The third assigns a return value to a variable
+
+    print(velox.EchoData('"Hi World1"'))
+    
+    print(velox.EchoData("AreaScan(1,1)"))
+    
+    print(velox.EchoData("Hi World2"))
+    evalue = velox.EchoData("Echo_This")
+
+    # ReadChuckPosition returns 3 values. Here we print the entire tuple
+    # to show the tuple name and the names of the 3 return values
+    print(velox.ReadChuckPosition("Microns"))
+    
+    
+    
+    #velox.MoveChuck(-2000,-2000,"Relative")
+
+    # it is possible to send raw command strings with the 
+    # sendSciCommand function.
+    # it isn't recommended, but in some cases, it might be necessary. 
+    # it is much easier and 'safer' to use the defined SCI functions.
+    # note that this is a function of MessageServerInterface, 
+    # not a velox module function
+    
+    print(msgServer.sendSciCommand("echodata", rparams='"RawHello Velox"'))
+
+    print(msgServer.sendSciCommand("SearchFirstLight",rparams='1 0'))
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/__init__.py b/src/FlexSensor/Prober/velox_api/velox/samples/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/velox.tar.gz b/src/FlexSensor/Prober/velox_api/velox/samples/velox.tar.gz
new file mode 100644
index 0000000000000000000000000000000000000000..3d40814fd761e46f15751cca86ef1edfe1e9ebb7
Binary files /dev/null and b/src/FlexSensor/Prober/velox_api/velox/samples/velox.tar.gz differ
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/vpi-ExceptionHandlingSample.py b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-ExceptionHandlingSample.py
new file mode 100644
index 0000000000000000000000000000000000000000..a518b179b579b94a68caad65035c0b49092f8bb9
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-ExceptionHandlingSample.py
@@ -0,0 +1,12 @@
+import velox
+
+with velox.MessageServerInterface() as msgServer:
+  
+    # FindFocus will throw an exception because we aren't properly set up yet.
+    # This is to demonstrate exception handling.
+    try:
+        print(velox.FindFocus())
+    except velox.SciException as e:
+        print('We caught an exception as expected:')
+        print(e)
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/vpi-MinimalSample.py b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-MinimalSample.py
new file mode 100644
index 0000000000000000000000000000000000000000..e7f242892e9e154b7ae8364a6f680d5867b159a4
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-MinimalSample.py
@@ -0,0 +1,9 @@
+import velox
+
+with velox.MessageServerInterface() as msgServer:
+
+    ver, desc = velox.ReportKernelVersion()
+    print('Got ', ver, 'and', desc)
+    x,y,z = velox.ReadChuckPosition("Inches")
+    print(x,y,z)
+
diff --git a/src/FlexSensor/Prober/velox_api/velox/samples/vpi-StartHereSample.py b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-StartHereSample.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0f1bc9227cad4600659da5d8e511846e8698b1e
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/samples/vpi-StartHereSample.py
@@ -0,0 +1,85 @@
+# import velox will choose the correct version of the library 
+# based on the version of Python being executed
+import velox
+
+# import sys for this example, but it is not required for VPI
+import sys
+
+# print the version of Python that is running, just to see that it is working
+print('Using Python Version ' + sys.version)
+
+# Connect to the message server using a 'with' statement.
+# The application name registered with the Velox Message Server 
+# will be the name of our script. Keep a reference to 
+# the object returned by velox.MessageServerInterface 
+# - in this example, we call it msgServer
+
+# the parameters to MessageServerInterface are optional. 
+# For a local connection, you can leave them blank. If 
+# connecting to a remote machine, add keyword parameters and set the 
+# address and socket
+# velox.MessageServerInterface(ipaddr='localhost',targetSocket=1412)
+
+with velox.MessageServerInterface() as msgServer:
+    # as long as the connection was successful, we can send some commands.
+    # if it was not successful, an exception is thrown.
+
+    
+    # try some SCI Command Examples
+
+    # The SCI commands in the velox module have docstrings to describe 
+    # their function, inputs, and outputs. 
+    # You can print them from a Python command to see what the function does. 
+
+    # print the docstring for the ReportKernelVersion command
+    # ReportKernelVersion returns 2 values. 
+    # here is the description of the command
+    
+    print(velox.ReportKernelVersion.__doc__)
+
+    # SCI commands return a namedtuple if multiple values are returned. 
+    # ReportKernelVersion returns a version number and a description. 
+    # You can acess the return values by name or by indexing the tuple.
+
+    v = velox.ReportKernelVersion()
+    print('The kernel version is', v.Version, 'and', v.Description)
+    print('The kernel version array is', v[0], 'and', v[1])
+
+    # a more convenient example is to unpack the tuple into variables 
+    # as part of the function call.
+    # here we get variables named ver and desc and use them directly
+    ver, desc = velox.ReportKernelVersion()
+    print('Got ', ver, 'and', desc)
+
+    # The Echo Data command just returns its own first input.  
+    # Echo data only returns the first string in the parameter list.
+    # To get a string with spaces to display, we need to add double quotes.
+    # Try it both ways to see the difference. The first one below does 
+    # what we expect. The second only prints the first word. 
+    # The third assigns a return value to a variable
+
+    print(velox.EchoData('"Hi World1"'))
+    
+    print(velox.EchoData("AreaScan(1,1)"))
+    
+    print(velox.EchoData("Hi World2"))
+    evalue = velox.EchoData("Echo_This")
+
+    # ReadChuckPosition returns 3 values. Here we print the entire tuple
+    # to show the tuple name and the names of the 3 return values
+    print(velox.ReadChuckPosition("Microns"))
+    
+    
+    
+    velox.MoveChuck(-2000,-2000,"Relative")
+
+    # it is possible to send raw command strings with the 
+    # sendSciCommand function.
+    # it isn't recommended, but in some cases, it might be necessary. 
+    # it is much easier and 'safer' to use the defined SCI functions.
+    # note that this is a function of MessageServerInterface, 
+    # not a velox module function
+    
+    print(msgServer.sendSciCommand("echodata", rparams='"RawHello Velox"'))
+
+    print(msgServer.sendSciCommand("SearchFirstLight",rparams='1 0'))
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/velox_api/velox/sci27.py b/src/FlexSensor/Prober/velox_api/velox/sci27.py
new file mode 100644
index 0000000000000000000000000000000000000000..16dac8e5d5e2643b8a8b4b1e6485bd4c06e97b6d
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/sci27.py
@@ -0,0 +1,11998 @@
+from  velox.vxmessageserver import *
+from decimal import Decimal
+from collections import namedtuple
+
+"""
+Velox SCI Commands
+This module provides a function interface to the Cascade Microtech Velox software suite. 
+The module was auto-generated from the commands.info.xml file on 2019-11-09.  
+737 SCI commands were found and included.
+
+To use this module, your code must import the veloxsci.py module.
+Create a connection to the Velox Message Server using the 'with MessageServerInterface():' 
+command as shown in the sample below.
+
+The Velox Message Server must be running prior to establishing a connection. 
+To start the Message Server, run Velox.
+
+The sample code to use this module is:
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+
+    # Your Code: try some SCI Commands - such as:
+    response = velox.ReportKernelVersion()
+    print ('The kernel version is', response.Version, 'and', response.Description)
+    
+"""
+def EchoData(TestCmd=""):
+    """
+    Test Command for the Kernel Communication. Like a ping command, the given text
+    string is returned unchanged.
+    API Status: published
+    Args:
+        TestCmd:str = "Test"
+    Returns:
+        TestRsp:str
+    Command Timeout: 5000
+    Example:EchoData Test
+    """
+    rsp = MessageServerInterface.sendSciCommand("EchoData",TestCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportKernelVersion(Module=""):
+    """
+    Returns the version information of the kernel or the control box code. The
+    "Version" value contains version number and revision level of the actual Kernel
+    implementation. The text string contains a code description, version number and
+    the revision date.
+    API Status: published
+    Args:
+        Module:str = "K"
+    Returns:
+        Version:Decimal
+        Description:str
+    Command Timeout: 5000
+    Example:ReportKernelVersion K
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReportKernelVersion",Module)
+    global ReportKernelVersion_Response
+    if not "ReportKernelVersion_Response" in globals(): ReportKernelVersion_Response = namedtuple("ReportKernelVersion_Response", "Version,Description")
+    return ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReadProberStatus():
+    """
+    Returns an actual status information of the prober.
+    API Status: published
+    Returns:
+        FlagsBusy:int
+        FlagsContact:int
+        Mode:str
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadProberStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProberStatus")
+    global ReadProberStatus_Response
+    if not "ReadProberStatus_Response" in globals(): ReadProberStatus_Response = namedtuple("ReadProberStatus_Response", "FlagsBusy,FlagsContact,Mode,IsQuiet")
+    return ReadProberStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]))
+
+def EnableMotorQuiet(WantQuietModeOn="", Stage=""):
+    """
+    Toggles the motor power for quiet probing. In most applications this feature is
+    not required. However, for special measurements it may be necessary to reduce
+    the noise of the system. Quiet on turns off the motor power for all stages (or
+    the one specified with the optional parameter). Quiet off will turn on the motor
+    power of all stages (or the one specified with the optional parameter) for
+    subsequent movements. A move command will also turn on the motor power of the
+    moved stage automatically. For automatical switching of the quiet mode refer to
+    Auto Quiet functionality.  Sending 'EnableMotorQuiet 1' will enable the quiet
+    mode for all stages. Sending 'EnableMotorQuiet 1 C' will only enable the quiet
+    mode for the chuck stage. Sending 'EnableMotorQuiet 1 1' will only enable the
+    quiet mode for the Positioner1 stage. Sending 'EnableMotorQuiet 0 S' will only
+    disable the quiet mode for the scope stage.
+    API Status: published
+    Args:
+        WantQuietModeOn:int = 0
+        Stage:str = "None"
+    Command Timeout: 10000
+    Example:EnableMotorQuiet 1
+    """
+    MessageServerInterface.sendSciCommand("EnableMotorQuiet",WantQuietModeOn,Stage)
+
+
+def SetChuckVacuum(WantChuckVacuumOn=""):
+    """
+    Toggles the chuck vacuum on (1) or off (0). Can return vacuum timeout error for
+    stations with wafer vacuum sensors in case no wafer was detected.
+    API Status: published
+    Args:
+        WantChuckVacuumOn:int = 0
+    Command Timeout: 10000
+    Example:SetChuckVacuum 1
+    """
+    MessageServerInterface.sendSciCommand("SetChuckVacuum",WantChuckVacuumOn)
+
+
+def SetMicroLight(WantIlluminatorOn=""):
+    """
+    Toggles the microscope light channel of the peripheral output board and all
+    cameras. Notifications: 7
+    API Status: published
+    Args:
+        WantIlluminatorOn:int = 2
+    Command Timeout: 5000
+    Example:SetMicroLight 1
+    """
+    MessageServerInterface.sendSciCommand("SetMicroLight",WantIlluminatorOn)
+
+
+def SetBeaconStatus(FlagsMode="", PulseWidthRed="", PulseWidthGreen="", PulseWidthYellow="", PulseWidthBlue="", PulseWidthWhite=""):
+    """
+    This command controls the beacon channel of the peripheral output board. All
+    lights can be switched on, off, or blinking. Setting an interval to zero means,
+    that the corresponding light will be statically on or off. The minimum blinking
+    interval is 50ms.
+    API Status: published
+    Args:
+        FlagsMode:int = 0
+        PulseWidthRed:int = 1000
+        PulseWidthGreen:int = 0
+        PulseWidthYellow:int = 0
+        PulseWidthBlue:int = 0
+        PulseWidthWhite:int = 0
+    Command Timeout: 5000
+    Example:SetBeaconStatus 1 1000
+    """
+    MessageServerInterface.sendSciCommand("SetBeaconStatus",FlagsMode,PulseWidthRed,PulseWidthGreen,PulseWidthYellow,PulseWidthBlue,PulseWidthWhite)
+
+
+def SetOutput(Channel="", WantOutputOn="", PulseTime=""):
+    """
+    Controls the Velox output channel signals. It can be used to activate/deactivate
+    outputs.
+    API Status: published
+    Args:
+        Channel:int = 1
+        WantOutputOn:int = 0
+        PulseTime:int = -1
+    Command Timeout: 5000
+    Example:SetOutput 4 0
+    """
+    MessageServerInterface.sendSciCommand("SetOutput",Channel,WantOutputOn,PulseTime)
+
+
+def StopAllMovements():
+    """
+    Stops all Prober movements immediately. The response status value of any pending
+    movement will signify that the stop command was executed.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopAllMovements
+    """
+    MessageServerInterface.sendSciCommand("StopAllMovements")
+
+
+def InkDevice(FlagsInker="", PulseWidth=""):
+    """
+    Inks the current device under test. The range of PulseWidth is 20ms to 2000ms.
+    For correct function, the inkers have to be linked to default outputs.
+    API Status: published
+    Args:
+        FlagsInker:int = 0
+        PulseWidth:int = 50
+    Command Timeout: 10000
+    Example:InkDevice 1 40
+    """
+    MessageServerInterface.sendSciCommand("InkDevice",FlagsInker,PulseWidth)
+
+
+def ReadProbeSetup():
+    """
+    Returns the current positioner configuration.  The output pattern is:  1. Type
+    Positioner 1 2. Type Positioner 2 3. Type Positioner 3 4. Type Positioner 4 5.
+    Type Positioner 5 6. Axis Positioner 1 (Bit 0: XY, Bit 1: Z) 7. Axis Positioner
+    2 (Bit 0: XY, Bit 1: Z) 8. Axis Positioner 3 (Bit 0: XY, Bit 1: Z) 9. Axis
+    Positioner 4 (Bit 0: XY, Bit 1: Z) 10. Axis Positioner 5 (Bit 0: XY, Bit 1: Z)
+    11. Type Positioner 6 12. Axis Positioner 6 (Bit 0: XY, Bit 1: Z)
+    API Status: published
+    Returns:
+        TypePositioner1:int
+        TypePositioner2:int
+        TypePositioner3:int
+        TypePositioner4:int
+        TypePositioner5:int
+        AxisPositioner1:int
+        AxisPositioner2:int
+        AxisPositioner3:int
+        AxisPositioner4:int
+        AxisPositioner5:int
+        TypePositioner6:int
+        AxisPositioner6:int
+    Command Timeout: 5000
+    Example:ReadProbeSetup
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeSetup")
+    global ReadProbeSetup_Response
+    if not "ReadProbeSetup_Response" in globals(): ReadProbeSetup_Response = namedtuple("ReadProbeSetup_Response", "TypePositioner1,TypePositioner2,TypePositioner3,TypePositioner4,TypePositioner5,AxisPositioner1,AxisPositioner2,AxisPositioner3,AxisPositioner4,AxisPositioner5,TypePositioner6,AxisPositioner6")
+    return ReadProbeSetup_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]))
+
+def ReadSystemStatus():
+    """
+    Returns the system options which are currently enabled at the prober.
+    API Status: published
+    Returns:
+        Name:str
+        System:str
+        ChuckXY:int
+        ChuckZ:int
+        ChuckTheta:int
+        ScopeXY:int
+        ScopeZ:int
+        EdgeSensor:int
+        OperationalMode:str
+        Turret:int
+        TemperatureChuck:int
+        AuxSiteCount:int
+        PlatenXY:int
+        PlatenZ:int
+        LoaderGateState:str
+        NucleusType:str
+    Command Timeout: 10000
+    Example:ReadSystemStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSystemStatus")
+    global ReadSystemStatus_Response
+    if not "ReadSystemStatus_Response" in globals(): ReadSystemStatus_Response = namedtuple("ReadSystemStatus_Response", "Name,System,ChuckXY,ChuckZ,ChuckTheta,ScopeXY,ScopeZ,EdgeSensor,OperationalMode,Turret,TemperatureChuck,AuxSiteCount,PlatenXY,PlatenZ,LoaderGateState,NucleusType")
+    return ReadSystemStatus_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),str(rsp[14]),str("" if len(rsp) < 16 else ' '.join(rsp[15:])))
+
+def SetExternalMode(Mode=""):
+    """
+    If 'R' is sent, it sets the external mode of the kernel. This disables most of
+    the control box functions (except the LOCAL function key). Otherwise, this
+    command re-enables all functions of the control box.
+    API Status: published
+    Args:
+        Mode:str = "L"
+    Command Timeout: 5000
+    Example:SetExternalMode L
+    """
+    MessageServerInterface.sendSciCommand("SetExternalMode",Mode)
+
+
+def SetStageLock(Stage="", WantStageLock="", Application=""):
+    """
+    Enables or disables the stage lock functionality. Stages which are locked can't
+    be moved in any way. If the joystick controller is locked, the display and the
+    keys are deactivated. The name of the application can be stored by using the
+    Application Name parameter and is shown in lock-caused error messages.
+    API Status: published
+    Args:
+        Stage:str = "0"
+        WantStageLock:int = 1
+        Application:str = ""
+    Command Timeout: 10000
+    Example:SetStageLock C 0 WaferMap
+    """
+    MessageServerInterface.sendSciCommand("SetStageLock",Stage,WantStageLock,Application)
+
+
+def ReadSensor(Channel="", Type=""):
+    """
+    Returns the actual status of the specified input channel, output channel or edge
+    sensor. The signal table is described in the Hardware Manual. Each used IO-board
+    has 16 channels (max. 4 IO-boards are supported), what results in a domain of 64
+    channel numbers. Beyond this range there are pseudo channels, which are used for
+    special purposes. Pseudo channels:
+    API Status: published
+    Args:
+        Channel:int = 1
+        Type:str = "Input"
+    Returns:
+        IsSensorOn:int
+    Command Timeout: 10000
+    Example:ReadSensor 11 I
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSensor",Channel,Type)
+    return int(rsp[0])
+
+def GetStageLock(Stage=""):
+    """
+    Reads whether stages or joystick controller are locked.
+    API Status: published
+    Args:
+        Stage:str = "0"
+    Returns:
+        Locks:int
+        Application:str
+    Command Timeout: 10000
+    Example:GetStageLock C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetStageLock",Stage)
+    global GetStageLock_Response
+    if not "GetStageLock_Response" in globals(): GetStageLock_Response = namedtuple("GetStageLock_Response", "Locks,Application")
+    return GetStageLock_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetBackSideMode(WantBackSideMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets bottomside mode. In this mode the Z axis is reverse and the
+    command MoveChuckLoad is not allowed.
+    API Status: internal
+    Args:
+        WantBackSideMode:int = 0
+    Command Timeout: 5000
+    Example:SetBackSideMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetBackSideMode",WantBackSideMode)
+
+
+def GetBackSideMode():
+    """
+    Returns the current side mode.
+    API Status: published
+    Returns:
+        IsBackSideModeOn:int
+    Command Timeout: 5000
+    Example:GetBackSideMode
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBackSideMode")
+    return int(rsp[0])
+
+def SetDarkMode(WantSetDarkMode=""):
+    """
+    Switches off all LEDs on the Control Box, on the positioners, and on the screen
+    of the Control Box and also the light of the cameras.
+    API Status: published
+    Args:
+        WantSetDarkMode:int = 0
+    Command Timeout: 5000
+    Example:SetDarkMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetDarkMode",WantSetDarkMode)
+
+
+def GetDarkMode():
+    """
+    Returns the current mode of the light sources.
+    API Status: published
+    Returns:
+        IsDarkMode:int
+    Command Timeout: 5000
+    Example:GetDarkMode
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDarkMode")
+    return int(rsp[0])
+
+def DockChuckCamera(ConnectCamera="", Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Connect or disconnect the chuck camera to the chuck stage. The command is only
+    available for the Prober type PA300BEP.
+    API Status: internal
+    Args:
+        ConnectCamera:str = "ParkPos"
+        Velocity:Decimal = 100
+    Command Timeout: 300000
+    Example:DockChuckCamera P 75
+    """
+    MessageServerInterface.sendSciCommand("DockChuckCamera",ConnectCamera,Velocity)
+
+
+def ReadCBoxStage():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current selected stage of the joystick controller.
+    API Status: internal
+    Returns:
+        Stage:str
+    Command Timeout: 5000
+    Example:ReadCBoxStage
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxStage")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxStage(Stage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current stage of the joystick controller.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Command Timeout: 5000
+    Example:SetCBoxStage C
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxStage",Stage)
+
+
+def ReadCBoxPosMonConf(Stage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current setting of the joystick controllers position monitor for the
+    secified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        PosRef:str
+        Unit:str
+    Command Timeout: 5000
+    Example:ReadCBoxPosMonConf C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxPosMonConf",Stage)
+    global ReadCBoxPosMonConf_Response
+    if not "ReadCBoxPosMonConf_Response" in globals(): ReadCBoxPosMonConf_Response = namedtuple("ReadCBoxPosMonConf_Response", "PosRef,Unit")
+    return ReadCBoxPosMonConf_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetCBoxPosMonConf(Stage="", PosRef="", Unit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Configures the joystick controller position monitor for the secified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetCBoxPosMonConf C Z Y
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxPosMonConf",Stage,PosRef,Unit)
+
+
+def ReadCBoxCurrSpeed(Stage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current speed of the joystick controller for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        CBoxSpeed:str
+    Command Timeout: 5000
+    Example:ReadCBoxCurrSpeed C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxCurrSpeed",Stage)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxCurrSpeed(Stage="", CBoxSpeed=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current speed of the joystick controller for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CBoxSpeed:str = "Speed4"
+    Command Timeout: 5000
+    Example:SetCBoxCurrSpeed C 3
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxCurrSpeed",Stage,CBoxSpeed)
+
+
+def MoveChuckAsync(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck stage to the specified X,Y position without waiting for the move
+    to be finished If chuck Z is in contact height or higher, the chuck will drop to
+    separation.
+    API Status: internal
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 5000
+    Example:MoveChuckAsync 5000. 5000. R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeAsync(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the scope stage to the specified X,Y position without waiting for the move
+    to be finished.
+    API Status: internal
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 5000
+    Example:MoveScopeAsync 5000 5000 R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveProbeAsync(Probe="", XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the probe stage to the specified X,Y position without waiting for the move
+    to be finished.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeAsync",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def ReadChuckStatus():
+    """
+    Returns the current chuck status. Every bit in the bit fields works like a
+    boolean value: One &lt;1&gt; means true/on and zero &lt;0&gt; means false/off.
+    Its counted from LSB to MSB.   - _FlagsInit_: X, Y, Z, Theta - _FlagsMode_:
+    HasOvertravel, HasAutoZ, HasInterlock, ContactSearch, IsContactSet,
+    EdgeInterlock, QuietContact, IsLocked - _FlagsLimit_: XHigh, XLow, YHigh, YLow,
+    ZHigh, ZLow, ThetaHigh, ThetaLow - _FlagsMoving_: X, Y, Z, Theta  All parameters
+    are provided as indirect access (e.g. first bit of M_pvecFlagsInit can be
+    accessed by M_pbIsInitX).
+    API Status: published
+    Returns:
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        IsVacuumOn:int
+        PresetHeight:str
+        LoadPos:str
+        IsLiftDown:int
+        CameraConnection:str
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadChuckStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckStatus")
+    global ReadChuckStatus_Response
+    if not "ReadChuckStatus_Response" in globals(): ReadChuckStatus_Response = namedtuple("ReadChuckStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,IsVacuumOn,PresetHeight,LoadPos,IsLiftDown,CameraConnection,IsQuiet")
+    return ReadChuckStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),int(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),str(rsp[9]),int(rsp[10]))
+
+def ReadChuckPosition(Unit="", PosRef="", Comp=""):
+    """
+    Returns the current chuck stage position in X, Y and Z.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckPosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckPosition",Unit,PosRef,Comp)
+    global ReadChuckPosition_Response
+    if not "ReadChuckPosition_Response" in globals(): ReadChuckPosition_Response = namedtuple("ReadChuckPosition_Response", "X,Y,Z")
+    return ReadChuckPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadChuckHeights(Unit=""):
+    """
+    Returns the current settings used for the chuck Z movement. `Contact` is the
+    contact-height from zero in default compensation. The other heights are relative
+    to this. If no contact is set, the value will be -1.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+        SearchGap:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckHeights",Unit)
+    global ReadChuckHeights_Response
+    if not "ReadChuckHeights_Response" in globals(): ReadChuckHeights_Response = namedtuple("ReadChuckHeights_Response", "Contact,Overtravel,AlignDist,SepDist,SearchGap")
+    return ReadChuckHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def InitChuck(FlagsInit="", FlagsDirection="", FlagsMoveRange=""):
+    """
+    Machine Coordinate System: Chuck X Y Z Theta  - _FlagsInit_: X, Y, Z, Theta -
+    _FlagsDirection_: X, Y, Z, Theta (true means plus direction) - _FlagsMoveRange_:
+    X, Y, Z, Theta   All flags can be accessed by indirect members.  Initializes the
+    chuck stage and resets current coordinate system. Should be used only in cases
+    when the reported coordinates do not correspond to real position of mechanics.
+    Find Move Range starts the initialization in the defined direction and then
+    moves to the other limit and finds the whole range of the axes.
+    API Status: published
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 150000
+    Example:InitChuck 7 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitChuck",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveChuck(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+    height or higher, Interlock and Auto Z flags will be analyzed and stage will
+    behave correspondingly - can move to separation first or return an error:
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 30000
+    Example:MoveChuck 5000. 5000. R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuck",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveChuckIndex(XSteps="", YSteps="", PosRef="", Velocity=""):
+    """
+    Moves the chuck stage in index steps. This command modifies Die Home Position.
+    API Status: published
+    Args:
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckIndex 1 1 R 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveChuckSubsite(XValue="", YValue="", Unit="", Velocity=""):
+    """
+    Moves the chuck stage to the specified X, Y sub-site position. Die home position
+    is defined by destination position of last successful MoveChuck or
+    MoveChuckIndex commands. MoveChuckVelocity does not touch die home position. If
+    you have moved chuck with MoveChuckVelocity, "MoveChuckSubsite 0 0" will move it
+    back to die home position.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckSubsite 200 200 Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckSubsite",XValue,YValue,Unit,Velocity)
+
+
+def MoveChuckContact(Velocity=""):
+    """
+    Performs a movement of chuck Z axis to preset contact height or will return
+    error if no contact height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckContact 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckContact",Velocity)
+
+
+def MoveChuckAlign(Velocity=""):
+    """
+    Moves the chuck Z axis to the align height. If no Contact height is set will
+    return an error.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckAlign",Velocity)
+
+
+def MoveChuckSeparation(Velocity=""):
+    """
+    Moves the chuck Z axis to the separation height. Returns error if no Contact
+    height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckSeparation",Velocity)
+
+
+def MoveChuckLoad(LoadPosition=""):
+    """
+    Moves the Chuck stage in X, Y, Z and Theta to the load position.
+    API Status: published
+    Args:
+        LoadPosition:str = "First"
+    Command Timeout: 60000
+    Example:MoveChuckLoad 0
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckLoad",LoadPosition)
+
+
+def MoveChuckZ(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves the chuck Z axis to the specified height. If contact is set, only moves up
+    to contact height will be allowed. If overtravel is enabled - up to overtravel
+    height.
+    API Status: published
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 60000
+    Example:MoveChuckZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SearchChuckContact(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves the chuck Z axis to the specified height and sets contact. The move stops
+    immediately if the Contact Sensor ( Edge Sensor) is triggered. If no contact has
+    been found and an old one was set before the old contact will not get lost, it
+    will be reset.
+    API Status: published
+    Args:
+        Height:Decimal = 100
+        PosRef:str = "Relative"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ContactHeight:Decimal
+    Command Timeout: 60000
+    Example:SearchChuckContact 1000 R Y 10
+    """
+    rsp = MessageServerInterface.sendSciCommand("SearchChuckContact",Height,PosRef,Unit,Velocity,Comp)
+    return Decimal(rsp[0])
+
+def MoveChuckVelocity(PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+    """
+    Moves the chuck stage in velocity mode. The motion continues until the
+    StopChuckMovement command is received, or the end limit is reached.
+    API Status: published
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 30000
+    Example:MoveChuckVelocity + + 0 100 30 0
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopChuckMovement(FlagsStop=""):
+    """
+    Stops chuck movement for the given axis. Notifications: 31 / 32 / 5
+    API Status: published
+    Args:
+        FlagsStop:int = 15
+    Command Timeout: 5000
+    Example:StopChuckMovement 7
+    """
+    MessageServerInterface.sendSciCommand("StopChuckMovement",FlagsStop)
+
+
+def SetChuckMode(Overtravel="", AutoZ="", Interlock="", ContactSearch="", EdgeInterlock="", QuietContact=""):
+    """
+    Mode manages the way the chuck behaves when it is in contact height. Chuck mode
+    is made from 6 flags and you can control all of them using this command. Every
+    flag can be turned on by using value 1 or turned off by using value 0. If you do
+    not want to change a flag - use value of 2.
+    API Status: published
+    Args:
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        ContactSearch:int = 2
+        EdgeInterlock:int = 2
+        QuietContact:int = 2
+    Command Timeout: 5000
+    Example:SetChuckMode 2 2 2 2 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetChuckMode",Overtravel,AutoZ,Interlock,ContactSearch,EdgeInterlock,QuietContact)
+
+
+def SetChuckHome(Mode="", Unit="", XValue="", YValue=""):
+    """
+    Sets wafer and die home position, which can be used later as coordinate system
+    for movements.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckHome 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetChuckHome",Mode,Unit,XValue,YValue)
+
+
+def SetChuckIndex(XValue="", YValue="", Unit=""):
+    """
+    Sets the wafer index size. Normally the size of one die.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetChuckIndex 5000. 5000. Y
+    """
+    MessageServerInterface.sendSciCommand("SetChuckIndex",XValue,YValue,Unit)
+
+
+def SetChuckHeight(PresetHeight="", Mode="", Unit="", Value=""):
+    """
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align and separation. A predefined contact search gap is able to write. No data
+    in the optional parameters sets contact height at current position. If Mode is
+    '0', contact height can be set at current position. The levels O, A, S and T
+    support no Mode '0'. If Mode is 'V' and no value for height is specified -
+    default 0 will be used, what potentially can be not what you expect. If Mode is
+    'R', contact height can be invalidated. The levels O, A, S and T support no Mode
+    'R'.
+    API Status: published
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckHeight C V Y 5000.
+    """
+    MessageServerInterface.sendSciCommand("SetChuckHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadChuckIndex(Unit=""):
+    """
+    The command gets the current die size which is stored in the kernel.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckIndex Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckIndex",Unit)
+    global ReadChuckIndex_Response
+    if not "ReadChuckIndex_Response" in globals(): ReadChuckIndex_Response = namedtuple("ReadChuckIndex_Response", "IndexX,IndexY")
+    return ReadChuckIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveChuckTransfer():
+    """
+    Moves the Chuck to the Transfer Position. If the movement starts in Load
+    Position (where it's possible to pull out the chuck) the handling of the Add On
+    Platen or the Pin Chuck is integrated.
+    API Status: published
+    Command Timeout: 90000
+    Example:MoveChuckTransfer
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckTransfer")
+
+
+def MoveChuckLift(SetLift=""):
+    """
+    Moves the chuck to the upper (0) or lower = lifted (1) position. This initiates
+    motion only, the actual movement may take some seconds.
+    API Status: published
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MoveChuckLift 1
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckLift",SetLift)
+
+
+def SetChuckThermoScale(ScaleX="", ScaleY=""):
+    """
+    Thermo drifts of the wafer will be compensated. The compensation is not
+    persistent, (power off - this compensation is deleted). The algorithm works as
+    an additional one.  This is for an iterative usage, so:  1. `ResetProber H` 2.
+    `SetChuckThermoScale 1.5 1.5` 3. `SetChuckThermoScale 1.5 1.5`  will result in a
+    scale of 2.25 in both directions. The thermal scale can also be reset using the
+    command 'SetChcukThermoValue 20 C'
+    API Status: published
+    Args:
+        ScaleX:Decimal = 1
+        ScaleY:Decimal = 1
+    Command Timeout: 5000
+    Example:SetChuckThermoScale 1.000005 1.0000045
+    """
+    MessageServerInterface.sendSciCommand("SetChuckThermoScale",ScaleX,ScaleY)
+
+
+def ReadChuckThermoScale():
+    """
+    Read the linear scaling value of the chuck.
+    API Status: published
+    Returns:
+        ScaleX:Decimal
+        ScaleY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckThermoScale
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoScale")
+    global ReadChuckThermoScale_Response
+    if not "ReadChuckThermoScale_Response" in globals(): ReadChuckThermoScale_Response = namedtuple("ReadChuckThermoScale_Response", "ScaleX,ScaleY")
+    return ReadChuckThermoScale_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetChuckThermoValue(Temperature="", Unit="", ExpCoeffX="", ExpCoeffY=""):
+    """
+    Set a temperature and optional the expansion coefficient. The temperature for
+    normal level is 20 degree. The scaling factor at this temperature is 1.0. If you
+    set the temperature directly the controller calculates the stage difference in
+    the coordinate system. For the calculation use the set coefficient of expansion
+    from the controller. The default coefficient of expansion is based on silicon:
+    2.33E-06 1/K.
+    API Status: published
+    Args:
+        Temperature:Decimal = 0
+        Unit:str = "Celsius"
+        ExpCoeffX:Decimal = 0
+        ExpCoeffY:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckThermoValue 250 C 2.43 2.32
+    """
+    MessageServerInterface.sendSciCommand("SetChuckThermoValue",Temperature,Unit,ExpCoeffX,ExpCoeffY)
+
+
+def ReadChuckThermoValue(Unit=""):
+    """
+    Read the current temperature (either set or calculated) for the thermal scaling.
+    With SetChuckThermoScale in use, the value will be calculated by the current
+    scale and the expansion factor of silicium. The temperature that is read with
+    this command is not identical to the current chuck temperature.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        Temperature:Decimal
+        ExpCoeffX:Decimal
+        ExpCoeffY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckThermoValue C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoValue",Unit)
+    global ReadChuckThermoValue_Response
+    if not "ReadChuckThermoValue_Response" in globals(): ReadChuckThermoValue_Response = namedtuple("ReadChuckThermoValue_Response", "Temperature,ExpCoeffX,ExpCoeffY")
+    return ReadChuckThermoValue_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetChuckTableID(TableName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return the TableID Number of the stored chuck table or create a new table. The
+    ID Number is unique for the name and the chuck. The table itself has a string
+    name, this name is not case sensitive. This command has to be used before all
+    other table commands can be used. Accesses to the table is possible only with an
+    ID Number (name dependet).
+    API Status: internal
+    Args:
+        TableName:str = "ChuckTable"
+    Returns:
+        TableID:int
+    Command Timeout: 5000
+    Example:GetChuckTableID ChuckTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetChuckTableID",TableName)
+    return int(rsp[0])
+
+def MoveChuckTablePoint(TableID="", PointID="", Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move the chuck to the next stored table site.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckTablePoint 3 10 67
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckTablePoint",TableID,PointID,Velocity)
+
+
+def ReadChuckTablePoint(TableID="", PointID="", Unit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read back the table site information for this point from the Kernel.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadChuckTablePoint 10 250 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckTablePoint",TableID,PointID,Unit)
+    global ReadChuckTablePoint_Response
+    if not "ReadChuckTablePoint_Response" in globals(): ReadChuckTablePoint_Response = namedtuple("ReadChuckTablePoint_Response", "CoordX,CoordY,CoordSystem")
+    return ReadChuckTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetChuckTablePoint(TableID="", PointID="", CoordX="", CoordY="", Unit="", CoordSystem=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set one point of the chuck table inside of the Kernel. If there is still a point
+    with this index loaded, the Kernel returns an error. Number of positions and
+    number of tables are dependet on the internal memory. All positions are stored
+    persistent, that means after switching power on or off the positions are still
+    available. The table starts with point number 1 and ends with the ID 16. The
+    table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetChuckTablePoint 10 12000.0 2344.0 Y F
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetChuckTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    return int(rsp[0])
+
+def ClearChuckTablePoint(TableID="", StartPoint="", EndPoint=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of chuck table site points in the in the Kernel. If Start
+    Point is -1 or negative the whole table will be deleted.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearChuckTablePoint 5 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearChuckTablePoint",TableID,StartPoint,EndPoint)
+    global ClearChuckTablePoint_Response
+    if not "ClearChuckTablePoint_Response" in globals(): ClearChuckTablePoint_Response = namedtuple("ClearChuckTablePoint_Response", "ClearNumber,ValidNumber")
+    return ClearChuckTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def AttachAmbientWafer(MoveTimeMs=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is moved to slowly attach a wafer that is at ambient temperature while
+    the chuck is hot.     The command acts similar to MoveChuckTransfer when moving
+    out of Load 2 but will use a much slower Z velocity.     This is only supported
+    for BnR-machines (CM300 and Summit200) at the moment.
+    API Status: internal
+    Args:
+        MoveTimeMs:Decimal = 30000
+    Command Timeout: 300000
+    Example:AttachAmbientWafer
+    """
+    MessageServerInterface.sendSciCommand("AttachAmbientWafer",MoveTimeMs)
+
+
+def ReadThetaStatus():
+    """
+    Returns the actual status of the chuck Theta axis.
+    API Status: published
+    Returns:
+        IsInit:int
+        FlagsLimit:int
+        IsMoving:int
+    Command Timeout: 5000
+    Example:ReadThetaStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadThetaStatus")
+    global ReadThetaStatus_Response
+    if not "ReadThetaStatus_Response" in globals(): ReadThetaStatus_Response = namedtuple("ReadThetaStatus_Response", "IsInit,FlagsLimit,IsMoving")
+    return ReadThetaStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadThetaPosition(Unit="", PosRef=""):
+    """
+    Returns the actual Theta position.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+        PosRef:str = "Home"
+    Returns:
+        Position:Decimal
+    Command Timeout: 5000
+    Example:ReadThetaPosition D Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadThetaPosition",Unit,PosRef)
+    return Decimal(rsp[0])
+
+def InitTheta(FlagsDoPlus="", FlagsMoveRange=""):
+    """
+    Performs an initialization move and resets the coordinate system of the Theta
+    axis.
+    API Status: published
+    Args:
+        FlagsDoPlus:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 120000
+    Example:InitTheta 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitTheta",FlagsDoPlus,FlagsMoveRange)
+
+
+def MoveTheta(Position="", PosRef="", Unit="", Velocity=""):
+    """
+    Moves the chuck Theta axis to the specified position. The positive direction is
+    counter-clockwise.
+    API Status: published
+    Args:
+        Position:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Degrees"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveTheta 1000. R E
+    """
+    MessageServerInterface.sendSciCommand("MoveTheta",Position,PosRef,Unit,Velocity)
+
+
+def MoveThetaVelocity(Polarity="", Velocity=""):
+    """
+    Moves the chuck Theta axis in velocity mode. The positive direction is counter-
+    clockwise. The motion continues until the StopThetaMovement command is received,
+    or the end limit (error condition) is reached. This command is mostly used for
+    joystick movements that do not have a target destination.
+    API Status: published
+    Args:
+        Polarity:str = "Fixed"
+        Velocity:Decimal = 0
+    Command Timeout: 240000
+    Example:MoveThetaVelocity + 67
+    """
+    MessageServerInterface.sendSciCommand("MoveThetaVelocity",Polarity,Velocity)
+
+
+def StopThetaMovement():
+    """
+    Stops any type (velocity, position etc.) of chuck Theta axis movement. This is
+    treated as a smooth stop rather than an emergency stop.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopThetaMovement
+    """
+    MessageServerInterface.sendSciCommand("StopThetaMovement")
+
+
+def SetThetaHome(Mode="", Unit="", Position=""):
+    """
+    Sets the chuck Theta position to home. This position is usable as reference
+    position for other commands.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Degrees"
+        Position:Decimal = 0
+    Command Timeout: 5000
+    Example:SetThetaHome 0
+    """
+    MessageServerInterface.sendSciCommand("SetThetaHome",Mode,Unit,Position)
+
+
+def ScanChuckZ(ZDistance="", TriggerEveryNthCycle="", Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts moving the chuck from the current position with Velocity [%] over
+    ZDistance (sign is important, as a negative sign will move chuck down during
+    scan) - Predefined camera trigger pulses (TTL active high for at least 5us) will
+    be sent during the scan every passed number of BnR cyclics (800us per cyclic)
+    until the ZDistance has been reached.  Command returns number of positions and
+    all compensated Z Positions from Zero, where the trigger was sent.
+    API Status: internal
+    Args:
+        ZDistance:Decimal = 1000
+        TriggerEveryNthCycle:int = 3
+        Velocity:Decimal = 10
+    Returns:
+        NumberOfPositions:int
+        TriggerPositions:str
+    Command Timeout: 60000
+    Example:ScanChuckZ 300 3 1.5
+    """
+    rsp = MessageServerInterface.sendSciCommand("ScanChuckZ",ZDistance,TriggerEveryNthCycle,Velocity)
+    global ScanChuckZ_Response
+    if not "ScanChuckZ_Response" in globals(): ScanChuckZ_Response = namedtuple("ScanChuckZ_Response", "NumberOfPositions,TriggerPositions")
+    return ScanChuckZ_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def MoveChuckZSafe():
+    """
+    Moves the chuck Z axis to a z height considered safe. This is either the lower
+    Z-Fence or the kernel setup item Chuck:SafeTransferHeight (which ever is larger)
+    API Status: published
+    Command Timeout: 60000
+    Example:MoveChuckZSafe
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckZSafe")
+
+
+def SetPlatenMode(Overtravel="", AutoZ="", Interlock="", AutoZFollow="", AutoQuiet=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The mode manages the way the platen behaves when it is in contact height. Platen
+    mode is made up from 5 flags and the user can control all of them by using this
+    command. Every flag can be turned on by setting value 1 or turned off by setting
+    value 0. If no change for a flag is wanted, use the value of 2.
+    API Status: internal
+    Args:
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        AutoZFollow:int = 2
+        AutoQuiet:int = 2
+    Command Timeout: 5000
+    Example:SetPlatenMode 2 2 2 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetPlatenMode",Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+
+
+def MovePlatenLift(SetLift=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen to the high (0) or low = lifted (1) position. This initiates
+    motion; the actual movement may take some seconds.
+    API Status: internal
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MovePlatenLift 1
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenLift",SetLift)
+
+
+def SearchPlatenContact(Height="", PosRef="", Unit="", Velocity="", CompLayer=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Searches contact height using the edge sensor using a z movement of the platen
+    stage
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        CompLayer:str = "Default"
+    Returns:
+        ContactHeight:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SearchPlatenContact",Height,PosRef,Unit,Velocity,CompLayer)
+    return Decimal(rsp[0])
+
+def ReadPlatenStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current platen status.
+    API Status: internal
+    Returns:
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        PresetHeight:str
+        IsLiftDown:int
+    Command Timeout: 10000
+    Example:ReadPlatenStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenStatus")
+    global ReadPlatenStatus_Response
+    if not "ReadPlatenStatus_Response" in globals(): ReadPlatenStatus_Response = namedtuple("ReadPlatenStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,PresetHeight,IsLiftDown")
+    return ReadPlatenStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ReadPlatenPosition(Unit="", PosRef="", Comp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the platens X, Y and Z axes. The default
+    compensation is the currently selected compensation for the stage.
+    API Status: internal
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 10000
+    Example:ReadPlatenPosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenPosition",Unit,PosRef,Comp)
+    global ReadPlatenPosition_Response
+    if not "ReadPlatenPosition_Response" in globals(): ReadPlatenPosition_Response = namedtuple("ReadPlatenPosition_Response", "X,Y,Z")
+    return ReadPlatenPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadPlatenHeights(Unit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual settings for the probe Z movement.
+    API Status: internal
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 10000
+    Example:ReadPlatenHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenHeights",Unit)
+    global ReadPlatenHeights_Response
+    if not "ReadPlatenHeights_Response" in globals(): ReadPlatenHeights_Response = namedtuple("ReadPlatenHeights_Response", "Contact,Overtravel,AlignDist,SepDist")
+    return ReadPlatenHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def InitPlaten(FlagsInit="", FlagsDirection="", FlagsMoveRange=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initializes the platens X, Y and Z axes. Currently the initialization in
+    negative direction and the move range scan are not supported.
+    API Status: internal
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 120000
+    Example:InitPlaten 4
+    """
+    MessageServerInterface.sendSciCommand("InitPlaten",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MovePlatenZ(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the specified height. If contact is set, only moves
+    up to contact height will be allowed. If overtravel is enabled - up to
+    overtravel height.
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 30000
+    Example:MovePlatenZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def MovePlatenContact(Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a movement of platen Z axis to preset contact height or returns an
+    error, if no contact height is set.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenContact 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenContact",Velocity)
+
+
+def MovePlatenAlign(Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the align height. If no contact height is set, the
+    command will return an error.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenAlign",Velocity)
+
+
+def MovePlatenSeparation(Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the separation height. If no contact height is set,
+    the command will return an error.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenSeparation",Velocity)
+
+
+def MovePlatenVelocity(PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen stage in velocity mode. The motion continues until the
+    StopPlatenMovement command is received, or the software fence is reached.
+    API Status: internal
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 240000
+    Example:MovePlatenVelocity + + 0 67 50 0
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopPlatenMovement(FlagsStop=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the movement of a set of platen axes immediately.
+    API Status: internal
+    Args:
+        FlagsStop:int = 7
+    Command Timeout: 10000
+    Example:StopPlatenMovement 4
+    """
+    MessageServerInterface.sendSciCommand("StopPlatenMovement",FlagsStop)
+
+
+def SetPlatenHeight(PresetHeight="", Mode="", Unit="", Value=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align and separation height. A command without data sets contact height at
+    current position.
+    API Status: internal
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 10000
+    Example:SetPlatenHeight C V Y 5000
+    """
+    MessageServerInterface.sendSciCommand("SetPlatenHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadManualPlatenState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads the current status of the manual platen. THis is only supported for
+    Nucleus and Summit200.
+    API Status: internal
+    Returns:
+        IsUp:int
+        IsDown:int
+        IsSafe:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadManualPlatenState")
+    global ReadManualPlatenState_Response
+    if not "ReadManualPlatenState_Response" in globals(): ReadManualPlatenState_Response = namedtuple("ReadManualPlatenState_Response", "IsUp,IsDown,IsSafe")
+    return ReadManualPlatenState_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadScopeStatus():
+    """
+    Returns the current scope status.
+    API Status: published
+    Returns:
+        FlagsInit:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        IsScopeLiftUp:int
+        PresetHeight:str
+        IsScopeLight:int
+        FlagsMode:int
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadScopeStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeStatus")
+    global ReadScopeStatus_Response
+    if not "ReadScopeStatus_Response" in globals(): ReadScopeStatus_Response = namedtuple("ReadScopeStatus_Response", "FlagsInit,FlagsLimit,FlagsMoving,Comp,IsScopeLiftUp,PresetHeight,IsScopeLight,FlagsMode,IsQuiet")
+    return ReadScopeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),str(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def ReadScopePosition(Unit="", PosRef="", Comp=""):
+    """
+    Returns the actual scope stage position in X, Y and Z. The default Compensation
+    Mode is the currently activated compensation mode of the kernel.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadScopePosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopePosition",Unit,PosRef,Comp)
+    global ReadScopePosition_Response
+    if not "ReadScopePosition_Response" in globals(): ReadScopePosition_Response = namedtuple("ReadScopePosition_Response", "X,Y,Z")
+    return ReadScopePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeHeights(Unit=""):
+    """
+    Returns the actual settings of the focus height, align gap, and separation gap
+    for the scope Z axis.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        FocusHeight:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeHeights",Unit)
+    global ReadScopeHeights_Response
+    if not "ReadScopeHeights_Response" in globals(): ReadScopeHeights_Response = namedtuple("ReadScopeHeights_Response", "FocusHeight,AlignDist,SepDist")
+    return ReadScopeHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def InitScope(FlagsInit="", FlagsDirection="", FlagsMoveRange=""):
+    """
+    Initializes the microscope stage in X, Y and Z. The Axis default is all axes and
+    the Direction default is XY in minus and Z in plus. Should be used only in cases
+    when the reported coordinates do not correspond to real position of mechanics.
+    Find Move Range starts the initialization in the defined direction and then
+    moves to the other limit and finds the whole range of the axes.
+    API Status: published
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 240000
+    Example:InitScope 3 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitScope",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveScope(XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 70000
+    Example:MoveScope 5000 5000 R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScope",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeIndex(XSteps="", YSteps="", PosRef="", Velocity=""):
+    """
+    Moves the microscope stage in index steps. If no PositionReference byte is
+    passed the scope will step relative to the wafer home position. ('R' means the
+    step relative to current position).
+    API Status: published
+    Args:
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveScopeIndex 1 1 R 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveScopeZ(Height="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves the microscope Z axis to the specified height. Default velocity is 100%.
+    API Status: published
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 120000
+    Example:MoveScopeZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SetScopeMode(QuietMode="", FollowMode=""):
+    """
+    Scope mode is made up of two flags which can be controlled using this command.
+    Each flag can be turned on by using value 1 or turned off by using value 0. If
+    you do not want to change a flag, use value of 2.
+    API Status: published
+    Args:
+        QuietMode:int = 2
+        FollowMode:int = 2
+    Command Timeout: 5000
+    Example:SetScopeMode 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetScopeMode",QuietMode,FollowMode)
+
+
+def MoveScopeVelocity(PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+    """
+    Moves the microscope stage in velocity mode. The motion continues until the
+    StopScopeMovement command is received, or the end limit (error condition) is
+    reached. Axes parameter: '+' move this axis in plus direction '-' move this axis
+    in minus direction '0' Do not change this axis
+    API Status: published
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 30000
+    Example:MoveScopeVelocity + + 0 67 100 0
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopScopeMovement(FlagsStop=""):
+    """
+    Stops scope movement for the given axis. A smooth stop is executed, no emergency
+    stop.
+    API Status: published
+    Args:
+        FlagsStop:int = 7
+    Command Timeout: 5000
+    Example:StopScopeMovement 7
+    """
+    MessageServerInterface.sendSciCommand("StopScopeMovement",FlagsStop)
+
+
+def SetScopeHome(Mode="", Unit="", XValue="", YValue=""):
+    """
+    Sets the scope Home position in X and Y. It identifies the scope coordinate
+    system for later movements. Usually this position is identical to the die home
+    location.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeHome 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeHome",Mode,Unit,XValue,YValue)
+
+
+def SetScopeIndex(XValue="", YValue="", Unit=""):
+    """
+    Sets the microscope index size. Normally set in relation to the wafer index
+    size.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetScopeIndex 5000. 5000. Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeIndex",XValue,YValue,Unit)
+
+
+def SetScopeHeight(PresetHeight="", Mode="", Unit="", Value=""):
+    """
+    This command defines scope focus height and the corresponding gaps for alignment
+    or separation. No data sets focus height at current position.
+    API Status: published
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeHeight F 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadScopeIndex(Unit=""):
+    """
+    Returns the actual scope stage index values in X and Y.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeIndex Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeIndex",Unit)
+    global ReadScopeIndex_Response
+    if not "ReadScopeIndex_Response" in globals(): ReadScopeIndex_Response = namedtuple("ReadScopeIndex_Response", "IndexX,IndexY")
+    return ReadScopeIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveScopeFocus(Velocity=""):
+    """
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 25000
+    Example:MoveScopeFocus 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeFocus",Velocity)
+
+
+def MoveScopeAlign(Velocity=""):
+    """
+    Moves the Scope Z axis to the alignment height. If no focus height is set an
+    error will bereturned.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 10000
+    Example:MoveScopeAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeAlign",Velocity)
+
+
+def MoveScopeSeparation(Velocity=""):
+    """
+    Moves the scope Z axis to the separation height. Returns an error if no focus
+    height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveScopeSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeSeparation",Velocity)
+
+
+def MoveScopeLift(SetLift=""):
+    """
+    Moves the microscope lift to the lower (0) or upper = lifted (1) position. This
+    initiates the motion only, the actual movement may take some seconds.
+    API Status: published
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MoveScopeLift 1
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeLift",SetLift)
+
+
+def ReadTurretStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current status of the motorized turret.
+    API Status: internal
+    Returns:
+        IsMoving:int
+    Command Timeout: 5000
+    Example:ReadTurretStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTurretStatus")
+    return int(rsp[0])
+
+def SelectLens(Lens=""):
+    """
+    Parfocality and para-centricity are adjusted according to the stored values.
+    This can be used with manual turrets to compensate for XYZ differences between
+    lenses.
+    API Status: published
+    Args:
+        Lens:int = 1
+    Command Timeout: 30000
+    Example:SelectLens 1
+    """
+    MessageServerInterface.sendSciCommand("SelectLens",Lens)
+
+
+def GetScopeTable(TableName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return the TableID Number of the stored chuck table or create a new table. The
+    ID Number is unique for the name and the chuck. The table itself has a string
+    name, this name is not case sensitive. This command has to be used before all
+    other table commands can be used. Accesses to the table is possible only with an
+    ID Number (name dependet).
+    API Status: internal
+    Args:
+        TableName:str = "ScopeTable"
+    Returns:
+        TableID:int
+    Command Timeout: 5000
+    Example:GetScopeTable ScopeTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetScopeTable",TableName)
+    return int(rsp[0])
+
+def MoveScopeTablePoint(TableID="", PointID="", Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveScopeTablePoint 10 5 67
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeTablePoint",TableID,PointID,Velocity)
+
+
+def ReadScopeTablePoint(TableID="", PointID="", Unit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read back the scope table site Information for this point from the Kernel.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadScopeTablePoint 2 10 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeTablePoint",TableID,PointID,Unit)
+    global ReadScopeTablePoint_Response
+    if not "ReadScopeTablePoint_Response" in globals(): ReadScopeTablePoint_Response = namedtuple("ReadScopeTablePoint_Response", "CoordX,CoordY,CoordSystem")
+    return ReadScopeTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def ReadCurrentLens():
+    """
+    Returns the number of the current microscope lens.
+    API Status: published
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    Example:ReadCurrentLens
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCurrentLens")
+    return int(rsp[0])
+
+def SetScopeTablePoint(TableID="", PointID="", CoordX="", CoordY="", Unit="", CoordSystem=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set one point of the scope table inside of the Kernel. If there is still a point
+    with this index loaded, the Kernel returns an error. Number of positions and
+    number of tables are dependet on the internal memory. All positions are stored
+    persistent, that means after switching power on or off the positions are still
+    available. The table starts with point number 1 and ends with the ID 16. The
+    table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetScopeTablePoint 10 10 8992.5 7883.0 Y H
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetScopeTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    return int(rsp[0])
+
+def ClearScopeTablePoint(TableID="", StartPoint="", EndPoint=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of scope table site points in the Kernel. If Start Point is
+    -1 or negative the whole table will be deleted.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearScopeTablePoint 2 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearScopeTablePoint",TableID,StartPoint,EndPoint)
+    global ClearScopeTablePoint_Response
+    if not "ClearScopeTablePoint_Response" in globals(): ClearScopeTablePoint_Response = namedtuple("ClearScopeTablePoint_Response", "ClearNumber,ValidNumber")
+    return ClearScopeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadScopeSiloCount():
+    """
+    Returns the number of silos in the scope fence. Will be zero if no silos are
+    configured.
+    API Status: published
+    Returns:
+        Count:int
+    Command Timeout: 5000
+    Example:ReadScopeSiloCount
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSiloCount")
+    return int(rsp[0])
+
+def ReadProbeStatus(Probe=""):
+    """
+    Returns the current positioner's status.
+    API Status: published
+    Args:
+        Probe:int = 1
+    Returns:
+        ProbeEcho:int
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        Side:str
+        PresetHeight:str
+        IsLiftUp:int
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadProbeStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeStatus",Probe)
+    global ReadProbeStatus_Response
+    if not "ReadProbeStatus_Response" in globals(): ReadProbeStatus_Response = namedtuple("ReadProbeStatus_Response", "ProbeEcho,FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,Side,PresetHeight,IsLiftUp,IsQuiet")
+    return ReadProbeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadProbePosition(Probe="", Unit="", PosRef="", Comp=""):
+    """
+    Returns the actual positioner's position in X, Y and Z. The default Compensation
+    Mode is the currently activated compensation mode of the kernel.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadProbePosition 1 Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbePosition",Probe,Unit,PosRef,Comp)
+    global ReadProbePosition_Response
+    if not "ReadProbePosition_Response" in globals(): ReadProbePosition_Response = namedtuple("ReadProbePosition_Response", "ProbeEcho,X,Y,Z")
+    return ReadProbePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadProbeHeights(Probe="", Unit=""):
+    """
+    Returns the actual settings for the probe Z movement.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeHeights 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeHeights",Probe,Unit)
+    global ReadProbeHeights_Response
+    if not "ReadProbeHeights_Response" in globals(): ReadProbeHeights_Response = namedtuple("ReadProbeHeights_Response", "ProbeEcho,Contact,Overtravel,AlignDist,SepDist")
+    return ReadProbeHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def OrientProbe(Probe="", Side=""):
+    """
+    Defines the orientation of the positioner's coordinate system and turns the
+    Y-axis of the probe coordinate system.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Side:str = "Left"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:OrientProbe 1 R
+    """
+    rsp = MessageServerInterface.sendSciCommand("OrientProbe",Probe,Side)
+    return int(rsp[0])
+
+def InitProbe(Probe="", FlagsInit="", FlagsDirection="", FlagsMoveRange="", FlagsInitInPlace=""):
+    """
+    Performs an initialization move and resets the coordinate system of the given
+    positioner.
+    API Status: published
+    Args:
+        Probe:int = 1
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+        FlagsInitInPlace:int = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 120000
+    Example:InitProbe 1 7 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("InitProbe",Probe,FlagsInit,FlagsDirection,FlagsMoveRange,FlagsInitInPlace)
+    return int(rsp[0])
+
+def MoveProbe(Probe="", XValue="", YValue="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbe 1 1000. 1000. R Y 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbe",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def MoveProbeIndex(Probe="", XSteps="", YSteps="", PosRef="", Velocity=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeIndex 1 1 1 R 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeIndex",Probe,XSteps,YSteps,PosRef,Velocity)
+    return int(rsp[0])
+
+def MoveProbeContact(Probe="", Velocity=""):
+    """
+    Moves the given ProbeHeads Z axis to the preset contact height. If no contact
+    height is set, the kernel will return a 'Contact height not set' error.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeContact 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeContact",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeAlign(Probe="", Velocity=""):
+    """
+    Moves the given ProbeHeads Z axis to the align height.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeAlign 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeAlign",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeSeparation(Probe="", Velocity=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeSeparation 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeSeparation",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeZ(Probe="", Height="", PosRef="", Unit="", Velocity="", Comp=""):
+    """
+    Moves a given ProbeHeads Z axis to a defined Z height.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeZ 1 1000. R Y 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeZ",Probe,Height,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def MoveProbeLift(Probe="", SetLift=""):
+    """
+    Moves the positioner to the lower (0) or upper = lifted (1) position. The
+    command initiates the motion only, the whole movement may take some seconds.
+    API Status: published
+    Args:
+        Probe:int = 1
+        SetLift:int = 1
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 10000
+    Example:MoveProbeLift 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeLift",Probe,SetLift)
+    return int(rsp[0])
+
+def MoveProbeVelocity(Probe="", PolarityX="", PolarityY="", PolarityZ="", VelocityX="", VelocityY="", VelocityZ=""):
+    """
+    '+' Move this axis into plus direction '-' Move this axis into minus direction
+    '0' Do not change this axis
+    API Status: published
+    Args:
+        Probe:int = 1
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeVelocity 1 + + Z 67 100 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeVelocity",Probe,PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+    return int(rsp[0])
+
+def StopProbeMovement(Probe="", FlagsStop=""):
+    """
+    Stops positioner movement for the given axes immediately. A smooth stop is
+    performed.
+    API Status: published
+    Args:
+        Probe:int = 1
+        FlagsStop:int = 7
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:StopProbeMovement 1 7
+    """
+    rsp = MessageServerInterface.sendSciCommand("StopProbeMovement",Probe,FlagsStop)
+    return int(rsp[0])
+
+def SetProbeMode(Probe="", Overtravel="", AutoZ="", Interlock="", AutoZFollow="", AutoQuiet=""):
+    """
+    The mode manages the way the chuck behaves when it is in contact height.
+    Positioner mode is made up from 5 flags and the user can control all of them by
+    using this command. Every flag can be turned on by setting value 1, or turned
+    off by setting value 0. Use the value 2 if no change for a flag is needed.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        AutoZFollow:int = 2
+        AutoQuiet:int = 2
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeMode 1 2 2 2 2
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeMode",Probe,Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+    return int(rsp[0])
+
+def SetProbeHome(Probe="", Mode="", Unit="", XValue="", YValue=""):
+    """
+    Sets the positioner's Home position in X and Y. This position identifies the
+    probe coordinate system for later movements. Usually this position is identical
+    to the die home position.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeHome 1 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeHome",Probe,Mode,Unit,XValue,YValue)
+    return int(rsp[0])
+
+def SetProbeIndex(Probe="", XValue="", YValue="", Unit=""):
+    """
+    Sets the positioner's index size or the location of the reference die relative
+    to the home die.
+    API Status: published
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeIndex 1 1000. 1000. Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeIndex",Probe,XValue,YValue,Unit)
+    return int(rsp[0])
+
+def SetProbeHeight(Probe="", PresetHeight="", Mode="", Unit="", Value=""):
+    """
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align, load and separation height. No data sets contact height at current
+    position.
+    API Status: published
+    Args:
+        Probe:int = 1
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeHeight 1 C 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeHeight",Probe,PresetHeight,Mode,Unit,Value)
+    return int(rsp[0])
+
+def ReadProbeIndex(Probe="", Unit=""):
+    """
+    Returns the current positioner's wafer index values or the current positioner's
+    index positions for X and Y.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeIndex 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeIndex",Probe,Unit)
+    global ReadProbeIndex_Response
+    if not "ReadProbeIndex_Response" in globals(): ReadProbeIndex_Response = namedtuple("ReadProbeIndex_Response", "ProbeEcho,IndexX,IndexY")
+    return ReadProbeIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetProbeLED(Probe="", NewLEDState=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the positioner LED On or Off.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        NewLEDState:int = 0
+    Returns:
+        ProbeEcho:int
+        LEDState:int
+    Command Timeout: 5000
+    Example:SetProbeLED 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeLED",Probe,NewLEDState)
+    global SetProbeLED_Response
+    if not "SetProbeLED_Response" in globals(): SetProbeLED_Response = namedtuple("SetProbeLED_Response", "ProbeEcho,LEDState")
+    return SetProbeLED_Response(int(rsp[0]),int(rsp[1]))
+
+def GetProbeTableID(Probe="", TableName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the ID of a stored probe table or creates a new table. The ID is unique
+    for the name and the probe. The table itself has a string name. This name is not
+    case sensitive. The command has to be used before all other table commands can
+    be used. Access to tables is possible only with an ID Number (name dependent).
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableName:str = "ProbeTable"
+    Returns:
+        ProbeEcho:int
+        TableID:int
+    Command Timeout: 5000
+    Example:GetProbeTableID 1 ProbeTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProbeTableID",Probe,TableName)
+    global GetProbeTableID_Response
+    if not "GetProbeTableID_Response" in globals(): GetProbeTableID_Response = namedtuple("GetProbeTableID_Response", "ProbeEcho,TableID")
+    return GetProbeTableID_Response(int(rsp[0]),int(rsp[1]))
+
+def MoveProbeTablePoint(Probe="", TableID="", PointID="", Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 1
+        PointID:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeTablePoint 3 14 10 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeTablePoint",Probe,TableID,PointID,Velocity)
+    return int(rsp[0])
+
+def ReadProbeTablePoint(Probe="", TableID="", PointID="", Unit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads the data from a point of a stored table in the Kernel.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadProbeTablePoint 2 4 10 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeTablePoint",Probe,TableID,PointID,Unit)
+    global ReadProbeTablePoint_Response
+    if not "ReadProbeTablePoint_Response" in globals(): ReadProbeTablePoint_Response = namedtuple("ReadProbeTablePoint_Response", "ProbeEcho,CoordX,CoordY,CoordSystem")
+    return ReadProbeTablePoint_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetProbeTablePoint(Probe="", TableID="", PointID="", CoordX="", CoordY="", Unit="", CoordSystem=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets one point of a ProbeHeads table inside the Kernel. If there is still a
+    point with this index loaded, the Kernel returns an error. Number of positions
+    and number of tables are dependet on the internal memory. All positions are
+    stored persistent, that means after switching power on or off the positions are
+    still available. The table starts with point number 1 and ends with the ID 16.
+    The table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ProbeEcho:int
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetProbeTablePoint 3 12 10 8992.5 7883.0 Y Z M
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeTablePoint",Probe,TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    global SetProbeTablePoint_Response
+    if not "SetProbeTablePoint_Response" in globals(): SetProbeTablePoint_Response = namedtuple("SetProbeTablePoint_Response", "ProbeEcho,ValidPoint")
+    return SetProbeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ClearProbeTablePoint(Probe="", TableID="", StartPoint="", EndPoint=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of ProbeHead table site points in the Kernel. If StartPoint
+    is a negative value, the whole table will be deleted.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ProbeEcho:int
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearProbeTablePoint 3 4 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearProbeTablePoint",Probe,TableID,StartPoint,EndPoint)
+    global ClearProbeTablePoint_Response
+    if not "ClearProbeTablePoint_Response" in globals(): ClearProbeTablePoint_Response = namedtuple("ClearProbeTablePoint_Response", "ProbeEcho,ClearNumber,ValidNumber")
+    return ClearProbeTablePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def MoveScopeSilo(Index=""):
+    """
+    Move the scope to the reference position of the given silo. The reference
+    position should be - if not defined otherwise - 200 um above the safe z-height
+    in the center of the scope.
+    API Status: published
+    Args:
+        Index:int = 1
+    Command Timeout: 70000
+    Example:MoveScopeSilo 1
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeSilo",Index)
+
+
+def SetScopeSiloReference(Index="", X="", Y="", Z=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the reference position of a silo. The next time the scope moves to this
+    silo, it woll go to this position. The Referenceposition must be inside the silo
+    in xy and above the lower Z-Fence of the silo.  Setting the reference position
+    directly on the fence in x, y or z typically leads to errors. Try to keep a
+    safety margin.
+    API Status: internal
+    Args:
+        Index:int = 1
+        X:Decimal = 0
+        Y:Decimal = 0
+        Z:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeSiloReference 1 1000 2000 3000
+    """
+    MessageServerInterface.sendSciCommand("SetScopeSiloReference",Index,X,Y,Z)
+
+
+def AlignChuckTheta(XDistance="", YDistance="", PosRef=""):
+    """
+    This command causes a chuck Theta axis rotation to align the wafer to the chuck
+    X,Y movements.     It can be used to perform a two point alignment with
+    P1(X1,Y1) and P2(X2,Y2) as two points on a wafer street line.     The units of
+    the distances are not important - but both distances should use the same unit.
+    If one or both distances are zero, the command does not return an error and
+    instead ignore this alignment
+    API Status: published
+    Args:
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignChuckTheta 10000 10 R
+    """
+    MessageServerInterface.sendSciCommand("AlignChuckTheta",XDistance,YDistance,PosRef)
+
+
+def AlignScopeTheta(XDistance="", YDistance="", PosRef=""):
+    """
+    This command causes a virtual rotation of the scope coordinate system to align
+    the scope to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+    perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+    Calculation of X and Y distances:
+    API Status: published
+    Args:
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignScopeTheta 10000 10 R
+    """
+    MessageServerInterface.sendSciCommand("AlignScopeTheta",XDistance,YDistance,PosRef)
+
+
+def AlignProbeTheta(Probe="", XDistance="", YDistance="", PosRef=""):
+    """
+    This command causes a rotation of the coordinate system of given probe to align
+    the probe to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+    perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+    Calculation of Y and Y distances:
+    API Status: published
+    Args:
+        Probe:int = 1
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 10000
+    Example:AlignProbeTheta 1 10000 10 R
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignProbeTheta",Probe,XDistance,YDistance,PosRef)
+    return int(rsp[0])
+
+def AlignCardTheta(Angle="", Unit="", PosRef=""):
+    """
+    This command causes a rotation of the chuck coordinate system to align the chuck
+    X, Y axis to the probecard.     The polarity of the data determines a left or a
+    right rotation of the chuck coordinate system.
+    API Status: published
+    Args:
+        Angle:Decimal = 0
+        Unit:str = "Degrees"
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignCardTheta 2.5 D R
+    """
+    MessageServerInterface.sendSciCommand("AlignCardTheta",Angle,Unit,PosRef)
+
+
+def ReadCardTheta(Unit=""):
+    """
+    Returns the angle between the chuck-coordinate-system and the probecard-
+    coordinate-system.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadCardTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCardTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadChuckTheta(Unit=""):
+    """
+    Returns the current chuck alignment angle which is identical to the current
+    value of theta rotation.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadScopeTheta(Unit=""):
+    """
+    Returns the scope's alignment angle, which is the angle between the chuck
+    coordinate system and the scope coordinate system.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadProbeTheta(Probe="", Unit=""):
+    """
+    Returns the actual positioner's alignment angle, which is the angle between the
+    chuck coordinate system and the positioner coordinate system.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Degrees"
+    Returns:
+        ProbeEcho:int
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeTheta 1 D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeTheta",Probe,Unit)
+    global ReadProbeTheta_Response
+    if not "ReadProbeTheta_Response" in globals(): ReadProbeTheta_Response = namedtuple("ReadProbeTheta_Response", "ProbeEcho,Angle")
+    return ReadProbeTheta_Response(int(rsp[0]),Decimal(rsp[1]))
+
+def ReadJoystickSpeeds(Stage="", Axis=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the preset speeds, which are used by the joystick controller for moving a
+    single stage. The speeds can be read for XY, for Z and for Theta axis
+    separately. Jog timing and index timing are the times, the joystick controller
+    waits between two single jog or index moves.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "X"
+    Returns:
+        JogTime:Decimal
+        Speed2:Decimal
+        Speed3:Decimal
+        Speed4:Decimal
+        IndexTime:Decimal
+    Command Timeout: 5000
+    Example:ReadJoystickSpeeds S Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeeds",Stage,Axis)
+    global ReadJoystickSpeeds_Response
+    if not "ReadJoystickSpeeds_Response" in globals(): ReadJoystickSpeeds_Response = namedtuple("ReadJoystickSpeeds_Response", "JogTime,Speed2,Speed3,Speed4,IndexTime")
+    return ReadJoystickSpeeds_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetJoystickSpeeds(Stage="", JogTime="", Speed2="", Speed3="", Speed4="", IndexTime="", Axis=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the preset speeds, which are used by the joystick controller for moving a
+    single stage. After setting, the speeds can be selected by pressing the Speed n
+    buttons at the controller. The speeds must be set separately for XY, for Z and
+    for Theta axis. Jog timing and index timing are the times, the joystick
+    controller waits between two single jog or index moves.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        JogTime:Decimal = 0
+        Speed2:Decimal = 0
+        Speed3:Decimal = 0
+        Speed4:Decimal = 0
+        IndexTime:Decimal = 0
+        Axis:str = "X"
+    Command Timeout: 5000
+    Example:SetJoystickSpeeds S 10 20 30 40 50 Z
+    """
+    MessageServerInterface.sendSciCommand("SetJoystickSpeeds",Stage,JogTime,Speed2,Speed3,Speed4,IndexTime,Axis)
+
+
+def SetLoaderGate(Open=""):
+    """
+    Opens or closes the loader gate. Automatic handling systems can load wafers to
+    the chuck through the gate.
+    API Status: published
+    Args:
+        Open:int = 0
+    Command Timeout: 5000
+    Example:SetLoaderGate 0
+    """
+    MessageServerInterface.sendSciCommand("SetLoaderGate",Open)
+
+
+def ReadWaferStatus():
+    """
+    Returns whether the system detected a wafer. This feature can be used if the
+    probe station is equipped with a vacuum sensor and while vacuum is activated.
+    API Status: published
+    Returns:
+        SensedByVac:str
+    Command Timeout: 5000
+    Example:ReadWaferStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadWaferStatus")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadContactCount(Stage=""):
+    """
+    Returns the number of times this stage moved to contact since the last time the
+    counter was reset.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        Count:int
+    Command Timeout: 5000
+    Example:ReadContactCount C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadContactCount",Stage)
+    return int(rsp[0])
+
+def ResetContactCount(Stage=""):
+    """
+    Resets the contact counter for the specified stage to zero. Notifications: 23
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Command Timeout: 5000
+    Example:ResetContactCount C
+    """
+    MessageServerInterface.sendSciCommand("ResetContactCount",Stage)
+
+
+def SetManualMode(Enable=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command enables the manual mode on Elite/Summit/S300 systems. This mode
+    will allow to move the chuck using the knobs.
+    API Status: internal
+    Args:
+        Enable:int = 1
+    Command Timeout: 10000
+    Example:SetManualMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetManualMode",Enable)
+
+
+def GetManualMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns the state of the manual mode on Elite/Summit/S300 stations.
+    API Status: internal
+    Returns:
+        Enable:int
+    Command Timeout: 10000
+    Example:GetManualMode 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetManualMode")
+    return int(rsp[0])
+
+def GetAxisReverse(Stage="", Axis=""):
+    """
+    Allows reading if an axis is reverse.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        IsReverse:int
+    Command Timeout: 5000
+    Example:GetAxisReverse C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAxisReverse",Stage,Axis)
+    return int(rsp[0])
+
+def EnableEdgeSensor(EdgeSensor="", Enable=""):
+    """
+    Enables/disables the use of an edge sensor.
+    API Status: published
+    Args:
+        EdgeSensor:int = 1
+        Enable:int = 1
+    Command Timeout: 5000
+    Example:EnableEdgeSensor 1 1
+    """
+    MessageServerInterface.sendSciCommand("EnableEdgeSensor",EdgeSensor,Enable)
+
+
+def SetTypedOutput(Channel="", WantOutputOn="", PulseTime=""):
+    """
+    Controls the kernel valve driver signals and can be used to drive the outputs.
+    API Status: published
+    Args:
+        Channel:str = "NoSensor"
+        WantOutputOn:int = 0
+        PulseTime:int = -1
+    Command Timeout: 5000
+    Example:SetTypedOutput WaferVacuum 1
+    """
+    MessageServerInterface.sendSciCommand("SetTypedOutput",Channel,WantOutputOn,PulseTime)
+
+
+def ReadTypedSensor(Channel=""):
+    """
+    Returns the status of the specified input channel, output channel, or edge
+    sensor.
+    API Status: published
+    Args:
+        Channel:str = "NoSensor"
+    Returns:
+        IsSensorOn:int
+    Command Timeout: 10000
+    Example:ReadTypedSensor EmoIn I
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTypedSensor",Channel)
+    return int(rsp[0])
+
+def MoveCoolDownPosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck to the cool down position that is defined in KernelSetup. The
+    cooldown position is used to move the chuck away in XY while the robot is in the
+    chamber and tries to get a hot wafer.
+    API Status: internal
+    Command Timeout: 30000
+    Example:MoveCoolDownPosition
+    """
+    MessageServerInterface.sendSciCommand("MoveCoolDownPosition")
+
+
+def ReadJoystickSpeedsCycle(Stage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the cycling speeds - these are the speeds that are used by
+    the USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        CycleJog:int
+        CycleSpeed2:int
+        CycleSpeed3:int
+        CycleSpeed4:int
+        CycleIndex:int
+    Command Timeout: 5000
+    Example:ReadJoystickSpeedsCycle S
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeedsCycle",Stage)
+    global ReadJoystickSpeedsCycle_Response
+    if not "ReadJoystickSpeedsCycle_Response" in globals(): ReadJoystickSpeedsCycle_Response = namedtuple("ReadJoystickSpeedsCycle_Response", "CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex")
+    return ReadJoystickSpeedsCycle_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetJoystickSpeedsCycle(Stage="", CycleJog="", CycleSpeed2="", CycleSpeed3="", CycleSpeed4="", CycleIndex=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets the cycling speeds - these are the speeds that are used by the
+    USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CycleJog:int = 0
+        CycleSpeed2:int = 0
+        CycleSpeed3:int = 0
+        CycleSpeed4:int = 0
+        CycleIndex:int = 0
+    Command Timeout: 5000
+    Example:SetJoystickSpeedsCycle C 1 1 1 1 1
+    """
+    MessageServerInterface.sendSciCommand("SetJoystickSpeedsCycle",Stage,CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex)
+
+
+def SendAUCSCommand(Command=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows sending low level AUCS commands to the ECX box stage. Only
+    applies to Elite/Summit/S300 stations.
+    API Status: internal
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 60000
+    Example:SendAUCSCommand "MM 1 0 INIT 0"
+    """
+    rsp = MessageServerInterface.sendSciCommand("SendAUCSCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadCompensationStatus(Stage="", Compensation=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command allows reading if a specific type of compensation is enabled or
+    disabled. Returns an error if this type of compensation is not available for
+    this stage.
+    API Status: internal
+    Args:
+        Stage:str = "None"
+        Compensation:str = "None"
+    Returns:
+        Enabled:int
+        Active:int
+    Command Timeout: 5000
+    Example:ReadCompensationStatus C A
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCompensationStatus",Stage,Compensation)
+    global ReadCompensationStatus_Response
+    if not "ReadCompensationStatus_Response" in globals(): ReadCompensationStatus_Response = namedtuple("ReadCompensationStatus_Response", "Enabled,Active")
+    return ReadCompensationStatus_Response(int(rsp[0]),int(rsp[1]))
+
+def RegisterNotification(NotificationCode="", WantNotification=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Deprecated. All Kernel notifications are now enabled by default.
+    API Status: internal
+    Args:
+        NotificationCode:int = 0
+        WantNotification:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("RegisterNotification",NotificationCode,WantNotification)
+
+
+def AlertNotification(NotificationId="", Value1="", Value2="", Value3=""):
+    """
+    This is not a regular command. Asynchronous notifications will be sent from the
+    Kernel controller to the host system only. All notifications can be switched off
+    and on, except the Prober reset notification (ID01).  /warning This is a stub
+    implementation without appropriate handling
+    API Status: published
+    Args:
+        NotificationId:int = 0
+        Value1:Decimal = 0
+        Value2:Decimal = 0
+        Value3:Decimal = 0
+    Command Timeout: 5000
+    Example:AlertNotification 31 195000 160000 0
+    """
+    MessageServerInterface.sendSciCommand("AlertNotification",NotificationId,Value1,Value2,Value3)
+
+
+def SetCompensationStatus(Stage="", Compensation="", Status=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables a compensation mode for the specified stage
+    API Status: internal
+    Args:
+        Stage:str = "None"
+        Compensation:str = "None"
+        Status:int = -1
+    Command Timeout: 5000
+    Example:SetCompensationStatus C A 1
+    """
+    MessageServerInterface.sendSciCommand("SetCompensationStatus",Stage,Compensation,Status)
+
+
+def GetControllerInfo(ControllerInfo=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command gets the value "Value" for the parameter "Parameter". The unit is
+    parameter specific.
+    API Status: internal
+    Args:
+        ControllerInfo:str = "Unknown"
+    Returns:
+        Value:Decimal
+    Command Timeout: 1000
+    Example:GetControllerInfo HasScanChuckZ
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetControllerInfo",ControllerInfo)
+    return Decimal(rsp[0])
+
+def SetOperationalMode(OperationalMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    In unprotected mode a number of security features like software fence and
+    initialization necessity are deactivated.          Unprotected mode is
+    deactivated automatically after 5 minutes. Sending 'SetOperationalMode U'
+    anytime before resets the timer back to 5 minutes. It is not necessary to
+    deactivate it before.  **WARNING**: If unprotected mode is enabled, even the
+    most basic safety- and sanity-checks are skipped. Any movement may cause
+    irreparable damage to the prober or attached hardware.
+    API Status: internal
+    Args:
+        OperationalMode:str = "ProtectedMode"
+    Command Timeout: 5000
+    Example:SetOperationalMode P
+    """
+    MessageServerInterface.sendSciCommand("SetOperationalMode",OperationalMode)
+
+
+def GetNanoChamberState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the currently configured Nano-chamber-state.
+    API Status: internal
+    Returns:
+        NanoChamberState:str
+    Command Timeout: 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNanoChamberState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetNanoChamberState(NanoChamberState=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the NanoChamber-state.
+    API Status: internal
+    Args:
+        NanoChamberState:str = "Free"
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("SetNanoChamberState",NanoChamberState)
+
+
+def SetCameraCool(State=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows to force activate/deactivate the camera cool output or to let it be set
+    automatically by purge control.
+    API Status: internal
+    Args:
+        State:int = 2
+    Command Timeout: 10000
+    Example:SetCameraCool 0
+    """
+    MessageServerInterface.sendSciCommand("SetCameraCool",State)
+
+
+def ActivateChuckVacuum():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the chuck vacuum and forces it to be on. This command ignores the
+    vacuum sensor and timeout.
+    API Status: internal
+    Command Timeout: 10000
+    Example:ActivateChuckVacuum
+    """
+    MessageServerInterface.sendSciCommand("ActivateChuckVacuum")
+
+
+def ReadMatrixValues(Stage="", MatrixIndexX="", MatrixIndexY=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns a point from the matrix compensation table for the
+    specified axis from the kernel. All command parameters are mandatory.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        MatrixIndexX:int = 0
+        MatrixIndexY:int = 0
+    Returns:
+        XVal:Decimal
+        YVal:Decimal
+    Command Timeout: 5000
+    Example:ReadMatrixValues C 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMatrixValues",Stage,MatrixIndexX,MatrixIndexY)
+    global ReadMatrixValues_Response
+    if not "ReadMatrixValues_Response" in globals(): ReadMatrixValues_Response = namedtuple("ReadMatrixValues_Response", "XVal,YVal")
+    return ReadMatrixValues_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetMatrixValues(Stage="", MatrixIndexX="", MatrixIndexY="", XVal="", YVal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Downloads a point of the matrix compensation table for a specified stage to the
+    kernel. All command parameters are mandatory.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        MatrixIndexX:int = 0
+        MatrixIndexY:int = 0
+        XVal:Decimal = 0
+        YVal:Decimal = 0
+    Command Timeout: 5000
+    Example:SetMatrixValues C 0 0 5000.0 5000.0 2500.0
+    """
+    MessageServerInterface.sendSciCommand("SetMatrixValues",Stage,MatrixIndexX,MatrixIndexY,XVal,YVal)
+
+
+def ReadMEAStatus(Stage="", Type=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads if the MEA file for a stage is loaded/enabled (Nucleus legacy stations
+    only)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Type:int = 0
+    Returns:
+        Enable:int
+    Command Timeout: 5000
+    Example:ReadMEAStatus C 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMEAStatus",Stage,Type)
+    return int(rsp[0])
+
+def LoadMEAFile(Stage="", Type="", Load=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Load the MEA file for a stage (Nucleus legacy stations only)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Type:int = 0
+        Load:int = 0
+    Command Timeout: 5000
+    Example:LoadMEAFile C 0 1
+    """
+    MessageServerInterface.sendSciCommand("LoadMEAFile",Stage,Type,Load)
+
+
+def ReadSoftwareLimits(Stage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The command returns the positions of the actual software limits (end of move
+    range) for each axis of the specified stage in microns. If the Theta stage is
+    selected Z1 and Z2 include the values for the Theta limits.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        ZLowValue:Decimal
+        ZHighValue:Decimal
+        X1Value:Decimal
+        Y1Value:Decimal
+        X2Value:Decimal
+        Y2Value:Decimal
+        X3Value:Decimal
+        Y3Value:Decimal
+        X4Value:Decimal
+        Y4Value:Decimal
+    Command Timeout: 5000
+    Example:ReadSoftwareLimits C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSoftwareLimits",Stage)
+    global ReadSoftwareLimits_Response
+    if not "ReadSoftwareLimits_Response" in globals(): ReadSoftwareLimits_Response = namedtuple("ReadSoftwareLimits_Response", "ZLowValue,ZHighValue,X1Value,Y1Value,X2Value,Y2Value,X3Value,Y3Value,X4Value,Y4Value")
+    return ReadSoftwareLimits_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def SetSoftwareFence(Stage="", AuxID="", FenceForm="", XBase="", YBase="", XDist="", YDist=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets types and dimensions of technological software fences. It can
+    also be used for enabling and disabling the software fence.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxID:int = 0
+        FenceForm:str = "None"
+        XBase:Decimal = 0
+        YBase:Decimal = 0
+        XDist:Decimal = 0
+        YDist:Decimal = 0
+    Command Timeout: 10000
+    Example:SetSoftwareFence C 0 R 5000 5000 25000 25000
+    """
+    MessageServerInterface.sendSciCommand("SetSoftwareFence",Stage,AuxID,FenceForm,XBase,YBase,XDist,YDist)
+
+
+def GetSoftwareFence(Stage="", AuxID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the type and the dimensions of an actual set technological
+    software fence. In case of a rectangular software fence, X and Y coordinates of
+    the four edge points of the fence are given back. In case of a circular software
+    fence, X and Y coordinates of the center point and the radius are given back.
+    All other return values are filled with zeros. All position values are in
+    microns from zero.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxID:int = 0
+    Returns:
+        FenceForm:str
+        XValue1:Decimal
+        YValue1:Decimal
+        XValue2:Decimal
+        YValue2:Decimal
+        XValue3:Decimal
+        YValue3:Decimal
+        XValue4:Decimal
+        YValue4:Decimal
+    Command Timeout: 10000
+    Example:GetSoftwareFence C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwareFence",Stage,AuxID)
+    global GetSoftwareFence_Response
+    if not "GetSoftwareFence_Response" in globals(): GetSoftwareFence_Response = namedtuple("GetSoftwareFence_Response", "FenceForm,XValue1,YValue1,XValue2,YValue2,XValue3,YValue3,XValue4,YValue4")
+    return GetSoftwareFence_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]))
+
+def GetZFence(Stage="", CompLayer=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This commands reads if the Z-Fence is activated and the currently set Z-fence
+    values for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CompLayer:str = "Default"
+    Returns:
+        Enabled:int
+        ZLow:Decimal
+        ZHigh:Decimal
+    Command Timeout: 10000
+    Example:GetZFence S
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZFence",Stage,CompLayer)
+    global GetZFence_Response
+    if not "GetZFence_Response" in globals(): GetZFence_Response = namedtuple("GetZFence_Response", "Enabled,ZLow,ZHigh")
+    return GetZFence_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetZFence(Stage="", Enabled="", ZLow="", ZHigh="", CompLayer=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This commands sets Z-Fence and the Z-fence values for the specified stage.
+    Values are stored uncompensated internally and set default compensated as
+    default.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Enabled:int = 0
+        ZLow:Decimal = 0
+        ZHigh:Decimal = 0
+        CompLayer:str = "Default"
+    Command Timeout: 10000
+    Example:SetZFence S 1 5000 10000
+    """
+    MessageServerInterface.sendSciCommand("SetZFence",Stage,Enabled,ZLow,ZHigh,CompLayer)
+
+
+def ResetProber(Mode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Restarts the Prober and replaces the current configuration with a formerly
+    written recovery file. If no recovery file was written, the configuration is
+    reset to the version of the last Prober restart. For ProberBench electronics,
+    'H' will restart the Operating system, 'S' will only restart the Kernel
+    application. For Windows Kernel, 'H' and 'S' are identical.
+    API Status: internal
+    Args:
+        Mode:str = "S"
+    Command Timeout: 20000
+    Example:ResetProber S
+    """
+    MessageServerInterface.sendSciCommand("ResetProber",Mode)
+
+
+def ResetCBox(ResetMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reboots the operation system inside the Joystick Controller and restarts the
+    functionality. The restart will need a time of around 20 seconds.
+    API Status: internal
+    Args:
+        ResetMode:str = "S"
+    Command Timeout: 20000
+    Example:ResetCBox S
+    """
+    MessageServerInterface.sendSciCommand("ResetCBox",ResetMode)
+
+
+def ReadStageLocations(Stage="", LocationType="", AuxID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The Home Position on the Chuck or ProbeHead Z axis is also called contact
+    height. The Home Position on the Scope Z axis is also called focus height.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        LocationType:str = "Center"
+        AuxID:int = 0
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadStageLocations C C 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadStageLocations",Stage,LocationType,AuxID)
+    global ReadStageLocations_Response
+    if not "ReadStageLocations_Response" in globals(): ReadStageLocations_Response = namedtuple("ReadStageLocations_Response", "X,Y,Z")
+    return ReadStageLocations_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetDataIterator(ShowAll=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a data stream handle which represents a data stream of setup parameters.
+    and requires the GetNextDatum command.
+    API Status: internal
+    Args:
+        ShowAll:int = 0
+    Returns:
+        IdentityToken:int
+        SizeNoAll:int
+    Command Timeout: 10000
+    Example:GetDataIterator 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDataIterator",ShowAll)
+    global GetDataIterator_Response
+    if not "GetDataIterator_Response" in globals(): GetDataIterator_Response = namedtuple("GetDataIterator_Response", "IdentityToken,SizeNoAll")
+    return GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def GetNextDatum(IdentityToken=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the next parameter from the data stream. Fields are separated by a
+    colon. Structure of the response parameter Value:
+    Path_Path:Name:Description:Value
+    API Status: internal
+    Args:
+        IdentityToken:int = 0
+    Returns:
+        IsLastDatum:int
+        DatumCode:int
+        Attributes:int
+        PathNameDescrValue:str
+    Command Timeout: 10000
+    Example:GetNextDatum 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNextDatum",IdentityToken)
+    global GetNextDatum_Response
+    if not "GetNextDatum_Response" in globals(): GetNextDatum_Response = namedtuple("GetNextDatum_Response", "IsLastDatum,DatumCode,Attributes,PathNameDescrValue")
+    return GetNextDatum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetDatum(PathNameAndValue=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        PathNameAndValue:str = ""
+    Command Timeout: 20000
+    Example:SetDatum Chuck:AlignGap:25
+    """
+    MessageServerInterface.sendSciCommand("SetDatum",PathNameAndValue)
+
+
+def GetDatum(PathName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a value string. The Value string consists of the value and the
+    description. The Locator only consists of the path and the name. All fields are
+    separated by a colon.  Structure of the command parameter Locator:
+    Path_Path:Name Structure of the response parameter Value: Value:Description
+    API Status: internal
+    Args:
+        PathName:str = ""
+    Returns:
+        Attributes:int
+        DatumCode:int
+        ValueDesc:str
+    Command Timeout: 5000
+    Example:GetDatum Chuck:AlignGap
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDatum",PathName)
+    global GetDatum_Response
+    if not "GetDatum_Response" in globals(): GetDatum_Response = namedtuple("GetDatum_Response", "Attributes,DatumCode,ValueDesc")
+    return GetDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetRecoveryDatum(PathNameAndValue=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        PathNameAndValue:str = ""
+    Command Timeout: 5000
+    Example:SetRecoveryDatum Chuck:AlignGap:25
+    """
+    MessageServerInterface.sendSciCommand("SetRecoveryDatum",PathNameAndValue)
+
+
+def TraceStart(Controller=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the motion recording. The recording parameters are set in dynamic
+    kernel setup.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Command Timeout: 10000
+    Example:TraceStart C
+    """
+    MessageServerInterface.sendSciCommand("TraceStart",Controller)
+
+
+def TraceStatus(Controller=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Checks the motion recording status for one stage.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Returns:
+        IsReady:int
+        SizeCh0Raw:int
+        SizeCh0Comp:int
+        SizeCh1Raw:int
+        SizeCh1Comp:int
+        SizeCh2Raw:int
+        SizeCh2Comp:int
+        SizeCh3Raw:int
+        SizeCh3Comp:int
+    Command Timeout: 10000
+    Example:TraceStatus C
+    """
+    rsp = MessageServerInterface.sendSciCommand("TraceStatus",Controller)
+    global TraceStatus_Response
+    if not "TraceStatus_Response" in globals(): TraceStatus_Response = namedtuple("TraceStatus_Response", "IsReady,SizeCh0Raw,SizeCh0Comp,SizeCh1Raw,SizeCh1Comp,SizeCh2Raw,SizeCh2Comp,SizeCh3Raw,SizeCh3Comp")
+    return TraceStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def TraceGetData(Controller="", Channel="", PointOne="", IsCompress=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get a collection of five data pairs. A pair is the index and the value of a
+    recording point. If the stream is empty or at the end the index is 1 and the
+    value 0. The index is relative to the start of the motion recording. The
+    recording is clocked by the motion controller cycle. The cycle time is contained
+    in the Kernel setup. In the raw stream all recorded trace points are contained.
+    But in the compressed stream only the non-linear depending trace points are
+    contained. To reload the recording points the stream must be reset to the first
+    recording point.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+        Channel:int = 0
+        PointOne:int = 1
+        IsCompress:int = 1
+    Returns:
+        Point1:int
+        Value1:int
+        Point2:int
+        Value2:int
+        Point3:int
+        Value3:int
+        Point4:int
+        Value4:int
+        Point5:int
+        Value5:int
+    Command Timeout: 10000
+    Example:TraceGetData C 0 0 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("TraceGetData",Controller,Channel,PointOne,IsCompress)
+    global TraceGetData_Response
+    if not "TraceGetData_Response" in globals(): TraceGetData_Response = namedtuple("TraceGetData_Response", "Point1,Value1,Point2,Value2,Point3,Value3,Point4,Value4,Point5,Value5")
+    return TraceGetData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def TraceSetDataPosition(Controller="", Channel="", NewPos="", IsCompress=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the index position in the raw or compressed stream for the next call of the
+    command TraceGetData.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+        Channel:int = 0
+        NewPos:int = 0
+        IsCompress:int = 1
+    Command Timeout: 10000
+    Example:TraceSetDataPosition C 0 1000 1
+    """
+    MessageServerInterface.sendSciCommand("TraceSetDataPosition",Controller,Channel,NewPos,IsCompress)
+
+
+def TraceStop(Controller=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the motion recording.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Command Timeout: 10000
+    Example:TraceStop C
+    """
+    MessageServerInterface.sendSciCommand("TraceStop",Controller)
+
+
+def SetZProfilePoint(Stage="", XValue="", YValue="", ZGap="", PosRef="", Unit="", ZProfileType=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set a point for the Z height profile. If this profile is enabled, the Z height
+    depends on a X and Y coordinate. The Z value is a gap to the current Z height.
+    Positive values are elevated spots, negative values are hollows. The height
+    profile is used to adjust the Z height. The adjusted Z height at a X and Y
+    position is derivated from the nearest profile point. The Z contact level will
+    be calculated from the contact height and the stored Z gap at this point.  See
+    GetZProfilePoint for details.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        ZGap:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        ZProfileType:int = 0
+    Returns:
+        ValueCount:int
+    Command Timeout: 5000
+    Example:SetZProfilePoint C 5000 5000 -3 H Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetZProfilePoint",Stage,XValue,YValue,ZGap,PosRef,Unit,ZProfileType)
+    return int(rsp[0])
+
+def ReadZProfilePoint(Stage="", Index="", PosRef="", Unit="", ZProfileType=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get a single point and the corresponding Z gap of the Z height profile.  The
+    different z profiles are:  - transient: meant to be used on a per-wafer-basis,
+    default - persistent: configured once, stays in memory - persistent-offset: same
+    as persistent, active when offset is enabled - scratch: not used internaly. Can
+    be used to translate KernelDatums <-> ZProfile-Points
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Index:int = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        ZProfileType:int = 0
+    Returns:
+        XValue:Decimal
+        YValue:Decimal
+        ZGap:Decimal
+        ValueCount:int
+    Command Timeout: 5000
+    Example:ReadZProfilePoint C 1 H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadZProfilePoint",Stage,Index,PosRef,Unit,ZProfileType)
+    global ReadZProfilePoint_Response
+    if not "ReadZProfilePoint_Response" in globals(): ReadZProfilePoint_Response = namedtuple("ReadZProfilePoint_Response", "XValue,YValue,ZGap,ValueCount")
+    return ReadZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]))
+
+def ClearZProfile(Stage="", ZProfileType=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clears all profile points. See GetZProfile for type description.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZProfileType:int = 0
+    Command Timeout: 5000
+    Example:ClearZProfile C
+    """
+    MessageServerInterface.sendSciCommand("ClearZProfile",Stage,ZProfileType)
+
+
+def ReadScopeSilo(Index=""):
+    """
+    Returns the definition of a silo. If the type is rectangle, center means
+    _Point1_. If the type is circle, the meaning of Pos2X and Pos2Y is undefined.
+    API Status: published
+    Args:
+        Index:int = 1
+    Returns:
+        Type:str
+        CenterX:Decimal
+        CenterY:Decimal
+        Radius:Decimal
+        Pos2X:Decimal
+        Pos2Y:Decimal
+        ZHigh:Decimal
+        RefX:Decimal
+        RefY:Decimal
+        RefZ:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeSilo 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSilo",Index)
+    global ReadScopeSilo_Response
+    if not "ReadScopeSilo_Response" in globals(): ReadScopeSilo_Response = namedtuple("ReadScopeSilo_Response", "Type,CenterX,CenterY,Radius,Pos2X,Pos2Y,ZHigh,RefX,RefY,RefZ")
+    return ReadScopeSilo_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def NewProjectFile(FileName=""):
+    """
+    Alerts applications if the project file was changed.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("NewProjectFile",FileName)
+
+
+def SaveProjectFile(FileName=""):
+    """
+    Alerts applications to save the current project.  This notification _MUST_ only
+    be invoked by CommonCommands. Sending this notification directly _WILL_ give
+    erroneous results.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectFile",FileName)
+
+
+def NewAccessLevel(AccessLevel="", UserName="", VeloxLocked=""):
+    """
+    Alerts applications of new access level.
+    API Status: published
+    Args:
+        AccessLevel:str = "Engineer"
+        UserName:str = ""
+        VeloxLocked:int = 0
+    Command Timeout: 5000
+    Example:NewAccessLevel 1
+    """
+    MessageServerInterface.sendSciCommand("NewAccessLevel",AccessLevel,UserName,VeloxLocked)
+
+
+def LicenseInfo(AnnualEnabled="", AnnualDaysLeft="", VeloxProEnabled="", VueTrackEnabled="", VueTrack4PEnabled="", ReAlignEnabled="", AutomationEnabled="", IdToolsEnabled="", IVistaEnabled="", IVistaProEnabled="", LaserCutterEnabled="", SiPToolsEnabled="", AutoRfEnabled=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifys the listener about the licensed Velox features. Is sent cyclically by
+    CommonCommands.
+    API Status: internal
+    Args:
+        AnnualEnabled:int = 1
+        AnnualDaysLeft:int = 460
+        VeloxProEnabled:int = 0
+        VueTrackEnabled:int = 0
+        VueTrack4PEnabled:int = 0
+        ReAlignEnabled:int = 0
+        AutomationEnabled:int = 0
+        IdToolsEnabled:int = 0
+        IVistaEnabled:int = 0
+        IVistaProEnabled:int = 0
+        LaserCutterEnabled:int = 0
+        SiPToolsEnabled:int = 0
+        AutoRfEnabled:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LicenseInfo",AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled)
+
+
+def RegisterProberAppChange(AppName="", SecName="", NewRegistered=""):
+    """
+    Alerts applications that an application is registered or unregistered on
+    MsgServer.
+    API Status: published
+    Args:
+        AppName:str = "SharedTest"
+        SecName:str = "SharedTest"
+        NewRegistered:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("RegisterProberAppChange",AppName,SecName,NewRegistered)
+
+
+def AlignmentModeChange(AlignmentMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications of a change of the current alignment mode
+    API Status: internal
+    Args:
+        AlignmentMode:str = "OnAxis"
+    Command Timeout: 5000
+    Example:AlignmentModeChange OnAxis
+    """
+    MessageServerInterface.sendSciCommand("AlignmentModeChange",AlignmentMode)
+
+
+def KernelConnectionStatus(ControllerNum="", Type="", Result="", Desc=""):
+    """
+    An example of Kernel Connection Status is &quot;Windows Socket Error Number and
+    Error Description.&quot;
+    API Status: published
+    Args:
+        ControllerNum:int = 1
+        Type:str = "Socket"
+        Result:str = "Disconnected"
+        Desc:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelConnectionStatus",ControllerNum,Type,Result,Desc)
+
+
+def KernelCompensationStatusChange(Stage="", Compensation="", Enabled="", Active=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications that a Kernel compensation has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Compensation:str = "None"
+        Enabled:int = 0
+        Active:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelCompensationStatusChange",Stage,Compensation,Enabled,Active)
+
+
+def KernelCompensationLevelChange(Stage="", Comp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications that a Kernel compensation level has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Comp:str = "None"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelCompensationLevelChange",Stage,Comp)
+
+
+def MoveZCombinedStatusChange(Status="", PlatenSafe="", Height="", HeightMax="", HeightRelative="", SafeHeight="", Message=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies about changes in the combined-z-move-system
+    API Status: internal
+    Args:
+        Status:str = "Off"
+        PlatenSafe:int = 0
+        Height:Decimal = 0
+        HeightMax:Decimal = 0
+        HeightRelative:Decimal = 0
+        SafeHeight:Decimal = 0
+        Message:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombinedStatusChange",Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message)
+
+
+def MachineStateChange(MachineState=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies about changes in the machine state
+    API Status: internal
+    Args:
+        MachineState:str = "Off"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MachineStateChange",MachineState)
+
+
+def ChuckVacuumChangeRequest(VacuumState=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies if the user requests a chuck vacuum change
+    API Status: internal
+    Args:
+        VacuumState:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ChuckVacuumChangeRequest",VacuumState)
+
+
+def SoftwareStopChangedNotify(SoftwareStopState=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies if software stop was activated or deactivated
+    API Status: internal
+    Args:
+        SoftwareStopState:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SoftwareStopChangedNotify",SoftwareStopState)
+
+
+def KernelQuietModeChange(IsQuiet="", Stage="", IsStageQuiet=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Informs if the overall quiet mode changes and about changes of single stages
+    API Status: internal
+    Args:
+        IsQuiet:int = 0
+        Stage:str = "None"
+        IsStageQuiet:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelQuietModeChange",IsQuiet,Stage,IsStageQuiet)
+
+
+def ConfigurationChanged(ParameterChanged=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies that a configuration item has changed by some application
+    API Status: internal
+    Args:
+        ParameterChanged:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ConfigurationChanged",ParameterChanged)
+
+
+def ScopeWorkingStageChanged(ScopeWorkingStage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Informs that a new working stage is active
+    API Status: internal
+    Args:
+        ScopeWorkingStage:int = -1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ScopeWorkingStageChanged",ScopeWorkingStage)
+
+
+def BnR_AxisNotify(Stage="", Axis="", State="", AdditionalStateInfo=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the user Interface and Kernel if the state of the axis has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        State:str = "NotExisting"
+        AdditionalStateInfo:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AxisNotify",Stage,Axis,State,AdditionalStateInfo)
+
+
+def BnR_StageNotify(Stage="", State=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the stage status has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_StageNotify",Stage,State)
+
+
+def BnR_InputNotify(Channel="", State=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state of an input channel has changed.
+    API Status: internal
+    Args:
+        Channel:str = "0"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_InputNotify",Channel,State)
+
+
+def BnR_OutputNotify(Channel="", State=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state of an output channel has changed.
+    API Status: internal
+    Args:
+        Channel:str = "0"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_OutputNotify",Channel,State)
+
+
+def BnR_AxisStatusNotify(Stage="", Axis="", Initialized="", PositiveLimit="", NegativeLimit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifys the listener that an axis status has changed. Currently used to notify
+    the Kernel about the init state of a BnR axis.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        Initialized:int = 0
+        PositiveLimit:int = 0
+        NegativeLimit:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AxisStatusNotify",Stage,Axis,Initialized,PositiveLimit,NegativeLimit)
+
+
+def AutoXYModeChange(AutoXYModeOn=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent by Spectrum if Automation was enabled or disabled. This can be AutoXY,
+    AutoZ or VueTrack. Handled by WaferMap to ensure that automation is executed
+    when stepping.
+    API Status: internal
+    Args:
+        AutoXYModeOn:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("AutoXYModeChange",AutoXYModeOn)
+
+
+def ZoomLevelChange(ZoomLevel=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent by OpticalControl when the AZoom zoom level is changed. Spectrum should
+    handle this so it doesn't have to poll OpticalControl for the current zoom
+    level.
+    API Status: internal
+    Args:
+        ZoomLevel:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ZoomLevelChange",ZoomLevel)
+
+
+def BnR_AnalogIONotify(AnalogIO="", ValuePercent="", UnderOverflow="", Error=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state or value of an analog input or output channel
+    has changed.
+    API Status: internal
+    Args:
+        AnalogIO:str = "AO_PurgeDewPoint"
+        ValuePercent:Decimal = 0
+        UnderOverflow:int = 0
+        Error:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AnalogIONotify",AnalogIO,ValuePercent,UnderOverflow,Error)
+
+
+def BnR_ControllerInfoNotify(ControllerNum="", ControllerInfo="", Value=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies the listener about changed controller info. Currently used to inform
+    Toolbar about the battery state of the BnR controller.
+    API Status: internal
+    Args:
+        ControllerNum:int = 1
+        ControllerInfo:str = "BatteryOK"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_ControllerInfoNotify",ControllerNum,ControllerInfo,Value)
+
+
+def BnR_PositionNotify(Stage="", XorT="", Y="", Z="", CommandedXorT="", CommandedY="", CommandedZ=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent by BnR controller if a axis position has changed. Currently
+    used to notify the Kernel about the new axis position.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XorT:Decimal = 0
+        Y:Decimal = 0
+        Z:Decimal = 0
+        CommandedXorT:Decimal = 0
+        CommandedY:Decimal = 0
+        CommandedZ:Decimal = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_PositionNotify",Stage,XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ)
+
+
+def BnR_InfoNotify(InfoType="", Info=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Generic Information Notification
+    API Status: internal
+    Args:
+        InfoType:str = ""
+        Info:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_InfoNotify",InfoType,Info)
+
+
+def WMNewCurrentDie(DieX="", DieY="", XFromHome="", YFromHome="", CurSite="", LastSiteIndex=""):
+    """
+    Alerts applications that WaferMap has a new position.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        XFromHome:Decimal = 0
+        YFromHome:Decimal = 0
+        CurSite:int = 1
+        LastSiteIndex:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("WMNewCurrentDie",DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex)
+
+
+def WMSetupChange():
+    """
+    Alerts applications that a wafer's parameters have been changed.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("WMSetupChange")
+
+
+def ButtonPress(TargetIdent=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent when button instrumented for guided workflow is pressed. The TargetIdent is
+    the identifier for the button as defined for the guided workflow.
+    API Status: internal
+    Args:
+        TargetIdent:int = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("ButtonPress",TargetIdent)
+
+
+def CryoCmdReady(State="", Error="", ErrorDescription=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent when the cooling or heating process was terminated successfully or
+    incorrectly. Returns the status with which the process was finished (IDLE, COLD,
+    COOL DOWN, WARMUP) and sends the error code and error message.
+    API Status: internal
+    Args:
+        State:str = "IDLE"
+        Error:int = 0
+        ErrorDescription:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CryoCmdReady",State,Error,ErrorDescription)
+
+
+def VMProjectLoaded():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification sent when Spectrum VS project has finished loading.
+    API Status: internal
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("VMProjectLoaded")
+
+
+def VMProbeCardData(Access="", FileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent when a probe card file is loaded.
+    API Status: internal
+    Args:
+        Access:str = "L"
+        FileName:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("VMProbeCardData",Access,FileName)
+
+
+def TTLTestDone():
+    """
+    Alerts applications that the TTL Test is ready.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("TTLTestDone")
+
+
+def PSStateChanged(State="", SubState="", Message="", Error=""):
+    """
+    Notification sent when VeloxPro changes its running state.
+    API Status: published
+    Args:
+        State:str = "Unknown"
+        SubState:str = "Unknown"
+        Message:str = ""
+        Error:int = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSStateChanged",State,SubState,Message,Error)
+
+
+def PSProgressChanged(ProgressPercent=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification sent during wafer stepping process. It updates the progress
+    information. 'Progress' is the relationship of dies tested to dies to be tested.
+    API Status: internal
+    Args:
+        ProgressPercent:Decimal = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSProgressChanged",ProgressPercent)
+
+
+def PSLoaderUsage(UseLoader="", UseAutoWafer="", WaferSizes=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent to notify the listener about usage of Loader, usage of
+    fully/semiautomatic mode and supported wafer sizes of process station.
+    API Status: internal
+    Args:
+        UseLoader:int = 0
+        UseAutoWafer:int = 0
+        WaferSizes:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSLoaderUsage",UseLoader,UseAutoWafer,WaferSizes)
+
+
+def LoaderMessage(Message=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent by loader to display a message on the process station.
+    API Status: internal
+    Args:
+        Message:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("LoaderMessage",Message)
+
+
+def OpenProjectDialog(ProjectFilename="", Option=""):
+    """
+    Asks if the current project should be saved and then brings up the Open Project
+    window which opens the selected project file if the user clicks ok.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+        Option:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("OpenProjectDialog",ProjectFilename,Option)
+
+
+def SaveProjectAsDialog():
+    """
+    Brings up the Save Project window which saves the project if the user clicks ok.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectAsDialog")
+
+
+def LoginDialog(LevelToOffer=""):
+    """
+    Brings up the Login window and sends a New Access Level alert if the user enters
+    a valid password.
+    API Status: published
+    Args:
+        LevelToOffer:str = "1"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LoginDialog",LevelToOffer)
+
+
+def GetStatus():
+    """
+    Returns the current software status. The server holds and maintains the software
+    status. Status can be changed by using any of the following commands:
+    BeginProbing, LoginDialog, AbortProbing, SetExternalMode, PauseProbing,
+    UnloadWafer, ResumeProbing
+    API Status: published
+    Returns:
+        DummyCommonMode:int
+        RunningMode:str
+        AccessLevel:str
+        ExternalMode:int
+        LicenseDaysLeft:int
+        MKH:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetStatus")
+    global GetStatus_Response
+    if not "GetStatus_Response" in globals(): GetStatus_Response = namedtuple("GetStatus_Response", "DummyCommonMode,RunningMode,AccessLevel,ExternalMode,LicenseDaysLeft,MKH")
+    return GetStatus_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def LicensingDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the Licensing window.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LicensingDialog")
+
+
+def GetLicenseInfo():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current license information.
+    API Status: internal
+    Returns:
+        AnnualEnabled:int
+        AnnualDaysLeft:int
+        VeloxProEnabled:int
+        VueTrackEnabled:int
+        VueTrack4PEnabled:int
+        ReAlignEnabled:int
+        AutomationEnabled:int
+        IdToolsEnabled:int
+        IVistaEnabled:int
+        IVistaProEnabled:int
+        LaserCutterEnabled:int
+        SiPToolsEnabled:int
+        AutoRfEnabled:int
+        SecsGemEnabled:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLicenseInfo")
+    global GetLicenseInfo_Response
+    if not "GetLicenseInfo_Response" in globals(): GetLicenseInfo_Response = namedtuple("GetLicenseInfo_Response", "AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled,SecsGemEnabled")
+    return GetLicenseInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]))
+
+def GetProjectFile():
+    """
+    Returns the current project file.
+    API Status: published
+    Returns:
+        ProjectFilename:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProjectFile")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportSoftwareVersion():
+    """
+    Returns the Velox software version as string.
+    API Status: published
+    Returns:
+        SoftwareVersion:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReportSoftwareVersion")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OpenProject(ProjectFilename=""):
+    """
+    The OpenProject command opens the specified project.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("OpenProject",ProjectFilename)
+
+
+def IsAppRegistered(Application=""):
+    """
+    Checks the server to see if the application "AppName" is registered with the
+    server.
+    API Status: published
+    Args:
+        Application:str = ""
+    Returns:
+        IsAppRegistered:int
+    Command Timeout: 5000
+    Example:IsAppRegistered WaferMap
+    """
+    rsp = MessageServerInterface.sendSciCommand("IsAppRegistered",Application)
+    return int(rsp[0])
+
+def SaveProject(ProjectFilename=""):
+    """
+    Saves the current data to the project file.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("SaveProject",ProjectFilename)
+
+
+def GetSoftwarePath(PathType=""):
+    """
+    Returns the path for either the applications/data or project files.
+    API Status: published
+    Args:
+        PathType:str = "User"
+    Returns:
+        SoftwarePath:str
+    Command Timeout: 5000
+    Example:GetSoftwarePath User
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwarePath",PathType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CCSelectLens(Lens=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Internal AZoom Helper Command.
+    API Status: internal
+    Args:
+        Lens:int = 1
+    Command Timeout: 10000
+    Example:CCSelectLens 1
+    """
+    MessageServerInterface.sendSciCommand("CCSelectLens",Lens)
+
+
+def CCReadCurrentLens():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Internal AZoom Helper Command. Probably no longer used.
+    API Status: internal
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CCReadCurrentLens")
+    return int(rsp[0])
+
+def CCMoveAuxSite(AuxID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command calls the Kernel command MoveAuxSite to move the chuck to the
+    position of a given AUX site. For the transfer move a safe height is used. If
+    AUX ID is set to 0, the target of the move is the wafer site. If the flag 'Auto
+    Align by Spectrum' in ControlCenter-SystemSetup-Aux Sites is True, the Spectrum
+    command AlignAux is executed after MoveAuxSite to align the site automatically.
+    The flag is only visible, if the aux site type is CalSubstrate and Spectrum is
+    installed. AUX ID in the response is the ID of the new active site.
+    API Status: internal
+    Args:
+        AuxID:int = 1
+    Command Timeout: 200000
+    """
+    MessageServerInterface.sendSciCommand("CCMoveAuxSite",AuxID)
+
+
+def ExecuteCleaningSequence(SequenceName="", AllowMediaReuse="", SkipAlignAux="", SkipReturnMove=""):
+    """
+    This command moves to the single cleaning site, executes CleanProbeTip, moves to
+    the contact verify site, and then moves to contact. Returns an error if the
+    clean or verify sites aren't defined.
+    API Status: published
+    Args:
+        SequenceName:str = ""
+        AllowMediaReuse:int = 0
+        SkipAlignAux:int = 0
+        SkipReturnMove:int = 0
+    Command Timeout: 1800000
+    Example:ExecuteCleaningSequence "DeepClean"
+    """
+    MessageServerInterface.sendSciCommand("ExecuteCleaningSequence",SequenceName,AllowMediaReuse,SkipAlignAux,SkipReturnMove)
+
+
+def GetAlignmentMode():
+    """
+    Get the active alignment mode (either on axis or off axis).
+    API Status: published
+    Returns:
+        AlignmentMode:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAlignmentMode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetAlignmentMode(AlignmentMode=""):
+    """
+    Sets the active alignment mode (either on axis or off axis).
+    API Status: published
+    Args:
+        AlignmentMode:str = "OnAxis"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SetAlignmentMode",AlignmentMode)
+
+
+def GetLoginData(CmdUserName=""):
+    """
+    Gets the Velox user data: name, full name, group, access level.     If the
+    commanded user name is empty, the data of the current user will be responded
+    API Status: published
+    Args:
+        CmdUserName:str = ""
+    Returns:
+        UserName:str
+        LongUserName:str
+        UserGroup:str
+        AccessLevel:str
+        VeloxLocked:int
+    Command Timeout: 5000
+    Example:GetLoginData
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLoginData",CmdUserName)
+    global GetLoginData_Response
+    if not "GetLoginData_Response" in globals(): GetLoginData_Response = namedtuple("GetLoginData_Response", "UserName,LongUserName,UserGroup,AccessLevel,VeloxLocked")
+    return GetLoginData_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]))
+
+def NucleusInitChuck():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up message box to warn user of chuck initialization for Nucleus stations.
+    Allows user to OK/Cancel.
+    API Status: internal
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("NucleusInitChuck")
+
+
+def ShutdownVeloxWithSave():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up message box to allow saving project before shutting down Velox. Allows
+    user to OK/Cancel.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ShutdownVeloxWithSave")
+
+
+def WinCalAutoCal():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalAutoCal command to WinCal.
+    API Status: internal
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalAutoCal")
+
+
+def WinCalCheckAutoRFStability(AllowMove=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalCheckAutoRFStability command to WinCal.
+    API Status: internal
+    Args:
+        AllowMove:int = 0
+    Returns:
+        StabilityPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalCheckAutoRFStability",AllowMove)
+    return int(rsp[0])
+
+def WinCalCloseRFStabilityReport():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalCloseRFStabilityReport command to WinCal.
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalCloseRFStabilityReport")
+
+
+def WinCalMoveToIssRef(IssIdx=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalMoveToIssRef command to WinCal to move to the specified ISS
+    reference.     The ISS index is the IssIdxMap index as returned from
+    WinCalGetIssListForAuxSite.
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("WinCalMoveToIssRef",IssIdx)
+
+
+def WinCalVerifyIssRefLocAtHome(IssIdx=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalVerifyIssRefLocAtHome command to WinCal and returns AllRefAtHome
+    as 1 if stage and positioners at home.
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Returns:
+        AllRefAtHome:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalVerifyIssRefLocAtHome",IssIdx)
+    return int(rsp[0])
+
+def WinCalGetIssForAuxSite(AuxID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalGetIssForAuxSite command to WinCal and returns the ISS
+    information for the given aux site ID.
+    API Status: internal
+    Args:
+        AuxID:int = 0
+    Returns:
+        IssIdx:int
+        IssPN:str
+        IssDescription:str
+        IssEnabled:int
+        AuxSiteName:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetIssForAuxSite",AuxID)
+    global WinCalGetIssForAuxSite_Response
+    if not "WinCalGetIssForAuxSite_Response" in globals(): WinCalGetIssForAuxSite_Response = namedtuple("WinCalGetIssForAuxSite_Response", "IssIdx,IssPN,IssDescription,IssEnabled,AuxSiteName")
+    return WinCalGetIssForAuxSite_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def WinCalGetNameAndVersion():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalGetNameAndVersion command to WinCal.
+    API Status: internal
+    Returns:
+        ServerName:str
+        Version:str
+        MajorVersion:int
+        MinorVersion:int
+        Revision:int
+        Build:int
+    Command Timeout: 30000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNameAndVersion")
+    global WinCalGetNameAndVersion_Response
+    if not "WinCalGetNameAndVersion_Response" in globals(): WinCalGetNameAndVersion_Response = namedtuple("WinCalGetNameAndVersion_Response", "ServerName,Version,MajorVersion,MinorVersion,Revision,Build")
+    return WinCalGetNameAndVersion_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def WinCalMonitorNoMove():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalMonitorNoMove command to WinCal. Triggers WinCal to measure the
+    monitor portion of the current calibration setup.
+    API Status: internal
+    Returns:
+        MonitorPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalMonitorNoMove")
+    return int(rsp[0])
+
+def WinCalValidateAdvanced(ProbeSpacing="", ResetTrace="", AllowMove=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalValidateAdvanced command to WinCal. Performs the validation step of
+    the currently selected calibration setup.     Resets the controller used in WinCal
+    for validataion.
+    API Status: internal
+    Args:
+        ProbeSpacing:Decimal = 130
+        ResetTrace:int = 1
+        AllowMove:int = 1
+    Returns:
+        ValidationPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalValidateAdvanced",ProbeSpacing,ResetTrace,AllowMove)
+    return int(rsp[0])
+
+def WinCalMeasureMonitorReference(AllowMove=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalMeasureMonitorReference command to WinCal.
+    API Status: internal
+    Args:
+        AllowMove:int = 0
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalMeasureMonitorReference",AllowMove)
+
+
+def WinCalGetNumValidationPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumValidationPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumValidationPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumValidationPorts")
+    return int(rsp[0])
+
+def WinCalSetNumValidationPorts(NumValidationPorts=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumValidationPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumValidationPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumValidationPorts",NumValidationPorts)
+
+
+def WinCalGetNumMonitoringPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumMonitoringPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumMonitoringPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumMonitoringPorts")
+    return int(rsp[0])
+
+def WinCalSetNumMonitoringPorts(NumMonitoringPorts=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumMonitoringPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumMonitoringPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumMonitoringPorts",NumMonitoringPorts)
+
+
+def WinCalGetNumRepeatabilityPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumRepeatabilityPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumRepeatabilityPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumRepeatabilityPorts")
+    return int(rsp[0])
+
+def WinCalSetNumRepeatabilityPorts(NumRepeatabilityPorts=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumRepeatabilityPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumRepeatabilityPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumRepeatabilityPorts",NumRepeatabilityPorts)
+
+
+def WinCalValidate():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalValidate command to WinCal. Performs the validation step of the
+    currently selected calibration setup in WinCal.
+    API Status: internal
+    Returns:
+        ValidationPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalValidate")
+    return int(rsp[0])
+
+def WinCalGetValidationSetup(Port=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends CalGetValidationSetup command to WinCal. Returns calibration setup
+    parameters.
+    API Status: internal
+    Args:
+        Port:int = 1
+    Returns:
+        StandardType:str
+        StandardPorts:int
+        StandardCompareType:int
+        StructureType:str
+        PostCorrect:int
+        PostCorrectMatching:int
+        AutoConfigure:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetValidationSetup",Port)
+    global WinCalGetValidationSetup_Response
+    if not "WinCalGetValidationSetup_Response" in globals(): WinCalGetValidationSetup_Response = namedtuple("WinCalGetValidationSetup_Response", "StandardType,StandardPorts,StandardCompareType,StructureType,PostCorrect,PostCorrectMatching,AutoConfigure")
+    return WinCalGetValidationSetup_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def WinCalAutoCalNoValidation(ProbeSpacing=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalAutoCalNoValidation command to WinCal. Performs an AutoCal
+    without the validation step
+    API Status: internal
+    Args:
+        ProbeSpacing:Decimal = 130
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalAutoCalNoValidation",ProbeSpacing)
+
+
+def WinCalHideAllWindows():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalHideAllWindows command to WinCal. This minimizes all the WinCal
+    windows
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalHideAllWindows")
+
+
+def WinCalGetReferenceStructureInfo(IssIdx=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetReferenceStructureInfo command to WinCal. Given the WinCal ISS
+    index it will return a string with the reference information
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Returns:
+        ReferenceInfo:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetReferenceStructureInfo",IssIdx)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def WinCalSystemSetupHasUnappliedChanges(ShowErrors=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalSystemSetupHasUnappliedChanges command to WinCal. Returns true
+    if WinCal has unapplied changes
+    API Status: internal
+    Args:
+        ShowErrors:int = 0
+    Returns:
+        HasUnappliedChanges:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalSystemSetupHasUnappliedChanges",ShowErrors)
+    return int(rsp[0])
+
+def WinCalRecordIssRefAtCurrentLoc(IssIdx=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalRecordIssRefAtCurrentLoc command to WinCal. Record the ISS,
+    indicated by the index, reference as being the current location
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalRecordIssRefAtCurrentLoc",IssIdx)
+
+
+def SaveProjectAsTemplateDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the Save Project as Template window which saves the project template
+    if the user clicks ok.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectAsTemplateDialog")
+
+
+def CreateProjectFromTemplateDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the New Project from Template dialog which allows the user to select a
+    template and create a new project.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CreateProjectFromTemplateDialog")
+
+
+def WinCalGetNumPortsAndProbes():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns Max Ports and Number of probes connected to a port
+    API Status: internal
+    Returns:
+        MaxPorts:int
+        NumPortsConnectedtoProbes:int
+    Command Timeout: 1000
+    Example:WinCalGetNumPortsAndProbes
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumPortsAndProbes")
+    global WinCalGetNumPortsAndProbes_Response
+    if not "WinCalGetNumPortsAndProbes_Response" in globals(): WinCalGetNumPortsAndProbes_Response = namedtuple("WinCalGetNumPortsAndProbes_Response", "MaxPorts,NumPortsConnectedtoProbes")
+    return WinCalGetNumPortsAndProbes_Response(int(rsp[0]),int(rsp[1]))
+
+def WinCalGetProbeInfoForPort(VnaPortNum=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the properties from one probe, based on the passed in index. Pass in a
+    physical VNA port number that is less than or equal to Max Probes from the call
+    to CalGetNumPortsAndProbes
+    API Status: internal
+    Args:
+        VnaPortNum:int = 1
+    Returns:
+        IsSelected:int
+        BaseProbe:str
+        Options:str
+        PhysicalOrient:str
+        IsDual:int
+        IsSymmetric:int
+        SignalConfig:str
+        SelectedPitch:int
+    Command Timeout: 1000
+    Example:WinCalGetProbeInfoForPort 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetProbeInfoForPort",VnaPortNum)
+    global WinCalGetProbeInfoForPort_Response
+    if not "WinCalGetProbeInfoForPort_Response" in globals(): WinCalGetProbeInfoForPort_Response = namedtuple("WinCalGetProbeInfoForPort_Response", "IsSelected,BaseProbe,Options,PhysicalOrient,IsDual,IsSymmetric,SignalConfig,SelectedPitch")
+    return WinCalGetProbeInfoForPort_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),str(rsp[6]),int(rsp[7]))
+
+def GetMachineState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current state of the machine.
+    API Status: internal
+    Returns:
+        MachineState:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMachineState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowAboutDialog(Pid=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shows the help about dialog for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ShowAboutDialog",Pid)
+
+
+def ShowSplashScreen(Pid="", TimeoutMs=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shows the splash screen for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+        TimeoutMs:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ShowSplashScreen",Pid,TimeoutMs)
+
+
+def CloseSplashScreen(Pid=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the splash screen for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("CloseSplashScreen",Pid)
+
+
+def GetLastFourProjects():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the last four project files that were opened.
+    API Status: internal
+    Returns:
+        ProjectFile1:str
+        ProjectFile2:str
+        ProjectFile3:str
+        ProjectFile4:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLastFourProjects")
+    global GetLastFourProjects_Response
+    if not "GetLastFourProjects_Response" in globals(): GetLastFourProjects_Response = namedtuple("GetLastFourProjects_Response", "ProjectFile1,ProjectFile2,ProjectFile3,ProjectFile4")
+    return GetLastFourProjects_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def WinCalExecuteCommand(Command=""):
+    """
+    Sends the WinCalExecuteCommand command to WinCal and returns the response
+    string.
+    API Status: published
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalExecuteCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDemoMode(TurnOnDemoMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+    This command will return an error if its called with any other parameter as 0.
+    API Status: internal
+    Args:
+        TurnOnDemoMode:int = 1
+    Command Timeout: 5000
+    Example:SetDemoMode 0
+    """
+    MessageServerInterface.sendSciCommand("SetDemoMode",TurnOnDemoMode)
+
+
+def ChangeDemoRsp(Param=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Override a command with a demo response. The command will not reach its
+    destination but the supplied demo response will be returned. An active overide
+    for a command will be removed if the provided timeout is negative. Format:  [ID]
+    [Time] [ErrorCode]:[Response]  - Id: command id in hex withoud leding 0x - Time:
+    time in ms between command and response, negativ to reset demo mode for this
+    command - Errorcode: 0 for success, everything else indicates an error -
+    Response: response string
+    API Status: internal
+    Args:
+        Param:str = ""
+    Command Timeout: 5000
+    Example:ChangeDemoRsp 31 200 0:5000.0 5000.0 8500
+    """
+    MessageServerInterface.sendSciCommand("ChangeDemoRsp",Param)
+
+
+def GetDemoMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+    This command will always return 0.
+    API Status: internal
+    Returns:
+        DemoModeOn:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDemoMode")
+    return int(rsp[0])
+
+def ResetNetworkPort(Param=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    (Re)sets the IP address and listen port of the socket to which the NetworkDriver
+    tries to connect to (IP address and listen port of Kernel socket). Dummy
+    implementation for Kernel to support backwards.
+    API Status: internal
+    Args:
+        Param:str = ""
+    Command Timeout: 10000
+    Example:ResetNetworkPort 192.168.3.1 10000
+    """
+    MessageServerInterface.sendSciCommand("ResetNetworkPort",Param)
+
+
+def GetNDriverClientStatus(ClientNum="", Param=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets status information about the connection NetworkDriver to Kernel. Socket
+    Error is the Windows socket error, Description the Windows socket error
+    description. If Socket Error is 0, the description 'Registered' informs that the
+    Kernel is ready to receive Remote Commands.
+    API Status: internal
+    Args:
+        ClientNum:int = 1
+        Param:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 5000
+    Example:GetNDriverClientStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNDriverClientStatus",ClientNum,Param)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OverrideCommandTimeout(CmdID="", TimeoutMilliSec=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows specifying a separate command timeout for a single instance
+    of a command. This is especially useful if the application that receives a
+    command knows how long a command will take.  This command had been added for
+    SoakTime-handling of StepNextDie. A safe guess for the timeout of StepNextDie is
+    5s.
+    API Status: internal
+    Args:
+        CmdID:int = 0
+        TimeoutMilliSec:int = 1000
+    Command Timeout: 5000
+    Example:OverrideCommandTimeout 3234 20000
+    """
+    MessageServerInterface.sendSciCommand("OverrideCommandTimeout",CmdID,TimeoutMilliSec)
+
+
+def ShutdownVelox(IgnorePID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shutdown all Velox applications in an ordered fashion. When this command returns
+    success, all non-mandatory apps are closed and the mandatory ones will follow
+    shortly
+    API Status: internal
+    Args:
+        IgnorePID:int = 0
+    Command Timeout: 120000
+    Example:ShutdownVelox
+    """
+    MessageServerInterface.sendSciCommand("ShutdownVelox",IgnorePID)
+
+
+def InitializationDone(CommandGroup=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Registration of an application can be delayed. To trigger this behavior,
+    RegisterProberApp has to be called with flag 3 set (0x04). From
+    RegisterProberApp to the time this command is sent, the application can send
+    commands but can't receive commands. This is necessary because some application
+    have to communicate with others during initialization and can not handle
+    commands properly during this time.  The command group is necessary because of
+    architectural reasons (By design, the command receiver does not now the sender
+    of a command).
+    API Status: internal
+    Args:
+        CommandGroup:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("InitializationDone",CommandGroup)
+
+
+def StepFirstZProfilePoint(XPos="", YPos="", NumberOfPoints="", NumberOfEPoints=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command goes to the first Z Profile Point, adjusts Z (in the automatic mode
+    only) and pauses after it (even in the automatic mode)
+    API Status: internal
+    Args:
+        XPos:Decimal = 0
+        YPos:Decimal = 0
+        NumberOfPoints:int = 0
+        NumberOfEPoints:int = 0
+    Command Timeout: 60000
+    Example:StepFirstZProfilePoint 10000 20000 5 5
+    """
+    MessageServerInterface.sendSciCommand("StepFirstZProfilePoint",XPos,YPos,NumberOfPoints,NumberOfEPoints)
+
+
+def StepNextZProfilePoint(Point=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command calculates a delta value for the current point and then moves to
+    the specified point (if it's presented) or to the next one. Note, that in case
+    of the automatic Z detecting a return ZDelta parameter is a value for the
+    current point, but in case of the semiautomatic mode the command returns ZDelta
+    as a value for a previous tested point. If the profiling is finished this
+    command will return #807 error (End of the profile). Point indices are started
+    from 1 (1 is first, 2 is second, and so on).
+    API Status: internal
+    Args:
+        Point:int = 0
+    Returns:
+        XPos:Decimal
+        YPos:Decimal
+        Delta:Decimal
+        CurPoint:int
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 60000
+    Example:StepNextZProfilePoint 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextZProfilePoint",Point)
+    global StepNextZProfilePoint_Response
+    if not "StepNextZProfilePoint_Response" in globals(): StepNextZProfilePoint_Response = namedtuple("StepNextZProfilePoint_Response", "XPos,YPos,Delta,CurPoint,NumberOfPoints,NumberOfEPoints")
+    return StepNextZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def SetZProfileOptions(ProfileMode="", SepSpeed="", ProfileSensor="", Stage="", SearchSpeed="", Gap="", Units="", ClearElectronics="", ClearRefZ="", Inaccuracy=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets some Z Profile Program Options remotely.
+    API Status: internal
+    Args:
+        ProfileMode:str = "S"
+        SepSpeed:Decimal = 25
+        ProfileSensor:str = "E"
+        Stage:str = "C"
+        SearchSpeed:Decimal = 50
+        Gap:Decimal = 10
+        Units:str = "Y"
+        ClearElectronics:int = 1
+        ClearRefZ:int = 1
+        Inaccuracy:Decimal = 0
+    Command Timeout: 10000
+    Example:SetZProfileOptions S 25 E C 50 10 Y 1 1 0
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileOptions",ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy)
+
+
+def GetZProfileOptions():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return predefined settings of the Z Profile Program.
+    API Status: internal
+    Returns:
+        ProfileMode:str
+        SepSpeed:Decimal
+        ProfileSensor:str
+        Stage:str
+        SearchSpeed:Decimal
+        Gap:Decimal
+        Units:str
+        ClearElectronics:int
+        ClearRefZ:int
+        Inaccuracy:Decimal
+    Command Timeout: 10000
+    Example:GetZProfileOptions
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileOptions")
+    global GetZProfileOptions_Response
+    if not "GetZProfileOptions_Response" in globals(): GetZProfileOptions_Response = namedtuple("GetZProfileOptions_Response", "ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy")
+    return GetZProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str(rsp[6]),int(rsp[7]),int(rsp[8]),Decimal(rsp[9]))
+
+def OpenZProfileFile(FileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command opens the file inside of the Z Profiling.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 240000
+    Example:OpenZProfileFile Profile1
+    """
+    rsp = MessageServerInterface.sendSciCommand("OpenZProfileFile",FileName)
+    global OpenZProfileFile_Response
+    if not "OpenZProfileFile_Response" in globals(): OpenZProfileFile_Response = namedtuple("OpenZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+    return OpenZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def SaveZProfileFile(FileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves the current profile in the specified file.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:SaveZProfileFile Profile1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SaveZProfileFile",FileName)
+    global SaveZProfileFile_Response
+    if not "SaveZProfileFile_Response" in globals(): SaveZProfileFile_Response = namedtuple("SaveZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+    return SaveZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadZProfile(NewOrigin=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read a profile from the ProberBench Electronics II to the application. Return a
+    number of available points.
+    API Status: internal
+    Args:
+        NewOrigin:str = "Z"
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:ReadZProfile H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadZProfile",NewOrigin)
+    return int(rsp[0])
+
+def SetZProfile():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Uploads the current profile to the ProberBench Electronics II. Returns a number
+    of written points.
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:SetZProfile
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetZProfile")
+    return int(rsp[0])
+
+def CloseZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the Z-Profiling application.
+    API Status: internal
+    Command Timeout: 5000
+    Example:CloseZProfiling
+    """
+    MessageServerInterface.sendSciCommand("CloseZProfiling")
+
+
+def SetZProfileStartPoint(X="", Y="", PosRef="", Units=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets new start point for the profile. All points of the profile will be shifted
+    accordingly.
+    API Status: internal
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        PosRef:str = "Z"
+        Units:str = "Y"
+    Command Timeout: 10000
+    Example:SetZProfileStartPoint 0 0 H Y
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileStartPoint",X,Y,PosRef,Units)
+
+
+def GetZProfilingStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a status of the profiling process. If this status is true it means the
+    process is started.
+    API Status: internal
+    Returns:
+        Started:int
+    Command Timeout: 10000
+    Example:GetZProfilingStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfilingStatus")
+    return int(rsp[0])
+
+def StopZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the profiling process.
+    API Status: internal
+    Command Timeout: 10000
+    Example:StopZProfiling
+    """
+    MessageServerInterface.sendSciCommand("StopZProfiling")
+
+
+def SetZProfileOrigin(Pos="", X="", Y="", Z=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets an origin for the profile. If the origin position is H the command ignores
+    X and Y parameters. If Z is None the command clears Z value of the origin.
+    Otherwise it tries to extract a double value from the string and set it.
+    API Status: internal
+    Args:
+        Pos:str = "H"
+        X:Decimal = 0
+        Y:Decimal = 0
+        Z:str = "None"
+    Command Timeout: 10000
+    Example:SetZProfileOrigin H 0 0 None
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileOrigin",Pos,X,Y,Z)
+
+
+def GetZProfileOrigin():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current parameters of the profile origin. If the origin Z has no value
+    the return string for it will be None, otherwise it consists a double value of
+    the profile Z.
+    API Status: internal
+    Returns:
+        Pos:str
+        X:Decimal
+        Y:Decimal
+        Z:str
+    Command Timeout: 10000
+    Example:GetZProfileOrigin
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileOrigin")
+    global GetZProfileOrigin_Response
+    if not "GetZProfileOrigin_Response" in globals(): GetZProfileOrigin_Response = namedtuple("GetZProfileOrigin_Response", "Pos,X,Y,Z")
+    return GetZProfileOrigin_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def StartZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command works in the automatic mode only. It starts the profiling process,
+    profiles the entire wafer and then returns a number of tested points. This
+    command does upload the current profile to the ProberBench Electronics II. To do
+    it please use SetZProfile command
+    API Status: internal
+    Command Timeout: 10000
+    Example:StartZProfiling
+    """
+    MessageServerInterface.sendSciCommand("StartZProfiling")
+
+
+def ZProfileWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command works in the automatic mode only. It starts the profiling process,
+    profiles the entire wafer and then returns a number of tested points. This
+    command does upload the current profile to the ProberBench Electronics II. To do
+    it please use SetZProfile command
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 36000000
+    Example:ZProfileWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("ZProfileWafer")
+    global ZProfileWafer_Response
+    if not "ZProfileWafer_Response" in globals(): ZProfileWafer_Response = namedtuple("ZProfileWafer_Response", "NumberOfPoints,NumberOfEPoints")
+    return ZProfileWafer_Response(int(rsp[0]),int(rsp[1]))
+
+def GetZProfileStartPoint(PosRef="", Units=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current start point of the profile by using given units and a
+    reference position.
+    API Status: internal
+    Args:
+        PosRef:str = "Z"
+        Units:str = "Y"
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 10000
+    Example:GetZProfileStartPoint H Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileStartPoint",PosRef,Units)
+    global GetZProfileStartPoint_Response
+    if not "GetZProfileStartPoint_Response" in globals(): GetZProfileStartPoint_Response = namedtuple("GetZProfileStartPoint_Response", "X,Y")
+    return GetZProfileStartPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AddZProfilePoint(X="", Y="", After=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Adds new point to the profile at the end (default) or after the given point.
+    Returns an index of new point and a number of all points in the profile. Point
+    indices are started from 1.
+    API Status: internal
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        After:int = 0
+    Returns:
+        Index:int
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:AddZProfilePoint 50000 50000
+    """
+    rsp = MessageServerInterface.sendSciCommand("AddZProfilePoint",X,Y,After)
+    global AddZProfilePoint_Response
+    if not "AddZProfilePoint_Response" in globals(): AddZProfilePoint_Response = namedtuple("AddZProfilePoint_Response", "Index,NumberOfPoints,NumberOfEPoints")
+    return AddZProfilePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def DeleteZProfilePoint(Index=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Deletes the point from the profile. Returns a number of all and enabled points
+    in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:DeleteZProfilePoint 11
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteZProfilePoint",Index)
+    global DeleteZProfilePoint_Response
+    if not "DeleteZProfilePoint_Response" in globals(): DeleteZProfilePoint_Response = namedtuple("DeleteZProfilePoint_Response", "NumberOfPoints,NumberOfEPoints")
+    return DeleteZProfilePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def SetZProfilePointStatus(Index="", Status=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables the point in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+        Status:str = "0"
+    Command Timeout: 10000
+    Example:SetZProfilePointStatus 11 E
+    """
+    MessageServerInterface.sendSciCommand("SetZProfilePointStatus",Index,Status)
+
+
+def GetZProfilePointStatus(Index=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a status of the point in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    Example:GetZProfilePointStatus 11
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfilePointStatus",Index)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def PreciseZProfile():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    All points are covered by triangles, each vertex of the triangle is a point of
+    the profile. The centers of the triangles are new points of the profile. If all
+    three vertexes of the triangle are tested points the new point will be marked as
+    tested also and has Z value equal to average Z of all three vertexes. Otherwise
+    the new point will be marked as untested. The command returns a number of points
+    in the profile after the update.
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:PreciseZProfile
+    """
+    rsp = MessageServerInterface.sendSciCommand("PreciseZProfile")
+    return int(rsp[0])
+
+def CloseTableView():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the TableView application.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CloseTableView")
+
+
+def StepChuckSite(Site=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the wafer chuck stage to the requested Site no. of the chuck table view.
+    If no Site no is specified the chuck will step automatically to the next logical
+    site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepChuckSite",Site)
+    return int(rsp[0])
+
+def StepChuckSubsite(Site=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the wafer chuck stage to the requested Subsite no. of the chuck subsite
+    table view. If no Subsite no. is specified the chuck will step automatically to
+    the next logical site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepChuckSubsite",Site)
+    return int(rsp[0])
+
+def StepScopeSite(Site=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the microscope stage to the requested Site no. of the scope table view. If
+    no Site no is specified the scope will step automatically to the next logical
+    site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepScopeSite",Site)
+    return int(rsp[0])
+
+def StepProbeSite(Probe="", Site=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the specified probe to the requested Site no. of the Probe no table view.
+    If no Site no. is specified the Probe no. will step automatically to the next
+    logical site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Probe:int = -1
+        Site:int = -1
+    Returns:
+        ProbeRet:int
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepProbeSite",Probe,Site)
+    global StepProbeSite_Response
+    if not "StepProbeSite_Response" in globals(): StepProbeSite_Response = namedtuple("StepProbeSite_Response", "ProbeRet,SiteRet")
+    return StepProbeSite_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadChuckSitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual chuck site position. The first site in the table is site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckSitePosition")
+    global ReadChuckSitePosition_Response
+    if not "ReadChuckSitePosition_Response" in globals(): ReadChuckSitePosition_Response = namedtuple("ReadChuckSitePosition_Response", "Site,X,Y")
+    return ReadChuckSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeSitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the site position of the specified probe. The first site in the table is
+    site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSitePosition")
+    global ReadScopeSitePosition_Response
+    if not "ReadScopeSitePosition_Response" in globals(): ReadScopeSitePosition_Response = namedtuple("ReadScopeSitePosition_Response", "Site,X,Y")
+    return ReadScopeSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadProbeSitePosition(Probe=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the site position of the specified probe. The first site in the table is
+    site 1.
+    API Status: internal
+    Args:
+        Probe:int = -1
+    Returns:
+        ProbeRet:int
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeSitePosition",Probe)
+    global ReadProbeSitePosition_Response
+    if not "ReadProbeSitePosition_Response" in globals(): ReadProbeSitePosition_Response = namedtuple("ReadProbeSitePosition_Response", "ProbeRet,Site,X,Y")
+    return ReadProbeSitePosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadChuckSubsitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the chuck subsite position. The first site in the table is site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckSubsitePosition")
+    global ReadChuckSubsitePosition_Response
+    if not "ReadChuckSubsitePosition_Response" in globals(): ReadChuckSubsitePosition_Response = namedtuple("ReadChuckSubsitePosition_Response", "Site,X,Y")
+    return ReadChuckSubsitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def StepFirstDie(ClearBins="", RecalcRoute=""):
+    """
+    Steps the chuck to the first die of the wafer map. Returns the row and column
+    number of the actual die location after the move is completed. If ClearBins is
+    1, all binning data will be cleared from dies. If yes the route will be
+    recalculated. All dies marked to skip during the last test (marked to skip with
+    SetDieStatus) will be eliminated from the route.
+    API Status: published
+    Args:
+        ClearBins:int = 1
+        RecalcRoute:int = 1
+    Returns:
+        DieX:int
+        DieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFirstDie",ClearBins,RecalcRoute)
+    global StepFirstDie_Response
+    if not "StepFirstDie_Response" in globals(): StepFirstDie_Response = namedtuple("StepFirstDie_Response", "DieX,DieY,CurSite,LastSiteIndex")
+    return StepFirstDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def StepNextDie(CDieX="", CDieY="", Site=""):
+    """
+    Steps the chuck to the specified x,y die location of the wafer map. If no
+    command data is passed, the chuck automatically steps to the next logical wafer
+    map die location. Returns the row and column number of the actual die location
+    after the move is completed. In addition, the SubDie location, and total number
+    of SubDies is also returned.  If Site (i.e. SubDie) is -1, the chuck will move
+    to SubDie 0, on the next die; in this case, the first 2 parameters are ignored.
+    If sent without parameters, it will literally 'step to the next die'. When using
+    this command from shared code, use SendWithoutParameter().
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextDie",CDieX,CDieY,Site)
+    global StepNextDie_Response
+    if not "StepNextDie_Response" in globals(): StepNextDie_Response = namedtuple("StepNextDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return StepNextDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinMapDie(Bin="", CDieX="", CDieY=""):
+    """
+    Assigns the bin information to the wafer map at the current die, unless a row
+    and column is specified. Inks the device if the real time inking option (of the
+    wafer map) is enabled.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+    Command Timeout: 30000
+    Example:BinMapDie 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinMapDie",Bin,CDieX,CDieY)
+    global BinMapDie_Response
+    if not "BinMapDie_Response" in globals(): BinMapDie_Response = namedtuple("BinMapDie_Response", "RDieX,RDieY")
+    return BinMapDie_Response(int(rsp[0]),int(rsp[1]))
+
+def AssignMapBins(Bins=""):
+    """
+    Assigns the pass or fail information to the actual bin value. Redundant to
+    SetBinCode.
+    API Status: published
+    Args:
+        Bins:str = ""
+    Command Timeout: 10000
+    Example:AssignMapBins PFFFFFF
+    """
+    MessageServerInterface.sendSciCommand("AssignMapBins",Bins)
+
+
+def StepFailedBack():
+    """
+    Steps the chuck back the number of consecutive failed dies (goes back to the
+    last known good die) and returns the number of consecutive failed dies.
+    API Status: published
+    Returns:
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedBack")
+    return int(rsp[0])
+
+def StepFailedForward():
+    """
+    Steps the chuck forward the number of consecutive failed dies (goes to next
+    untested die).
+    API Status: published
+    Returns:
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedForward")
+    return int(rsp[0])
+
+def ReadMapPosition(Pos="", FromPos=""):
+    """
+    Returns the actual Wafer Map chuck position. The SubDie collection is 1-based,
+    the first value is 1, not 0.     M_pnCurSite returns the currently selected
+    Subdie (1-based) or 0 if no Subdie is currently selected. This command (i.e.
+    ReadMapPosition) has been included for legacy support.       ReadMapPosition2 is
+    the preferred method for reading Wafer Map chuck position.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        DieX:int
+        DieY:int
+        XFromHome:Decimal
+        YFromHome:Decimal
+        CurSite:int
+        LastSiteIndex:int
+        CurDie:int
+        DiesCount:int
+        CurCluster:int
+        ClustersCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapPosition",Pos,FromPos)
+    global ReadMapPosition_Response
+    if not "ReadMapPosition_Response" in globals(): ReadMapPosition_Response = namedtuple("ReadMapPosition_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+    return ReadMapPosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadMapYield():
+    """
+    Returns the actual wafer map yield data information.
+    API Status: published
+    Returns:
+        TotalDies:int
+        TestedDies:int
+        Passed:int
+        Failed:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapYield")
+    global ReadMapYield_Response
+    if not "ReadMapYield_Response" in globals(): ReadMapYield_Response = namedtuple("ReadMapYield_Response", "TotalDies,TestedDies,Passed,Failed")
+    return ReadMapYield_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinStepDie(Bin="", CDieX="", CDieY="", Site=""):
+    """
+    Bins the current die and steps the chuck to the next selected die location of
+    the wafer map (default) or steps to the specified Column and Row position, if
+    these values are passed.  In contrast to StepNextDie, the BinStepDie command
+    will only step from die to die while staying on the current subdie. It will not
+    step through the subdies so it cannot be used for subdie stepping.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    Example:BinStepDie 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinStepDie",Bin,CDieX,CDieY,Site)
+    global BinStepDie_Response
+    if not "BinStepDie_Response" in globals(): BinStepDie_Response = namedtuple("BinStepDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return BinStepDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetMapHome(DieX="", DieY=""):
+    """
+    If the command has no parameters it sets the current position as home position
+    both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+    home position using the given die coordinates.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapHome",DieX,DieY)
+
+
+def SaveMapFile(FileName="", FileType=""):
+    """
+    Saves current map file with specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+        FileType:str = "m"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SaveMapFile",FileName,FileType)
+
+
+def SetWaferMapMode(Mode=""):
+    """
+    Enables or disables an external mode for the application. In the external mode,
+    all controls are disabled. The application handles all its remote commands in
+    both modes. Special interactive modes can also be turned on.
+    API Status: published
+    Args:
+        Mode:str = ""
+    Returns:
+        ModeType:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetWaferMapMode",Mode)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetWaferMapMode(ModeType=""):
+    """
+    Returns whether the application is in external mode or not.
+    API Status: published
+    Args:
+        ModeType:str = ""
+    Returns:
+        Mode:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapMode",ModeType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferNum(Number=""):
+    """
+    Specifies the wafer number.
+    API Status: published
+    Args:
+        Number:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferNum",Number)
+
+
+def GetWaferNum():
+    """
+    Returns the wafer number for the current wafer.
+    API Status: published
+    Returns:
+        Number:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferNum")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferID(ID=""):
+    """
+    Specifies the ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferID",ID)
+
+
+def GetWaferID():
+    """
+    Returns the wafer ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetProductID(ID=""):
+    """
+    Specifies the product ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetProductID",ID)
+
+
+def GetProductID():
+    """
+    Displays the product ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProductID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DoInkerRun():
+    """
+    Instructs the WaferMap to perform an ink run on the current wafer. Returns the
+    number of dies which were inked during the inker run.
+    API Status: published
+    Returns:
+        InkedDies:int
+    Command Timeout: 30000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DoInkerRun")
+    return int(rsp[0])
+
+def CloseWaferMap():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the Wafer Map application.
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("CloseWaferMap")
+
+
+def GetNumSelectedDies():
+    """
+    Gets the number of dies in the map which are selected for probing.
+    API Status: published
+    Returns:
+        SelectedDies:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNumSelectedDies")
+    return int(rsp[0])
+
+def GetSelectedDieCoords(Die=""):
+    """
+    Given the index of a selected die in the range [1..NumSelectedDies], returns the
+    column and row indices for the selected die.
+    API Status: published
+    Args:
+        Die:int = 0
+    Returns:
+        DieX:int
+        DieY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSelectedDieCoords",Die)
+    global GetSelectedDieCoords_Response
+    if not "GetSelectedDieCoords_Response" in globals(): GetSelectedDieCoords_Response = namedtuple("GetSelectedDieCoords_Response", "DieX,DieY")
+    return GetSelectedDieCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def StepNextDieOffset(XOffset="", YOffset="", CDieX="", CDieY=""):
+    """
+    Moves to a user-specified offset within a die. The optional col row params can
+    be used to specify the die. If they are omitted, WaferMap moves to the specified
+    offset within the next selected die.
+    API Status: published
+    Args:
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextDieOffset",XOffset,YOffset,CDieX,CDieY)
+    global StepNextDieOffset_Response
+    if not "StepNextDieOffset_Response" in globals(): StepNextDieOffset_Response = namedtuple("StepNextDieOffset_Response", "RDieX,RDieY")
+    return StepNextDieOffset_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadMapPosition2(Pos="", FromPos=""):
+    """
+    Returns the actual Wafer Map chuck position. The SubDie collection is 0-based,
+    the first value is 0, not 1. M_pnCurSite returns the currently selected Subdie
+    (0-based) or -1 if no Subdie is currently selected.  This command is the
+    preferred method for reading Wafer Map chuck position.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        DieX:int
+        DieY:int
+        XFromHome:Decimal
+        YFromHome:Decimal
+        CurSite:int
+        LastSiteIndex:int
+        CurDie:int
+        DiesCount:int
+        CurCluster:int
+        ClustersCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapPosition2",Pos,FromPos)
+    global ReadMapPosition2_Response
+    if not "ReadMapPosition2_Response" in globals(): ReadMapPosition2_Response = namedtuple("ReadMapPosition2_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+    return ReadMapPosition2_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def DeleteSubDie2(Site=""):
+    """
+    Deletes selected subdie. The SubDie collection is 0-based, the first value is 0,
+    not 1.       This command is the preferred method for deleting a selected
+    subdie.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteSubDie2",Site)
+    return int(rsp[0])
+
+def DeleteAllSubDie():
+    """
+    Deletes all subdies for all dies.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("DeleteAllSubDie")
+
+
+def GetDieLabel(DieX="", DieY=""):
+    """
+    Returns a label from the wafer map at the current die, unless a row and column
+    are specified.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieLabel",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabel(Label="", DieX="", DieY=""):
+    """
+    Assigns a label to the wafer map at the current die, unless a row and column are
+    specified.
+    API Status: published
+    Args:
+        Label:str = ""
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieLabel",Label,DieX,DieY)
+
+
+def StepNextSubDie(Site=""):
+    """
+    Steps the chuck to the specified SubDie number relative to the current die
+    origin of the wafer map. Returns the SubDie number of the actual die location
+    after the move is completed and the total number of subdies.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextSubDie",Site)
+    global StepNextSubDie_Response
+    if not "StepNextSubDie_Response" in globals(): StepNextSubDie_Response = namedtuple("StepNextSubDie_Response", "CurSite,LastSiteIndex")
+    return StepNextSubDie_Response(int(rsp[0]),int(rsp[1]))
+
+def OpenWaferMap(FileName=""):
+    """
+    Opens a Wafer Map file.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("OpenWaferMap",FileName)
+
+
+def SetDieResult(Result="", DieX="", DieY=""):
+    """
+    Assigns a measurement result to the wafer map at the current die, unless a row
+    and column are specified.
+    API Status: published
+    Args:
+        Result:str = ""
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieResult",Result,DieX,DieY)
+
+
+def GetDieResult(DieX="", DieY=""):
+    """
+    Returns a measurement result from the wafer map at the current die, unless a row
+    and column are specified.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieResult",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResult(Result="", DieX="", DieY="", Site=""):
+    """
+    Assigns a measurement result to the wafer die map at the current die and the
+    current subdie, unless a subdie, row, and column are specified. The SubDie
+    collection is 0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Result:str = ""
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieMapResult",Result,DieX,DieY,Site)
+
+
+def GetDieMapResult(DieX="", DieY="", Site=""):
+    """
+    Returns a measurement result from the wafer map at the current die and current
+    subdie, unless a row, column, and subdie are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieMapResult",DieX,DieY,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BinSubDie(Bin="", CDieX="", CDieY="", Site=""):
+    """
+    Assigns the bin information for the current subdie in the current die, unless a
+    subdie, row, and column are specified. The SubDie collection is 0-based, the
+    first value is 0, not 1.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinSubDie",Bin,CDieX,CDieY,Site)
+    global BinSubDie_Response
+    if not "BinSubDie_Response" in globals(): BinSubDie_Response = namedtuple("BinSubDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return BinSubDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetSubDieData(Site="", X="", Y="", Label=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        Site:int = 0
+        X:Decimal = 0
+        Y:Decimal = 0
+        Label:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieData",Site,X,Y,Label)
+
+
+def GetSubDieData(Site=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        CurSite:int
+        X:Decimal
+        Y:Decimal
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieData",Site)
+    global GetSubDieData_Response
+    if not "GetSubDieData_Response" in globals(): GetSubDieData_Response = namedtuple("GetSubDieData_Response", "CurSite,X,Y,Label")
+    return GetSubDieData_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def GetMapHome():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the home die location of the WaferMap.
+    API Status: internal
+    Returns:
+        DieX:int
+        DieY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapHome")
+    global GetMapHome_Response
+    if not "GetMapHome_Response" in globals(): GetMapHome_Response = namedtuple("GetMapHome_Response", "DieX,DieY")
+    return GetMapHome_Response(int(rsp[0]),int(rsp[1]))
+
+def GetMapDims():
+    """
+    Returns the parameters for the current wafer.
+    API Status: published
+    Returns:
+        MapType:str
+        XIndex:Decimal
+        YIndex:Decimal
+        Columns:int
+        Rows:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapDims")
+    global GetMapDims_Response
+    if not "GetMapDims_Response" in globals(): GetMapDims_Response = namedtuple("GetMapDims_Response", "MapType,XIndex,YIndex,Columns,Rows")
+    return GetMapDims_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetWaferMapParams(Diameter="", DieWidth="", DieHeight="", FlatLength="", FlatAngle="", XOffset="", YOffset="", EdgeArea=""):
+    """
+    Creates the circle wafer with specified parameters. If parameter is omitted,
+    then zero is used. For this version of the command, units for XOffset and
+    YOffset are percentages.
+    API Status: published
+    Args:
+        Diameter:Decimal = 200
+        DieWidth:Decimal = 10000
+        DieHeight:Decimal = 10000
+        FlatLength:Decimal = 20
+        FlatAngle:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        EdgeArea:Decimal = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferMapParams",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def SetRectMapParams(DieWidth="", DieHeight="", Columns="", Rows=""):
+    """
+    Creates the rectangle wafer with specified parameters.
+    API Status: published
+    Args:
+        DieWidth:Decimal = 0
+        DieHeight:Decimal = 0
+        Columns:int = 0
+        Rows:int = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetRectMapParams",DieWidth,DieHeight,Columns,Rows)
+
+
+def StepToDie(DieNumber="", Site=""):
+    """
+    Steps the chuck to the die location specified by the die number of the wafer
+    map. If no command data is passed, the chuck automatically steps to the next
+    logical wafer map die location. Returns the row and column number of the actual
+    die location after the move is completed. In addition, the SubDie location, and
+    total number of SubDies is also returned.
+    API Status: published
+    Args:
+        DieNumber:int = -1
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepToDie",DieNumber,Site)
+    global StepToDie_Response
+    if not "StepToDie_Response" in globals(): StepToDie_Response = namedtuple("StepToDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return StepToDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetMapOrientation(UseOrientationCornerForShift=""):
+    """
+    Returns parameters of the map coordinate system.
+    API Status: published
+    Args:
+        UseOrientationCornerForShift:int = 0
+    Returns:
+        Orientation:int
+        OriginShiftX:int
+        OriginShiftY:int
+        UseAlphas:int
+        UseIOs:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapOrientation",UseOrientationCornerForShift)
+    global GetMapOrientation_Response
+    if not "GetMapOrientation_Response" in globals(): GetMapOrientation_Response = namedtuple("GetMapOrientation_Response", "Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs")
+    return GetMapOrientation_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetMapOrientation(Orientation="", OriginShiftX="", OriginShiftY="", UseAlphas="", UseIOs="", UseOrientationCornerForShift=""):
+    """
+    Sets up new map origin and new coordinate system after that.
+    API Status: published
+    Args:
+        Orientation:int = 0
+        OriginShiftX:int = 0
+        OriginShiftY:int = 0
+        UseAlphas:int = 0
+        UseIOs:int = 1
+        UseOrientationCornerForShift:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapOrientation",Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs,UseOrientationCornerForShift)
+
+
+def SetDieStatus(DieX="", DieY="", Status=""):
+    """
+    Sets the die status.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Status:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieStatus",DieX,DieY,Status)
+
+
+def GetDieStatus(DieX="", DieY=""):
+    """
+    Gets the die status.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieStatus",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieStatus(Site="", Status=""):
+    """
+    Sets the SubDie status. The SubDie collection is 0-based, the first value is 0,
+    not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+        Status:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieStatus",Site,Status)
+
+
+def GetSubDieStatus(Site=""):
+    """
+    Returns the SubDie status. The SubDie collection is 0-based, the first value is
+    0, not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieStatus",Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetBinCode(Bin=""):
+    """
+    Returns the Die size from the current map.
+    API Status: published
+    Args:
+        Bin:int = 0
+    Returns:
+        Chars:str
+        Color:int
+        Status:str
+        Inker1:int
+        Inker2:int
+        Inker3:int
+        Inker4:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBinCode",Bin)
+    global GetBinCode_Response
+    if not "GetBinCode_Response" in globals(): GetBinCode_Response = namedtuple("GetBinCode_Response", "Chars,Color,Status,Inker1,Inker2,Inker3,Inker4")
+    return GetBinCode_Response(str(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetBinCode(Bin="", Chars="", Color="", Status="", Inker1="", Inker2="", Inker3="", Inker4=""):
+    """
+    Appends the Bin information to a bin code.
+    API Status: published
+    Args:
+        Bin:int = 0
+        Chars:str = ""
+        Color:int = 0
+        Status:str = ""
+        Inker1:int = 0
+        Inker2:int = 0
+        Inker3:int = 0
+        Inker4:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetBinCode",Bin,Chars,Color,Status,Inker1,Inker2,Inker3,Inker4)
+
+
+def GetDieDataAsNum(CDieIndex=""):
+    """
+    Returns the Die Information in the Row Column format. If the Die Number is
+    invalid it returns an error. If the Die Number is absent it uses the current die
+    on the wafer.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        RDieIndex:int
+        DieX:int
+        DieY:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieDataAsNum",CDieIndex)
+    global GetDieDataAsNum_Response
+    if not "GetDieDataAsNum_Response" in globals(): GetDieDataAsNum_Response = namedtuple("GetDieDataAsNum_Response", "RDieIndex,DieX,DieY,Bin,Result")
+    return GetDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsNum(DieIndex="", Bin="", Result=""):
+    """
+    Sets the Die Information. If the Die Number is invalid it returns an error.
+    API Status: published
+    Args:
+        DieIndex:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieDataAsNum",DieIndex,Bin,Result)
+
+
+def GetSubDieDataAsNum(CDieIndex="", Site=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        RDieIndex:int
+        DieX:int
+        DieY:int
+        CurSite:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsNum",CDieIndex,Site)
+    global GetSubDieDataAsNum_Response
+    if not "GetSubDieDataAsNum_Response" in globals(): GetSubDieDataAsNum_Response = namedtuple("GetSubDieDataAsNum_Response", "RDieIndex,DieX,DieY,CurSite,Bin,Result")
+    return GetSubDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsNum(DieIndex="", Site="", Bin="", Result=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        DieIndex:int = 0
+        Site:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieDataAsNum",DieIndex,Site,Bin,Result)
+
+
+def GetDieDataAsColRow(CDieX="", CDieY=""):
+    """
+    Returns the Die Information in the Row Column format. If the Die Number is
+    invalid it returns an error. If the Die Column and Row are absent it uses the
+    current die on the wafer.
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        DieIndex:int
+        RDieX:int
+        RDieY:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieDataAsColRow",CDieX,CDieY)
+    global GetDieDataAsColRow_Response
+    if not "GetDieDataAsColRow_Response" in globals(): GetDieDataAsColRow_Response = namedtuple("GetDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,Bin,Result")
+    return GetDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsColRow(DieX="", DieY="", Bin="", Result=""):
+    """
+    Sets the Data in the Row Column format. If the Die is invalid it returns an
+    error.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieDataAsColRow",DieX,DieY,Bin,Result)
+
+
+def GetSubDieDataAsColRow(CDieX="", CDieY="", Site=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        DieIndex:int
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsColRow",CDieX,CDieY,Site)
+    global GetSubDieDataAsColRow_Response
+    if not "GetSubDieDataAsColRow_Response" in globals(): GetSubDieDataAsColRow_Response = namedtuple("GetSubDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,CurSite,Bin,Result")
+    return GetSubDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsColRow(DieX="", DieY="", Site="", Bin="", Result=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieDataAsColRow",DieX,DieY,Site,Bin,Result)
+
+
+def SelectAllDiesForProbing(DoSelectAll="", DoEdgeDies=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables all dies.
+    API Status: internal
+    Args:
+        DoSelectAll:int = 0
+        DoEdgeDies:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SelectAllDiesForProbing",DoSelectAll,DoEdgeDies)
+
+
+def GetMapName():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current WaferMap Filename.
+    API Status: internal
+    Returns:
+        Name:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapName")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetLotID(ID=""):
+    """
+    Specifies the ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetLotID",ID)
+
+
+def GetLotID():
+    """
+    Returns the Lot ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLotID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StepFirstCluster(ClearBins="", RecalcRoute=""):
+    """
+    Steps the chuck to the first die cluster of the cluster map. If clusters are not
+    defined, the first Die is used. Returns the row and column information of the
+    actual cluster and die location after the move is completed. Switches to remote
+    control if the "Disable Velox" flag is set in the external options window.
+    API Status: published
+    Args:
+        ClearBins:int = 1
+        RecalcRoute:int = 1
+    Returns:
+        ClusterX:int
+        ClusterY:int
+        ClusterIndex:int
+        IncompleteCluster:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFirstCluster",ClearBins,RecalcRoute)
+    global StepFirstCluster_Response
+    if not "StepFirstCluster_Response" in globals(): StepFirstCluster_Response = namedtuple("StepFirstCluster_Response", "ClusterX,ClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+    return StepFirstCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def StepNextCluster(CClusterX="", CClusterY=""):
+    """
+    Steps the chuck to the specified x,y cluster die location of the cluster map. If
+    no command data is passed, the chuck automatically steps to the next logical
+    cluster map location. If clusters are not defined, the Die information is used.
+    Returns the row and column number of the actual die location after the move is
+    completed.
+    API Status: published
+    Args:
+        CClusterX:int = 0
+        CClusterY:int = 0
+    Returns:
+        RClusterX:int
+        RClusterY:int
+        ClusterIndex:int
+        IncompleteCluster:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextCluster",CClusterX,CClusterY)
+    global StepNextCluster_Response
+    if not "StepNextCluster_Response" in globals(): StepNextCluster_Response = namedtuple("StepNextCluster_Response", "RClusterX,RClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+    return StepNextCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetMapRoute(MoveMode="", StartColumn="", StartRow="", MoveParam=""):
+    """
+    Specifies the Move Path for the probe station inside the Wafer Map. Optimization
+    is done for the shortest move way for the station.
+    API Status: published
+    Args:
+        MoveMode:str = "B"
+        StartColumn:str = "L"
+        StartRow:str = "T"
+        MoveParam:str = "H"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapRoute",MoveMode,StartColumn,StartRow,MoveParam)
+
+
+def GetMapRoute():
+    """
+    Returns the specified move path for the probe station inside the Wafer Map.
+    API Status: published
+    Returns:
+        MoveMode:str
+        StartColumn:str
+        StartRow:str
+        MoveParam:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapRoute")
+    global GetMapRoute_Response
+    if not "GetMapRoute_Response" in globals(): GetMapRoute_Response = namedtuple("GetMapRoute_Response", "MoveMode,StartColumn,StartRow,MoveParam")
+    return GetMapRoute_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetClusterParams(UseClusters="", ClusterWidth="", ClusterHeight="", TestIncomplete=""):
+    """
+    Specifies the clusters parameters.
+    API Status: published
+    Args:
+        UseClusters:int = 0
+        ClusterWidth:int = 1
+        ClusterHeight:int = 1
+        TestIncomplete:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetClusterParams",UseClusters,ClusterWidth,ClusterHeight,TestIncomplete)
+
+
+def GetClusterParams():
+    """
+    Returns current clusters parameters.
+    API Status: published
+    Returns:
+        UseClusters:int
+        ClusterWidth:int
+        ClusterHeight:int
+        TestIncomplete:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterParams")
+    global GetClusterParams_Response
+    if not "GetClusterParams_Response" in globals(): GetClusterParams_Response = namedtuple("GetClusterParams_Response", "UseClusters,ClusterWidth,ClusterHeight,TestIncomplete")
+    return GetClusterParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def NewWaferMap():
+    """
+    Deletes current wafer map, sub dies and binning information; then creates new
+    wafer map with defaults parameters.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("NewWaferMap")
+
+
+def AddSubDie(X="", Y="", Label=""):
+    """
+    Adds new subdie at the end of the table.
+    API Status: published
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        Label:str = ""
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("AddSubDie",X,Y,Label)
+    return int(rsp[0])
+
+def DeleteSubDie(Site=""):
+    """
+    Deletes selected subdie. The SubDie collection is 1-based, the first value is 1,
+    not 0. If 0 is passed in as the subdie index, WaferMap will delete all subdies
+    for all dies.This command (i.e. DeleteSubDie) has been included for legacy
+    support.       DeleteSubDie2 is the preferred method for deleting a selected
+    subdie. DeleteAllSubDie is the preferred method for deleting all subdies for all
+    dies.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteSubDie",Site)
+    return int(rsp[0])
+
+def GetNumSelectedClusters():
+    """
+    Gets the number of clusters in the map which are selected for probing.
+    API Status: published
+    Returns:
+        SelectedClusters:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNumSelectedClusters")
+    return int(rsp[0])
+
+def GetSelectedClusterCoords(ClusterIndex=""):
+    """
+    Given the index of a selected cluster in the range [1..NumSelectedClusters],
+    returns the column and row indices for the selected cluster.
+    API Status: published
+    Args:
+        ClusterIndex:int = 0
+    Returns:
+        ClusterX:int
+        ClusterY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSelectedClusterCoords",ClusterIndex)
+    global GetSelectedClusterCoords_Response
+    if not "GetSelectedClusterCoords_Response" in globals(): GetSelectedClusterCoords_Response = namedtuple("GetSelectedClusterCoords_Response", "ClusterX,ClusterY")
+    return GetSelectedClusterCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def GetClusterDieStatus(ClusterX="", ClusterY="", DieX="", DieY=""):
+    """
+    Gets the die status in the cluster. Die coordinates are internal for the cluster
+    using the wafer map coordinate system. (0,0) die in the cluster is left top
+    corner (whether this die exists or not).
+    API Status: published
+    Args:
+        ClusterX:int = 0
+        ClusterY:int = 0
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterDieStatus",ClusterX,ClusterY,DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetClusterDieStatus(ClusterX="", ClusterY="", DieX="", DieY="", Status=""):
+    """
+    Sets the die status in the cluster. Die coordinates are internal for the cluster
+    using the wafer map coordinate system. (0,0) die in the cluster is left top
+    corner (whether this die exists or not).
+    API Status: published
+    Args:
+        ClusterX:int = 0
+        ClusterY:int = 0
+        DieX:int = 0
+        DieY:int = 0
+        Status:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetClusterDieStatus",ClusterX,ClusterY,DieX,DieY,Status)
+
+
+def OpenBinCodeTable(FileName=""):
+    """
+    Opens a Bin Code Table file (.bct) with the specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("OpenBinCodeTable",FileName)
+
+
+def SaveBinCodeTable(FileName=""):
+    """
+    Saves bin code table to a file with the specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SaveBinCodeTable",FileName)
+
+
+def SetBinTableSize(BinsSize=""):
+    """
+    Sets size of the bin code table. This is the size of bins used in statistics and
+    binning.
+    API Status: published
+    Args:
+        BinsSize:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetBinTableSize",BinsSize)
+
+
+def GetBinTableSize():
+    """
+    Gets size of the bin code table.
+    API Status: published
+    Returns:
+        BinsSize:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBinTableSize")
+    return int(rsp[0])
+
+def StepFailedClusterBack():
+    """
+    Steps the chuck the consecutive failed clusters back (goes back to the last
+    known good cluster) and returns the number of consecutive failed clusters.
+    API Status: published
+    Returns:
+        FailedClusters:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedClusterBack")
+    return int(rsp[0])
+
+def StepFailedClusterForward():
+    """
+    Steps the chuck the consecutive failed clusters forward and returns the number
+    of consecutive failed clusters (goes to next untested cluster).
+    API Status: published
+    Returns:
+        FailedClusters:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedClusterForward")
+    return int(rsp[0])
+
+def GoToWaferHome():
+    """
+    Moves the chuck to the wafer home position.
+    API Status: published
+    Command Timeout: 6000000
+    """
+    MessageServerInterface.sendSciCommand("GoToWaferHome")
+
+
+def GetWaferInfo():
+    """
+    Returns a number of all units marked to test. Note that TestSites is a number of
+    all sites for all dies.
+    API Status: published
+    Returns:
+        ClustersCount:int
+        DiesCount:int
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferInfo")
+    global GetWaferInfo_Response
+    if not "GetWaferInfo_Response" in globals(): GetWaferInfo_Response = namedtuple("GetWaferInfo_Response", "ClustersCount,DiesCount,SitesCount")
+    return GetWaferInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetClusterInfo(Cluster=""):
+    """
+    Returns a number of all dies and sites marked to test in the given cluster.
+    API Status: published
+    Args:
+        Cluster:int = 0
+    Returns:
+        DiesCount:int
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterInfo",Cluster)
+    global GetClusterInfo_Response
+    if not "GetClusterInfo_Response" in globals(): GetClusterInfo_Response = namedtuple("GetClusterInfo_Response", "DiesCount,SitesCount")
+    return GetClusterInfo_Response(int(rsp[0]),int(rsp[1]))
+
+def GetDieInfo(Die=""):
+    """
+    Returns a number of sites marked to test in the given die.
+    API Status: published
+    Args:
+        Die:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieInfo",Die)
+    return int(rsp[0])
+
+def ConvertToAlphas(Start="", Finish=""):
+    """
+    Returns a string of the alpha column coordinates for the given range divided by
+    spaces.
+    API Status: published
+    Args:
+        Start:int = 0
+        Finish:int = 0
+    Returns:
+        Alphas:str
+    Command Timeout: 240000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ConvertToAlphas",Start,Finish)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetActiveLayer(Layer=""):
+    """
+    Sets new active layer.
+    API Status: published
+    Args:
+        Layer:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetActiveLayer",Layer)
+
+
+def GetActiveLayer():
+    """
+    Returns current active layer.
+    API Status: published
+    Returns:
+        Layer:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetActiveLayer")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieRefPoint(RefX="", RefY=""):
+    """
+    Sets a new reference point for the die. This point is NOT used for die stepping,
+    nor for subdie stepping. When using the "Chuck Position from Reference" WaferMap
+    GUI setting, the Die Reference Point can be set to be more representative of the
+    actual reference location within the die. A setting of (0.0, 0.0) is defined as
+    the upper left corner of the die. All subdie coordinates are relative to upper
+    left corner of the die.
+    API Status: published
+    Args:
+        RefX:Decimal = 0
+        RefY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieRefPoint",RefX,RefY)
+
+
+def GetDieRefPoint():
+    """
+    Returns current reference point for the die. For details see SetDieRefPoint
+    command.
+    API Status: published
+    Returns:
+        RefX:Decimal
+        RefY:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieRefPoint")
+    global GetDieRefPoint_Response
+    if not "GetDieRefPoint_Response" in globals(): GetDieRefPoint_Response = namedtuple("GetDieRefPoint_Response", "RefX,RefY")
+    return GetDieRefPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ClearAllBins():
+    """
+    Clears all binning data in the wafer map.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ClearAllBins")
+
+
+def SetWindowState(State="", Window=""):
+    """
+    Has sense in the application only (not for ActiveX controls). It shows or hides
+    a window. All parameters are case-insensitive.
+    API Status: published
+    Args:
+        State:str = "s"
+        Window:str = "setup"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWindowState",State,Window)
+
+
+def SetCurrentBin(Bin="", ButtonStatus=""):
+    """
+    Sets the current bin for the application. Second parameter allows to enable or
+    disable "Mark with Bin" mode in the application.
+    API Status: published
+    Args:
+        Bin:int = 0
+        ButtonStatus:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetCurrentBin",Bin,ButtonStatus)
+
+
+def GetCurrentBin():
+    """
+    Returns the current bin in the application.
+    API Status: published
+    Returns:
+        Bin:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCurrentBin")
+    return int(rsp[0])
+
+def ReadClusterPosition(Pos="", FromPos=""):
+    """
+    Returns the actual wafer map cluster position. If the cluster probing is
+    disabled, the command will assume a cluster of size 1x1.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        ClusterX:int
+        ClusterY:int
+        ClusterIndex:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+        ClusterWidth:int
+        ClusterHeight:int
+        EnabledDies:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadClusterPosition",Pos,FromPos)
+    global ReadClusterPosition_Response
+    if not "ReadClusterPosition_Response" in globals(): ReadClusterPosition_Response = namedtuple("ReadClusterPosition_Response", "ClusterX,ClusterY,ClusterIndex,DieX,DieY,DieIndex,ClusterWidth,ClusterHeight,EnabledDies")
+    return ReadClusterPosition_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str("" if len(rsp) < 9 else ' '.join(rsp[8:])))
+
+def GetWaferMapParams():
+    """
+    Returns the circle wafer parameters. For this version of the command, units for
+    XOffset and YOffset are percentages.
+    API Status: published
+    Returns:
+        Diameter:Decimal
+        DieWidth:Decimal
+        DieHeight:Decimal
+        FlatLength:Decimal
+        FlatAngle:int
+        XOffset:Decimal
+        YOffset:Decimal
+        EdgeArea:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams")
+    global GetWaferMapParams_Response
+    if not "GetWaferMapParams_Response" in globals(): GetWaferMapParams_Response = namedtuple("GetWaferMapParams_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+    return GetWaferMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def GetRectMapParams():
+    """
+    Creates a rectangular wafermap with specified parameters.
+    API Status: published
+    Returns:
+        DieWidth:Decimal
+        DieHeight:Decimal
+        Columns:int
+        Rows:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetRectMapParams")
+    global GetRectMapParams_Response
+    if not "GetRectMapParams_Response" in globals(): GetRectMapParams_Response = namedtuple("GetRectMapParams_Response", "DieWidth,DieHeight,Columns,Rows")
+    return GetRectMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SyncMapHome(X="", Y=""):
+    """
+    Tries to find an appropriate position in the wafer for the current chuck
+    position. X and Y describe the chuck position of the wafer center relatively to
+    the chuck zero position. If the wafer position is found the command sets it as
+    the wafer map home position and sets the current chuck position as the chuck
+    home position. If there is no corresponding wafer position the command returns
+    error 701. Command is used by AutoAlign for the BuildMap feature.
+    API Status: published
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SyncMapHome",X,Y)
+
+
+def SetWaferProfileOptions(ProfileSensor="", SearchSpeed="", Gap="", SuccessRatio="", ProfDistX="", ProfDistY=""):
+    """
+    Sets some WaferMap profiling options remotely.
+    API Status: published
+    Args:
+        ProfileSensor:str = "e"
+        SearchSpeed:Decimal = 50
+        Gap:Decimal = 10
+        SuccessRatio:Decimal = 75
+        ProfDistX:Decimal = 0
+        ProfDistY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferProfileOptions",ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY)
+
+
+def GetWaferProfileOptions():
+    """
+    Returns predefined settings of the WaferMap profiling options.
+    API Status: published
+    Returns:
+        ProfileSensor:str
+        SearchSpeed:Decimal
+        Gap:Decimal
+        SuccessRatio:Decimal
+        ProfDistX:Decimal
+        ProfDistY:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferProfileOptions")
+    global GetWaferProfileOptions_Response
+    if not "GetWaferProfileOptions_Response" in globals(): GetWaferProfileOptions_Response = namedtuple("GetWaferProfileOptions_Response", "ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY")
+    return GetWaferProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def StartWaferProfiling(DoContinue=""):
+    """
+    Starts the profiling process. To determine the current profiling state, use
+    GetWaferProfilingStatus command.
+    API Status: published
+    Args:
+        DoContinue:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("StartWaferProfiling",DoContinue)
+
+
+def GetWaferProfilingStatus():
+    """
+    Returns status of the profiling process. If this status is true, the process is
+    started.
+    API Status: published
+    Returns:
+        Started:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferProfilingStatus")
+    return int(rsp[0])
+
+def StopWaferProfiling():
+    """
+    Stops the profiling process.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("StopWaferProfiling")
+
+
+def DoWaferProfiling():
+    """
+    Profiles the wafer and returns a status of the profiling as an error code.
+    API Status: published
+    Command Timeout: 36000000
+    """
+    MessageServerInterface.sendSciCommand("DoWaferProfiling")
+
+
+def DoWaferProfilingOffAxis():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Profiles the wafer and returns a status of the profiling as an error code.
+    Executes profiling using the off axis camera
+    API Status: internal
+    Command Timeout: 36000000
+    """
+    MessageServerInterface.sendSciCommand("DoWaferProfilingOffAxis")
+
+
+def GetSubDieLabel(DieX="", DieY="", Site=""):
+    """
+    Returns a label from the wafer map at the current die and current subdie, unless
+    a row, column, and subdie are specified. The SubDie collection is 0-based, the
+    first value is 0, not 1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieLabel",DieX,DieY,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabel(Label="", DieX="", DieY="", Site=""):
+    """
+    Assigns a label to the wafer map at the current die and the current subdie,
+    unless a subdie, row, and column are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Label:str = ""
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieLabel",Label,DieX,DieY,Site)
+
+
+def GetSubDieLabelAsNum(CDieIndex="", Site=""):
+    """
+    Returns a label from the wafer map the current die and the current subdie,
+    unless a subdie, and die number are specified. The SubDie collection is 0-based,
+    the first value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieLabelAsNum",CDieIndex,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabelAsNum(Label="", CDieIndex="", Site=""):
+    """
+    Assigns a label to the wafer map at the current die and the current subdie,
+    unless a subdie, and die number are specified. The SubDie collection is 0-based,
+    the first value is 0, not 1.
+    API Status: published
+    Args:
+        Label:str = ""
+        CDieIndex:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieLabelAsNum",Label,CDieIndex,Site)
+
+
+def GetDieLabelAsNum(CDieIndex=""):
+    """
+    Returns a label from the wafer map at the current die, unless a die number is
+    specified.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieLabelAsNum",CDieIndex)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabelAsNum(Label="", CDieIndex=""):
+    """
+    Assigns a label to the wafer map at the current die, unless a die number is
+    specified.
+    API Status: published
+    Args:
+        Label:str = ""
+        CDieIndex:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieLabelAsNum",Label,CDieIndex)
+
+
+def GetHomeDieOffset():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the XY offset from the reference position of the Home Die to wafer
+    center in chuck coordinates.
+    API Status: internal
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHomeDieOffset")
+    global GetHomeDieOffset_Response
+    if not "GetHomeDieOffset_Response" in globals(): GetHomeDieOffset_Response = namedtuple("GetHomeDieOffset_Response", "X,Y")
+    return GetHomeDieOffset_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetWaferMapParams2(Diameter="", DieWidth="", DieHeight="", FlatLength="", FlatAngle="", XOffset="", YOffset="", EdgeArea=""):
+    """
+    Creates the circle wafer with specified parameters. If parameter is omitted,
+    then zero is used. For this version of the command, units for XOffset and
+    YOffset are microns.
+    API Status: published
+    Args:
+        Diameter:Decimal = 200
+        DieWidth:Decimal = 10000
+        DieHeight:Decimal = 10000
+        FlatLength:Decimal = 20
+        FlatAngle:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        EdgeArea:Decimal = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferMapParams2",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def GetWaferMapParams2():
+    """
+    Returns the circle wafer parameters. For this version of the command, units for
+    XOffset and YOffset are microns.
+    API Status: published
+    Returns:
+        Diameter:Decimal
+        DieWidth:Decimal
+        DieHeight:Decimal
+        FlatLength:Decimal
+        FlatAngle:int
+        XOffset:Decimal
+        YOffset:Decimal
+        EdgeArea:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams2")
+    global GetWaferMapParams2_Response
+    if not "GetWaferMapParams2_Response" in globals(): GetWaferMapParams2_Response = namedtuple("GetWaferMapParams2_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+    return GetWaferMapParams2_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def SetWaferTestAngle(Angle=""):
+    """
+    This command sets the Wafer Test Angle. This is different from the notch angle
+    and allows rotating the WaferMap.
+    API Status: published
+    Args:
+        Angle:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferTestAngle",Angle)
+
+
+def GetWaferTestAngle():
+    """
+    This returns the Wafer Test Angle. This is different from the notch angle and
+    allows rotating the WaferMap.
+    API Status: published
+    Returns:
+        Angle:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferTestAngle")
+    return int(rsp[0])
+
+def LoadPreMappedDiesTable(FileName="", ClearMap=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Loads the Pre-Mapped Dies Table file with specified name.
+    API Status: internal
+    Args:
+        FileName:str = ""
+        ClearMap:int = 1
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("LoadPreMappedDiesTable",FileName,ClearMap)
+
+
+def GetPreMappedDieInfo(DieX="", DieY=""):
+    """
+    This command is valid when a PreMapped Dies Table has been loaded. Returns
+    values at the current die, unless a column (M_pnDieX) and row (M_pnDieY) are
+    specified.  Returns actual (as measured during the Pre-Mapping) x, y, z, and
+    theta die positions. Also returns whether or not Z and Theta are being used.
+    This command is only valid when a Pre-Mapped Dies Table has been loaded. If a
+    PreMapped Dies Table has NOT been loaded, ERR_IllegalParameters (715) is
+    returned.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        UseZ:int
+        UseTheta:int
+        ActualX:Decimal
+        ActualY:Decimal
+        ActualZ:Decimal
+        Theta:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPreMappedDieInfo",DieX,DieY)
+    global GetPreMappedDieInfo_Response
+    if not "GetPreMappedDieInfo_Response" in globals(): GetPreMappedDieInfo_Response = namedtuple("GetPreMappedDieInfo_Response", "UseZ,UseTheta,ActualX,ActualY,ActualZ,Theta")
+    return GetPreMappedDieInfo_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def GetDieResultAsNum(CDieIndex=""):
+    """
+    Returns a measurement result from the wafer map at the current die, unless a die
+    number is specified.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieResultAsNum",CDieIndex)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieResultAsNum(Result="", CDieIndex=""):
+    """
+    Assigns a measurement result to the wafer map at the current die, unless a die
+    number is specified.
+    API Status: published
+    Args:
+        Result:str = ""
+        CDieIndex:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieResultAsNum",Result,CDieIndex)
+
+
+def GetDieMapResultAsNum(CDieIndex="", Site=""):
+    """
+    Returns a measurement result from the wafer map the current die and the current
+    subdie, unless a subdie, and die number are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieMapResultAsNum",CDieIndex,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResultAsNum(Result="", CDieIndex="", Site=""):
+    """
+    Assigns a measurement result to the wafer die map at the current die at the
+    current subdie, unless a subdie, and die number are specified. The SubDie
+    collection is 0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Result:str = ""
+        CDieIndex:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieMapResultAsNum",Result,CDieIndex,Site)
+
+
+def MapEdgeDies(Enable=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables edge dies for test
+    API Status: internal
+    Args:
+        Enable:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("MapEdgeDies",Enable)
+
+
+def GetSpectrumData(DataPath=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows access to read any data item in Spectrum explorer.     GetSpectrumData
+    AlignWafer/ProjectData/Mark1/ChuckPosition/X     GetSpectrumData Chuck
+    Camera/Camera Settings/Shutter
+    API Status: internal
+    Args:
+        DataPath:str = ""
+    Returns:
+        Value:str
+    Command Timeout: 6000
+    Example:GetSpectrumData Chuck Camera/Camera Settings/Shutter
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSpectrumData",DataPath)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumData(PathAndValue=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows changing any data item in Spectrum explorer. Works independent of access
+    level. SetSpectrumData AlignWafer/ProjectData/Mark1/ChuckPosition/X=1000
+    SetSpectrumData Chuck Camera/Camera Settings/Shutter=17
+    API Status: internal
+    Args:
+        PathAndValue:str = ""
+    Command Timeout: 6000
+    Example:SetSpectrumData Scope Camera/Camera Settings/Shutter=17
+    """
+    MessageServerInterface.sendSciCommand("SetSpectrumData",PathAndValue)
+
+
+def ReadVMPosition(ToolName="", XY="", Z="", Model=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the current chuck and microscope position and sets them as
+    new controller or chuck and microscope positions.     The command was originally used
+    by ReAlignWizard but may be removed in the future because of direct access to
+    tooldata     within Spectrum.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        XY:int = 1
+        Z:int = 0
+        Model:int = -1
+    Command Timeout: 60000
+    Example:ReadVMPosition AlignWafer 1 0 0
+    """
+    MessageServerInterface.sendSciCommand("ReadVMPosition",ToolName,XY,Z,Model)
+
+
+def MoveToVMPosition(ToolName="", XYChuck="", ZChuck="", XYScope="", ZScope="", Model=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command moves to trained stages positions of a requested tool. Command is
+    used by ReAlignWizard to move to     the trained positions for AutoAlign and
+    DetectWaferHeight.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        XYChuck:int = 1
+        ZChuck:int = 1
+        XYScope:int = 0
+        ZScope:int = 0
+        Model:int = -1
+    Command Timeout: 120000
+    Example:MoveToVMPosition AlignWafer 1 0 0 0 0
+    """
+    MessageServerInterface.sendSciCommand("MoveToVMPosition",ToolName,XYChuck,ZChuck,XYScope,ZScope,Model)
+
+
+def ShapeTracker(SetHome="", AutoEdgeFind="", FileName=""):
+    """
+    ShapeTracker automatically tracks the shape of a substrate (e.g. a broken wafer)
+    to determine the contour of it. The data will be memorized as xy coordinates of
+    contour points referenced to the home position. These Points are written to a
+    file after tracking the shape.
+    API Status: published
+    Args:
+        SetHome:int = 1
+        AutoEdgeFind:int = 0
+        FileName:str = ""
+    Command Timeout: 600000
+    Example:ShapeTracker 1
+    """
+    MessageServerInterface.sendSciCommand("ShapeTracker",SetHome,AutoEdgeFind,FileName)
+
+
+def DetectWaferHeight(SetStartPosition="", Synchronize="", ChuckX="", ChuckY=""):
+    """
+    Synchronizes chuck and top camera in X, Y and Z. Then the wafer surface is
+    focused on the trained chuck position or the manual adjusted reference position.
+    This tool uses the FindFocus tool with its own Range.
+    API Status: published
+    Args:
+        SetStartPosition:int = 0
+        Synchronize:int = 0
+        ChuckX:Decimal = -1
+        ChuckY:Decimal = -1
+    Returns:
+        PositionX:Decimal
+        PositionY:Decimal
+        WaferHeight:Decimal
+        SynchGap:Decimal
+        ZOffset:Decimal
+        Stage:str
+    Command Timeout: 300000
+    Example:DetectWaferHeight 0 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("DetectWaferHeight",SetStartPosition,Synchronize,ChuckX,ChuckY)
+    global DetectWaferHeight_Response
+    if not "DetectWaferHeight_Response" in globals(): DetectWaferHeight_Response = namedtuple("DetectWaferHeight_Response", "PositionX,PositionY,WaferHeight,SynchGap,ZOffset,Stage")
+    return DetectWaferHeight_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def CheckSpectrumPlugin(Plugin=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command checks if a plugin is trained and returns a string of error/warning
+    messages including information about what is not trained, setup for the tool to
+    run.
+    API Status: internal
+    Args:
+        Plugin:str = ""
+    Returns:
+        PluginAvailable:int
+        Message:str
+    Command Timeout: 1000
+    Example:CheckSpectrumPlugin AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("CheckSpectrumPlugin",Plugin)
+    global CheckSpectrumPlugin_Response
+    if not "CheckSpectrumPlugin_Response" in globals(): CheckSpectrumPlugin_Response = namedtuple("CheckSpectrumPlugin_Response", "PluginAvailable,Message")
+    return CheckSpectrumPlugin_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AutoAlign(SetValue="", SkipSettingHome=""):
+    """
+    Executes the AutoAlign tool to do a theta alignment of the wafer with optional
+    index calculation or thermal expansion measurement. The command will update home
+    if home was trained. It will only move to its trained chuck/scope position
+    before starting the alignment if the option "MoveToTrainedXYPosition" and/or
+    "MoveToTrainedZPosition" is true.
+    API Status: published
+    Args:
+        SetValue:int = 0
+        SkipSettingHome:int = 0
+    Command Timeout: 300000
+    Example:AutoAlign 1
+    """
+    MessageServerInterface.sendSciCommand("AutoAlign",SetValue,SkipSettingHome)
+
+
+def SetCameraQuiet(Active=""):
+    """
+    Activates/deactivates the camera quiet mode. (Applies only to ATM300A and
+    SPS300/SUMMIT200 stations.)     The camera quiet mode deactivates the chuck,
+    platen and contact view camera and triggers a digital output     which
+    connects/disconnects these cameras firewire connection to the PC.
+    API Status: published
+    Args:
+        Active:int = 0
+    Command Timeout: 30000
+    Example:SetCameraQuiet 1
+    """
+    MessageServerInterface.sendSciCommand("SetCameraQuiet",Active)
+
+
+def SetRefDieOffset(RefDieCol="", RefDieRow="", RefDieDistToCentreX="", RefDieDistToCentreY=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is based on the SetMapOrientation command. It allows shifting the
+    center of the reference die to the center of the wafer.
+    API Status: internal
+    Args:
+        RefDieCol:int = 0
+        RefDieRow:int = 0
+        RefDieDistToCentreX:Decimal = 0
+        RefDieDistToCentreY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetRefDieOffset",RefDieCol,RefDieRow,RefDieDistToCentreX,RefDieDistToCentreY)
+
+
+def AlignWafer(TrackPosition=""):
+    """
+    Performs a two-point alignment and moves chuck to the trained align position. XY
+    correction is made afterwards to calculate the new home position.
+    API Status: published
+    Args:
+        TrackPosition:int = 0
+    Returns:
+        ThetaOffset:Decimal
+    Command Timeout: 120000
+    Example:AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignWafer",TrackPosition)
+    return Decimal(rsp[0])
+
+def AlignChip():
+    """
+    Performs a single or two point alignment and moves the current chip to the
+    trained aligned position in Theta (in degrees) and X, Y (in microns). The
+    current chip is assumed to be in the region of interest when the command is
+    called.
+    API Status: published
+    Returns:
+        ThetaOffset:Decimal
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 180000
+    Example:AlignChip
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignChip")
+    global AlignChip_Response
+    if not "AlignChip_Response" in globals(): AlignChip_Response = namedtuple("AlignChip_Response", "ThetaOffset,XOffset,YOffset")
+    return AlignChip_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def FindFocus(StepCount="", Range=""):
+    """
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search.
+    API Status: published
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocus 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocus",StepCount,Range)
+    global FindFocus_Response
+    if not "FindFocus_Response" in globals(): FindFocus_Response = namedtuple("FindFocus_Response", "ZPosition,Stage")
+    return FindFocus_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAux(AuxSiteID=""):
+    """
+    Performs an automated aux site alignment in XYZ. Tool can correct reference
+    position and contact height for the given aux site.
+    API Status: published
+    Args:
+        AuxSiteID:int = 0
+    Command Timeout: 300000
+    Example:AlignAux 1
+    """
+    MessageServerInterface.sendSciCommand("AlignAux",AuxSiteID)
+
+
+def FindFeature(Model="", ReturnDistanceFromModelOrigin="", UseSingleImageAcquisition=""):
+    """
+    Search user-defined models. Up to 40 different models can be trained. After
+    training, these models can be searched on screen either by direct user
+    interaction or from external applications with a remote command. The remote
+    command returns the X/Y-Positions, angle (degree) and score value (0 - 1.0) for
+    each instance of the controller found in the region of interest.
+    API Status: published
+    Args:
+        Model:int = 1
+        ReturnDistanceFromModelOrigin:int = 0
+        UseSingleImageAcquisition:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 10000
+    Example:FindFeature 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFeature",Model,ReturnDistanceFromModelOrigin,UseSingleImageAcquisition)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CloseSpectrum():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    CloseSpectrum closes the Spectrum application. Used internally by CommonCommands
+    during Project loading. Does save configuration data but does not save project
+    data.
+    API Status: internal
+    Command Timeout: 6000
+    Example:CloseSpectrum
+    """
+    MessageServerInterface.sendSciCommand("CloseSpectrum")
+
+
+def SnapImage(MountPos="", FullPath="", SnapShotMode=""):
+    """
+    Saves the currently displayed image to the specified file. The image is stored
+    in the requested file format (bmp, jpg or png). By default. it will save the raw
+    camera image and an image with the overlays that are currently visible on the
+    camera view. Using a parameter, one can decide to only save either raw image,
+    overlay image or both. By Specifying 'ALL' as the mount position, the captured
+    screenshot will consist of the currently selected camera layout without
+    providing the raw image. If MountPos and FullPath are empty then the current
+    camera view with overlays is copied to the clipboard.
+    API Status: published
+    Args:
+        MountPos:str = "Scope"
+        FullPath:str = "Image.bmp"
+        SnapShotMode:int = 2
+    Command Timeout: 60000
+    Example:SnapImage Scope C:/Temp/Image.bmp
+    """
+    MessageServerInterface.sendSciCommand("SnapImage",MountPos,FullPath,SnapShotMode)
+
+
+def SetCameraView(Name="", Zoom="", LiveVideo="", WindowState=""):
+    """
+    Switches the desired video window of Spectrum as foreground and active view. The
+    camera view can be determined over a tool name or the camera mount position. The
+    second parameter defines the displays zoom factor to be used. Third parameter is
+    used to toogle the live video. Last parameter can be used to maximize a window.
+    API Status: published
+    Args:
+        Name:str = ""
+        Zoom:int = 0
+        LiveVideo:int = 2
+        WindowState:int = 1
+    Command Timeout: 6000
+    Example:SetCameraView AlignWafer 0 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetCameraView",Name,Zoom,LiveVideo,WindowState)
+
+
+def SetCameraLight(Name="", State="", Shutter="", Gain="", Brightness="", Contrast="", Sharpness="", Illumination=""):
+    """
+    Switches the light of the choosen camera on or off. Light values of -1 will
+    cause that the parameter is not affected.
+    API Status: published
+    Args:
+        Name:str = ""
+        State:int = 0
+        Shutter:Decimal = -1
+        Gain:Decimal = -1
+        Brightness:int = -1
+        Contrast:int = -1
+        Sharpness:int = -1
+        Illumination:int = -1
+    Command Timeout: 6000
+    Example:SetCameraLight AlignWafer 1 20 5
+    """
+    MessageServerInterface.sendSciCommand("SetCameraLight",Name,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination)
+
+
+def ShowWizard(ToolName="", MountPosition="", AskExecute=""):
+    """
+    Starts the wizard of a given tool on the display defined in the tool settings.
+    Additionally it can start a wizard for training single models with the syntax
+    e.g. ShowWizard FindFeature/ProjectData/Features/Feature1/Model For the tools
+    MeasureOnScreen, Calibrate and CameraOrigin you can specify a mount position
+    e.g. ShowWizard Calibrate Platen
+    API Status: published
+    Args:
+        ToolName:str = ""
+        MountPosition:str = ""
+        AskExecute:int = 0
+    Returns:
+        Cancelled:int
+    Command Timeout: 10000000
+    Example:ShowWizard AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("ShowWizard",ToolName,MountPosition,AskExecute)
+    return int(rsp[0])
+
+def ProbeToPadAlign(Position=""):
+    """
+    Sets a new Home position. The command is used during ReAlign to search the
+    trained home reference controller and to calculate the new xy home position.
+    API Status: published
+    Args:
+        Position:str = "H"
+    Returns:
+        XOffsetWafer:Decimal
+        YOffsetWafer:Decimal
+    Command Timeout: 120000
+    Example:ProbeToPadAlign H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProbeToPadAlign",Position)
+    global ProbeToPadAlign_Response
+    if not "ProbeToPadAlign_Response" in globals(): ProbeToPadAlign_Response = namedtuple("ProbeToPadAlign_Response", "XOffsetWafer,YOffsetWafer")
+    return ProbeToPadAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ReadOcrString():
+    """
+    Reads the wafer ID string from the wafer's surface. Returns the read ID as
+    string. Requires IDTools license.
+    API Status: published
+    Returns:
+        OcrString:str
+    Command Timeout: 60000
+    Example:ReadOcrString
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadOcrString")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadBarCode():
+    """
+    Reads the wafers barcode and decodes it to a string. Requires IDTools license.
+    API Status: published
+    Returns:
+        BarCodeString:str
+    Command Timeout: 60000
+    Example:ReadBarCode
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadBarCode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def Read2DMatrixCode():
+    """
+    Reads the wafers matrix code and decodes it to a string. Requires IDTools
+    license.
+    API Status: published
+    Returns:
+        MatrixCodeString:str
+    Command Timeout: 60000
+    Example:Read2DMatrixCode
+    """
+    rsp = MessageServerInterface.sendSciCommand("Read2DMatrixCode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumRemote(Activate=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the Spectrum remote mode. In this mode all user interface elements are
+    hidden and disabled. This is used when Spectrum is hosted inside VeloxPro.
+    API Status: internal
+    Args:
+        Activate:int = 1
+    Command Timeout: 10000
+    Example:SetSpectrumRemote 1
+    """
+    MessageServerInterface.sendSciCommand("SetSpectrumRemote",Activate)
+
+
+def GetCameraLight(Name=""):
+    """
+    Returns light properties of choosen camera.
+    API Status: published
+    Args:
+        Name:str = ""
+    Returns:
+        MountPosition:str
+        State:int
+        Shutter:Decimal
+        Gain:Decimal
+        Brightness:int
+        Contrast:int
+        Sharpness:int
+        Illumination:int
+    Command Timeout: 6000
+    Example:GetCameraLight Scope
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraLight",Name)
+    global GetCameraLight_Response
+    if not "GetCameraLight_Response" in globals(): GetCameraLight_Response = namedtuple("GetCameraLight_Response", "MountPosition,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination")
+    return GetCameraLight_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def GetCameraView(Name=""):
+    """
+    Returns the present camera view state of a desired tool or active view.
+    API Status: published
+    Args:
+        Name:str = ""
+    Returns:
+        MountPosition:str
+        Zoom:int
+        LiveVideo:int
+        WindowState:int
+    Command Timeout: 6000
+    Example:GetCameraView AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraView",Name)
+    global GetCameraView_Response
+    if not "GetCameraView_Response" in globals(): GetCameraView_Response = namedtuple("GetCameraView_Response", "MountPosition,Zoom,LiveVideo,WindowState")
+    return GetCameraView_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetPattern(ToolName="", ModelName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Transforms the specific controller of a demanded tool into a bitmap. This bitmap will
+    be stored in the same folder as the project file.     The command was originally
+    required by ReAlignWizard and is currently no longer in use.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        ModelName:str = ""
+    Returns:
+        BitmapPath:str
+    Command Timeout: 30000
+    Example:GetPattern AlignWafer Model1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPattern",ToolName,ModelName)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowPosition(MountPosition="", DistPositionX="", DistPositionY=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the ChuckCenter under a given camera. When no camera mount position is
+    given, Spectrum uses active view. If there is an Offset different from zero,
+    this position will be moved under the camera.
+    API Status: internal
+    Args:
+        MountPosition:str = ""
+        DistPositionX:Decimal = 0
+        DistPositionY:Decimal = 0
+    Command Timeout: 60000
+    Example:ShowPosition Scope
+    """
+    MessageServerInterface.sendSciCommand("ShowPosition",MountPosition,DistPositionX,DistPositionY)
+
+
+def GetCameraHomePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the home die coordinates when the home die is under the alignment camera
+    (for instance, the top camera).     Command was used during TrainReAlign to get
+    the start position for Z-Profiling. Command is no longer used.
+    API Status: internal
+    Returns:
+        XPosition:Decimal
+        YPosition:Decimal
+        ZPosition:Decimal
+    Command Timeout: 6000
+    Example:GetCameraHomePosition
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraHomePosition")
+    global GetCameraHomePosition_Response
+    if not "GetCameraHomePosition_Response" in globals(): GetCameraHomePosition_Response = namedtuple("GetCameraHomePosition_Response", "XPosition,YPosition,ZPosition")
+    return GetCameraHomePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SynchronizeCamera(MountPos="", SynchronizeXY="", SynchronizeZ=""):
+    """
+    Synchronizes the Platen camera with the calibration mark. The mark is mounted on
+    the chuck camera. The chuck must be moved to get the mark in view of the
+    specified camera.
+    API Status: published
+    Args:
+        MountPos:str = "Scope"
+        SynchronizeXY:int = 0
+        SynchronizeZ:int = 0
+    Returns:
+        XPosition:Decimal
+        YPosition:Decimal
+        ZPosition:Decimal
+    Command Timeout: 120000
+    Example:SynchronizeCamera S 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SynchronizeCamera",MountPos,SynchronizeXY,SynchronizeZ)
+    global SynchronizeCamera_Response
+    if not "SynchronizeCamera_Response" in globals(): SynchronizeCamera_Response = namedtuple("SynchronizeCamera_Response", "XPosition,YPosition,ZPosition")
+    return SynchronizeCamera_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ProbeCardOCS(UpdateZ="", MeasureBothGroups=""):
+    """
+    Determines the chuck XYZ axis position where the needles of the probe card are
+    in focus. The output parameter is the Z axis value in microns from zero of the
+    new focus height.
+    API Status: published
+    Args:
+        UpdateZ:int = 1
+        MeasureBothGroups:int = 1
+    Returns:
+        ZPosition:Decimal
+    Command Timeout: 360000
+    Example:ProbeCardOCS 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProbeCardOCS",UpdateZ,MeasureBothGroups)
+    return Decimal(rsp[0])
+
+def MoveChuckAutoXY(XPosition="", YPosition="", XSubsiteOffset="", YSubsiteOffset=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is sent by WaferMap to trigger AutoXY, AutoZ or VueTrack for each die
+    move. Automation must be activated/trained before command can be used. Response
+    is X, Y relative distance of adjustment from requested position.
+    API Status: internal
+    Args:
+        XPosition:Decimal = 0
+        YPosition:Decimal = 0
+        XSubsiteOffset:Decimal = 0
+        YSubsiteOffset:Decimal = 0
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 6000000
+    Example:MoveChuckAutoXY 5000 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveChuckAutoXY",XPosition,YPosition,XSubsiteOffset,YSubsiteOffset)
+    global MoveChuckAutoXY_Response
+    if not "MoveChuckAutoXY_Response" in globals(): MoveChuckAutoXY_Response = namedtuple("MoveChuckAutoXY_Response", "XOffset,YOffset")
+    return MoveChuckAutoXY_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def VueTrackAlign(FullVueTrackAlign=""):
+    """
+    Alignment for the next wafer when using VueTrack.
+    API Status: published
+    Args:
+        FullVueTrackAlign:int = 1
+    Command Timeout: 6000000
+    Example:VueTrackAlign
+    """
+    MessageServerInterface.sendSciCommand("VueTrackAlign",FullVueTrackAlign)
+
+
+def AutoFocusEVue(DistBelow="", DistAbove="", XOffsetCenter="", YOffsetCenter=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is only used internally for software testing and for providing backwards
+    compatibility with SCPI legacy commands. It executes a focus search using the
+    eVue focus drive.
+    API Status: internal
+    Args:
+        DistBelow:Decimal = 0
+        DistAbove:Decimal = 0
+        XOffsetCenter:int = 0
+        YOffsetCenter:int = 0
+    Returns:
+        FocusScore:Decimal
+        ZPosition:Decimal
+    Command Timeout: 30000
+    Example:AutoFocusEVue 200 200 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutoFocusEVue",DistBelow,DistAbove,XOffsetCenter,YOffsetCenter)
+    global AutoFocusEVue_Response
+    if not "AutoFocusEVue_Response" in globals(): AutoFocusEVue_Response = namedtuple("AutoFocusEVue_Response", "FocusScore,ZPosition")
+    return AutoFocusEVue_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AutoAlignOffAxis(SetValue=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes the ReAlign Wafer Alignment tool to do a theta alignment of the wafer
+    with optional index calculation or thermal expansion measurement. AutoAlign is
+    performed using the Platen camera. Only supported for systems with off-axis
+    camera.
+    API Status: internal
+    Args:
+        SetValue:int = 0
+    Command Timeout: 300000
+    Example:AutoAlignOffAxis 1
+    """
+    MessageServerInterface.sendSciCommand("AutoAlignOffAxis",SetValue)
+
+
+def FindFocusOffAxis(StepCount="", Range=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search. Focus search is performed using the Platen camera. Only supported for
+    systems with off-axis camera.
+    API Status: internal
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocusOffAxis 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocusOffAxis",StepCount,Range)
+    global FindFocusOffAxis_Response
+    if not "FindFocusOffAxis_Response" in globals(): FindFocusOffAxis_Response = namedtuple("FindFocusOffAxis_Response", "ZPosition,Stage")
+    return FindFocusOffAxis_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAuxOffAxis(AuxSiteID=""):
+    """
+    Performs an automated aux site alignment in XYZ using the Off Axis camera. Tool
+    can correct reference position and contact height for the given aux site.
+    API Status: published
+    Args:
+        AuxSiteID:int = 0
+    Command Timeout: 300000
+    Example:AlignAuxOffAxis 1
+    """
+    MessageServerInterface.sendSciCommand("AlignAuxOffAxis",AuxSiteID)
+
+
+def FindFocusPlaten(StepCount="", Range=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search. Uses the FindFocus tool settings but always the Platen camera -
+    independent of the FindFocus mount. This command is used on e.g. BlueRay systems
+    that have a platen camera but can't use ReAlign/DetectWaferHeight as they don't
+    have an upward looking camera.
+    API Status: internal
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocusPlaten 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocusPlaten",StepCount,Range)
+    global FindFocusPlaten_Response
+    if not "FindFocusPlaten_Response" in globals(): FindFocusPlaten_Response = namedtuple("FindFocusPlaten_Response", "ZPosition,Stage")
+    return FindFocusPlaten_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignChipOffAxis():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a single or two point alignment and moves the current chip to the
+    trained aligned position in Theta (in degrees) and X, Y (in microns). This
+    command is using the off axis platen camera with functionality of ReAlign.
+    API Status: internal
+    Returns:
+        ThetaOffset:Decimal
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 180000
+    Example:AlignChipOffAxis
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignChipOffAxis")
+    global AlignChipOffAxis_Response
+    if not "AlignChipOffAxis_Response" in globals(): AlignChipOffAxis_Response = namedtuple("AlignChipOffAxis_Response", "ThetaOffset,XOffset,YOffset")
+    return AlignChipOffAxis_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SelectAZoomLens(Lens=""):
+    """
+    Selects 1 of 4 symbolic lenses (4 classified coarse ranges).
+    API Status: published
+    Args:
+        Lens:int = 1
+    Command Timeout: 10000
+    Example:SelectAZoomLens 1
+    """
+    MessageServerInterface.sendSciCommand("SelectAZoomLens",Lens)
+
+
+def GetAZoomLens():
+    """
+    Returns 1 of 4 symbolic lenses, coarse ranges.
+    API Status: published
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    Example:GetAZoomLens
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAZoomLens")
+    return int(rsp[0])
+
+def AZoomSetupDialog():
+    """
+    Opens the operator panel. In this window you can change the settings for all
+    defined lenses.
+    API Status: published
+    Command Timeout: 5000
+    Example:AZoomSetupDialog
+    """
+    MessageServerInterface.sendSciCommand("AZoomSetupDialog")
+
+
+def MoveAZoomFocus(Focus="", Ref=""):
+    """
+    Changes the focus magnitude.
+    API Status: published
+    Args:
+        Focus:int = 100
+        Ref:str = "R"
+    Returns:
+        RetFocus:int
+    Command Timeout: 10000
+    Example:MoveAZoomFocus 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAZoomFocus",Focus,Ref)
+    return int(rsp[0])
+
+def ReadAZoomFocus():
+    """
+    Returns the focus magnitude.
+    API Status: published
+    Returns:
+        Focus:int
+    Command Timeout: 5000
+    Example:ReadAZoomFocus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAZoomFocus")
+    return int(rsp[0])
+
+def MoveAZoomVelocity(Direction="", Velocity=""):
+    """
+    Moves the A-Zoom using the set focus speed.
+    API Status: published
+    Args:
+        Direction:str = ""
+        Velocity:int = 100
+    Returns:
+        RetVelocity:Decimal
+    Command Timeout: 240000
+    Example:MoveAZoomVelocity + 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAZoomVelocity",Direction,Velocity)
+    return Decimal(rsp[0])
+
+def StopAZoom():
+    """
+    Stops the A-Zoom movements.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopAZoom
+    """
+    MessageServerInterface.sendSciCommand("StopAZoom")
+
+
+def SetAZoomLight(Light=""):
+    """
+    Switches all lights ON or OFF. ON means the values defined by the current lens.
+    1 switches the light on, 0 switches the light off. Without parameter toggles
+    between on an off.
+    API Status: published
+    Args:
+        Light:int = 0
+    Command Timeout: 5000
+    Example:SetAZoomLight 1
+    """
+    MessageServerInterface.sendSciCommand("SetAZoomLight",Light)
+
+
+def CloseAZoom():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the OpticalControl application. Used during Project File handling.
+    API Status: internal
+    Command Timeout: 5000
+    Example:CloseAZoom
+    """
+    MessageServerInterface.sendSciCommand("CloseAZoom")
+
+
+def OCLightVal(Value="", Channel="", Segment=""):
+    """
+    Set the brightness of given channel and segment to the given value.
+    API Status: published
+    Args:
+        Value:int = 0
+        Channel:int = 1
+        Segment:int = 1
+    Command Timeout: 5000
+    Example:OCLightVal 128 1 4
+    """
+    MessageServerInterface.sendSciCommand("OCLightVal",Value,Channel,Segment)
+
+
+def OCLightOn(On="", Channel=""):
+    """
+    Switch the light (if it has segments then all) in a given channel ON or OFF.
+    Switch ON - that means: light to the before adjusted brightness.
+    API Status: published
+    Args:
+        On:int = 0
+        Channel:int = 1
+    Command Timeout: 5000
+    Example:OCLightOn 1 1
+    """
+    MessageServerInterface.sendSciCommand("OCLightOn",On,Channel)
+
+
+def OCSetZoomLevel(Zoom="", Motor=""):
+    """
+    Set logical zoom factor for given motor (if has more then one, else to the one)
+    API Status: published
+    Args:
+        Zoom:int = 0
+        Motor:int = 1
+    Command Timeout: 5000
+    Example:OCSetZoomLevel 50 1
+    """
+    MessageServerInterface.sendSciCommand("OCSetZoomLevel",Zoom,Motor)
+
+
+def OCGetZoomLevel(Motor=""):
+    """
+    Get logical zoom factor for given motor (if has more then one, else to the one)
+    API Status: published
+    Args:
+        Motor:int = 1
+    Returns:
+        Zoom:int
+    Command Timeout: 5000
+    Example:OCGetZoomLevel 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("OCGetZoomLevel",Motor)
+    return int(rsp[0])
+
+def StartReAlignTemperature(TargetTemperature="", ThetaAlignOnFinish="", ContactOnFinish=""):
+    """
+    Starts temperature ramping using ReAlign. ReAlign will re-adjust the probes and
+    wafer during ramping to the new target temperature. Command returns immediately.
+    The status of temperature ramping must be checked using the
+    GetReAlignTemperatureStatus command.
+    API Status: published
+    Args:
+        TargetTemperature:Decimal = 0
+        ThetaAlignOnFinish:int = 0
+        ContactOnFinish:int = 0
+    Command Timeout: 5000
+    Example:StartReAlignTemperature 150
+    """
+    MessageServerInterface.sendSciCommand("StartReAlignTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish)
+
+
+def StopReAlignTemperature():
+    """
+    Stops temperature ramping using ReAlign.
+    API Status: published
+    Command Timeout: 10000
+    Example:StopReAlignTemperature
+    """
+    MessageServerInterface.sendSciCommand("StopReAlignTemperature")
+
+
+def GetReAlignTemperatureStatus():
+    """
+    Returns the status of the current temperature ramping using ReAlign process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 300000
+    Example:GetReAlignTemperatureStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetReAlignTemperatureStatus")
+    global GetReAlignTemperatureStatus_Response
+    if not "GetReAlignTemperatureStatus_Response" in globals(): GetReAlignTemperatureStatus_Response = namedtuple("GetReAlignTemperatureStatus_Response", "StatusId,StatusStr")
+    return GetReAlignTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReAlign(Repeats="", Mode="", AlignProbeCard="", CorrectZ=""):
+    """
+    Performs an automatic realignment of the wafer. This includes measuring the
+    needle drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck
+    drift XYZ and optionally a Z-Profile. Alternatively the tool performs a
+    ProbeToDie Alignment to correct the needle position for the current die. Command
+    returns once ReAlign is finished or aborted because of an error.
+    API Status: published
+    Args:
+        Repeats:int = 1
+        Mode:str = "H"
+        AlignProbeCard:int = 2
+        CorrectZ:int = 2
+    Returns:
+        XOffsetWafer:Decimal
+        YOffsetWafer:Decimal
+        ZOffsetWafer:Decimal
+        XOffsetCard:Decimal
+        YOffsetCard:Decimal
+        ZOffsetCard:Decimal
+    Command Timeout: 1000000
+    Example:ReAlign 2 H 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+    global ReAlign_Response
+    if not "ReAlign_Response" in globals(): ReAlign_Response = namedtuple("ReAlign_Response", "XOffsetWafer,YOffsetWafer,ZOffsetWafer,XOffsetCard,YOffsetCard,ZOffsetCard")
+    return ReAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def NextWafer():
+    """
+    Starts the NextWafer routine.
+    API Status: published
+    Returns:
+        Canceled:int
+    Command Timeout: 60000000
+    Example:NextWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("NextWafer")
+    return int(rsp[0])
+
+def StartReAlign(Repeats="", Mode="", AlignProbeCard="", CorrectZ=""):
+    """
+    Starts an automatic realignment of the wafer. This includes measuring the needle
+    drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck drift
+    XYZ and optionally a Z-Profile. Alternatively the tool performs a ProbeToPad
+    Alignment to correct the needle position for the current die. Command returns
+    immediately. The status of the asynchronous ReAlign execution must be checked
+    using the GetReAlignStatus command.
+    API Status: published
+    Args:
+        Repeats:int = 1
+        Mode:str = "H"
+        AlignProbeCard:int = 2
+        CorrectZ:int = 2
+    Command Timeout: 60000
+    Example:StartReAlign 2 H 0 0
+    """
+    MessageServerInterface.sendSciCommand("StartReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+
+
+def StopReAlign():
+    """
+    Stops the ReAlign procedure.
+    API Status: published
+    Command Timeout: 120000
+    Example:StopReAlign
+    """
+    MessageServerInterface.sendSciCommand("StopReAlign")
+
+
+def GetReAlignStatus():
+    """
+    Returns a status of the ReAlign procedure. If the return value is true, ReAlign
+    is running.
+    API Status: published
+    Returns:
+        Running:int
+    Command Timeout: 60000
+    Example:GetReAlignStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetReAlignStatus")
+    return int(rsp[0])
+
+def EnableOverlay(Overlay=""):
+    """
+    Allows activating the overlay of the needles for the top camera.
+    API Status: published
+    Args:
+        Overlay:int = 0
+    Command Timeout: 6000
+    Example:EnableOverlay 0
+    """
+    MessageServerInterface.sendSciCommand("EnableOverlay",Overlay)
+
+
+def SwitchOffset(Offset=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Switches the offset compensation. Applicable for MicroAlign stations only.
+    API Status: internal
+    Args:
+        Offset:int = 0
+    Command Timeout: 60000
+    Example:SwitchOffset 1
+    """
+    MessageServerInterface.sendSciCommand("SwitchOffset",Offset)
+
+
+def TrainFeature(Model=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command was only implemented for supporting a SCPI legacy command. Does not make
+    sense in Velox, as there is no default training rectangle on the screen as in
+    Nucleus.
+    API Status: internal
+    Args:
+        Model:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 30000
+    Example:TrainFeature 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("TrainFeature",Model)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetEvueExposureLevel():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the exposure value of the eVue. Implemented for supporting SCPI legacy
+    command.
+    API Status: internal
+    Returns:
+        Exposure:Decimal
+    Command Timeout: 10000
+    Example:GetEvueExposureLevel
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueExposureLevel")
+    return Decimal(rsp[0])
+
+def SetEvueExposureLevel(Exposure=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the exposure value of the eVue. Implemented for supporting SCPI legacy
+    command.
+    API Status: internal
+    Args:
+        Exposure:Decimal = 0
+    Command Timeout: 10000
+    Example:SetEvueExposureLevel
+    """
+    MessageServerInterface.sendSciCommand("SetEvueExposureLevel",Exposure)
+
+
+def MoveEvueFocusStage(EvueZ="", EvueVelocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the eVue focus stage to a specified position. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Args:
+        EvueZ:Decimal = 0
+        EvueVelocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveEvueFocusStage 1000
+    """
+    MessageServerInterface.sendSciCommand("MoveEvueFocusStage",EvueZ,EvueVelocity)
+
+
+def GetEvueFocusStagePos():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the eVue focus stage. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Returns:
+        EvueZ:Decimal
+    Command Timeout: 5000
+    Example:GetEvueFocusStagePos
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueFocusStagePos")
+    return Decimal(rsp[0])
+
+def RunEvueAutoExpose(UseCB=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command runs the AutoExpose function for the eVue. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Args:
+        UseCB:int = 1
+    Command Timeout: 20000
+    Example:RunEvueAutoExpose 1
+    """
+    MessageServerInterface.sendSciCommand("RunEvueAutoExpose",UseCB)
+
+
+def GetEvueZoomLevel():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Valid only with the eVue microscope that is connected to Velox.     On eVue
+    systems, this command, returns values ranging from 0.5 to 5.0 for a 10x system
+    and 0.5 to 20.0 for a 40x system.
+    API Status: internal
+    Returns:
+        Zoom:Decimal
+    Command Timeout: 5000
+    Example:GetEvueZoomLevel
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueZoomLevel")
+    return Decimal(rsp[0])
+
+def SetEvueZoomLevel(Zoom=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Valid only with the eVue microscope or an A-Zoom microscope that is connected to
+    Velox. On eVue systems, this command sets the proper CCD zoom level to the
+    appropriate optical path.
+    API Status: internal
+    Args:
+        Zoom:Decimal = 0
+    Command Timeout: 5000
+    Example:SetEvueZoomLevel 2.0
+    """
+    MessageServerInterface.sendSciCommand("SetEvueZoomLevel",Zoom)
+
+
+def StartAutomationTemperature(TargetTemperature="", ThetaAlignOnFinish="", ContactOnFinish="", AlignOnFinish=""):
+    """
+    Starts temperature ramping using Automation. The Automation (mostly VueTrack)
+    will re-adjust the probes and wafer during ramping to the new target
+    temperature.
+    API Status: published
+    Args:
+        TargetTemperature:Decimal = 0
+        ThetaAlignOnFinish:int = 0
+        ContactOnFinish:int = 0
+        AlignOnFinish:int = 1
+    Command Timeout: 5000
+    Example:StartAutomationTemperature 150
+    """
+    MessageServerInterface.sendSciCommand("StartAutomationTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish,AlignOnFinish)
+
+
+def StopAutomationTemperature():
+    """
+    Stops temperature ramping using Automation.
+    API Status: published
+    Command Timeout: 10000
+    Example:StopAutomationTemperature
+    """
+    MessageServerInterface.sendSciCommand("StopAutomationTemperature")
+
+
+def GetAutomationTemperatureStatus():
+    """
+    Returns the status of the current temperature ramping using automation process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 300000
+    Example:GetAutomationTemperatureStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationTemperatureStatus")
+    global GetAutomationTemperatureStatus_Response
+    if not "GetAutomationTemperatureStatus_Response" in globals(): GetAutomationTemperatureStatus_Response = namedtuple("GetAutomationTemperatureStatus_Response", "StatusId,StatusStr")
+    return GetAutomationTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationActive():
+    """
+    Command to read from Spectrum if Automation (AutoXY, AutoZ or VueTrack) is
+    active. Command is used     by WaferMap to read if it must send MoveChuckAutoXY
+    instead of MoveChuck
+    API Status: published
+    Returns:
+        Active:int
+    Command Timeout: 1000
+    Example:GetAutomationActive
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationActive")
+    return int(rsp[0])
+
+def AutomationNeedleSearch(NeedleIndex="", MoveScope=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    VueTrack vision search of the given needle index.
+    API Status: internal
+    Args:
+        NeedleIndex:int = 1
+        MoveScope:int = 1
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+        ZOffset:Decimal
+        XYMatchScore:Decimal
+        ZMatchScore:Decimal
+    Command Timeout: 60000
+    Example:AutomationNeedleSearch 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationNeedleSearch",NeedleIndex,MoveScope)
+    global AutomationNeedleSearch_Response
+    if not "AutomationNeedleSearch_Response" in globals(): AutomationNeedleSearch_Response = namedtuple("AutomationNeedleSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore,ZMatchScore")
+    return AutomationNeedleSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def AutomationReferenceSearch():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    AutomationReferenceSearch exposes the functionality of searching the Automation
+    reference target via remote command
+    API Status: internal
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+        ZOffset:Decimal
+        XYMatchScore:Decimal
+    Command Timeout: 60000
+    Example:AutomationReferenceSearch
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationReferenceSearch")
+    global AutomationReferenceSearch_Response
+    if not "AutomationReferenceSearch_Response" in globals(): AutomationReferenceSearch_Response = namedtuple("AutomationReferenceSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore")
+    return AutomationReferenceSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def MovePositionersSafe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the configured motorized positioners to a safe position
+    API Status: internal
+    Command Timeout: 60000
+    Example:MovePositionersSafe
+    """
+    MessageServerInterface.sendSciCommand("MovePositionersSafe")
+
+
+def SetConstantContactMode(IsOn="", ForceLastCorrection=""):
+    """
+    Starts Constant Contact mode using Automation. The Automation will re-adjust the
+    wafer during ramping to the new target temperature.
+    API Status: published
+    Args:
+        IsOn:int = 0
+        ForceLastCorrection:int = 0
+    Command Timeout: 5000
+    Example:SetConstantContactMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetConstantContactMode",IsOn,ForceLastCorrection)
+
+
+def GetConstantContactModeStatus():
+    """
+    Returns the status of the current ConstantContact automation process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 5000
+    Example:GetConstantContactModeStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetConstantContactModeStatus")
+    global GetConstantContactModeStatus_Response
+    if not "GetConstantContactModeStatus_Response" in globals(): GetConstantContactModeStatus_Response = namedtuple("GetConstantContactModeStatus_Response", "StatusId,StatusStr")
+    return GetConstantContactModeStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetAutomationActive(Activate=""):
+    """
+    Command to set if Automation (AutoXY, AutoZ or VueTrack) is active. Command can
+    be used to e.g. deactivate automation     programmatically in case it is no
+    longer used.     When activating automation, the command will return an error in
+    case it is not possible (e.g. not trained)
+    API Status: published
+    Args:
+        Activate:int = 0
+    Command Timeout: 1000
+    Example:SetAutomationActive 1
+    """
+    MessageServerInterface.sendSciCommand("SetAutomationActive",Activate)
+
+
+def AutomationSearchCurrentDie():
+    """
+    Performs an Automation search and position correction using the current chuck
+    position. Response is X, Y relative distance of adjustment.
+    API Status: published
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 6000000
+    Example:AutomationSearchCurrentDie
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationSearchCurrentDie")
+    global AutomationSearchCurrentDie_Response
+    if not "AutomationSearchCurrentDie_Response" in globals(): AutomationSearchCurrentDie_Response = namedtuple("AutomationSearchCurrentDie_Response", "XOffset,YOffset")
+    return AutomationSearchCurrentDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def PreMapWafer():
+    """
+    PreMapWafer finds actual singulated die locations and updates positions used by
+    WaferMap.
+    API Status: published
+    Returns:
+        NumberOfDies:int
+    Command Timeout: 14400000
+    Example:PreMapWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("PreMapWafer")
+    return int(rsp[0])
+
+def ISSProbeAlign():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs an probe to pad operation on the ISS with two RF positioners.
+    API Status: internal
+    Command Timeout: 6000000
+    Example:ISSProbeAlign
+    """
+    MessageServerInterface.sendSciCommand("ISSProbeAlign")
+
+
+def FindWaferCenter(NoManualRecovery=""):
+    """
+    FindWaferCenter finds the center of the wafer using edge detection.
+    API Status: published
+    Args:
+        NoManualRecovery:int = 0
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 300000
+    Example:FindWaferCenter
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindWaferCenter",NoManualRecovery)
+    global FindWaferCenter_Response
+    if not "FindWaferCenter_Response" in globals(): FindWaferCenter_Response = namedtuple("FindWaferCenter_Response", "ChuckX,ChuckY")
+    return FindWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def LocateHomeDie(NoManualRecovery=""):
+    """
+    LocateHomeDie finds the center of the wafer using edge detection and sets the
+    home position.
+    API Status: published
+    Args:
+        NoManualRecovery:int = 0
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 300000
+    Example:LocateHomeDie
+    """
+    rsp = MessageServerInterface.sendSciCommand("LocateHomeDie",NoManualRecovery)
+    global LocateHomeDie_Response
+    if not "LocateHomeDie_Response" in globals(): LocateHomeDie_Response = namedtuple("LocateHomeDie_Response", "ChuckX,ChuckY")
+    return LocateHomeDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetAutomationProbeLayout(LayoutName="", ProbeID="", XOffset="", YOffset=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stores the provided X or Y offset for the given probe for the specified layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+    Command Timeout: 10000
+    Example:SetAutomationProbeLayout "layout1" 1 100.0 0
+    """
+    MessageServerInterface.sendSciCommand("SetAutomationProbeLayout",LayoutName,ProbeID,XOffset,YOffset)
+
+
+def DeleteAutomationProbeLayout(LayoutName="", ProbeID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Delete the specfied layout. If LayoutName is empty then all layouts are deleted.
+    If optional ProbeID parmameter is set, it removes just that probe from the
+    layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+    Command Timeout: 10000
+    Example:DeleteAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("DeleteAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def CaptureAutomationProbeLayout(LayoutName="", ProbeID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Capture the specfied layout. If optional ProbeID parmameter is set, it captures
+    just that probe from the layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+    Command Timeout: 30000
+    Example:CaptureAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("CaptureAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def MoveToAutomationProbeLayout(LayoutName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move to the probes to specfied layout which are offsets from the trained
+    positions.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+    Command Timeout: 300000
+    Example:MoveToAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("MoveToAutomationProbeLayout",LayoutName)
+
+
+def ResetAutomation():
+    """
+    Reset automation data back to trained values.
+    API Status: published
+    Command Timeout: 10000
+    Example:ResetAutomation
+    """
+    MessageServerInterface.sendSciCommand("ResetAutomation")
+
+
+def GetWaferCenter():
+    """
+    GetWaferCenter returns the chuck location (zero based) of the wafer center. It
+    returns 0 0 if FindWaferCenter has not been executed for the current wafer.
+    API Status: published
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 10000
+    Example:GetWaferCenter
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferCenter")
+    global GetWaferCenter_Response
+    if not "GetWaferCenter_Response" in globals(): GetWaferCenter_Response = namedtuple("GetWaferCenter_Response", "ChuckX,ChuckY")
+    return GetWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def InitEvueFocusStage():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initializes the eVue focus stage by finding the limit switches
+    API Status: internal
+    Command Timeout: 30000
+    Example:InitEvueFocusStage
+    """
+    MessageServerInterface.sendSciCommand("InitEvueFocusStage")
+
+
+def EvueSetNumTraceEntriesPreTrigger(NumTraceEntriesPreTrigger=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the number of trace log items to preserve prior to the trigger event. With
+    the continuous event capture log in Bluestone, up to {X} events are captured and
+    kept after the trigger event is sensed. Then, events are captured after the
+    trigger event until the trace log is full and then trace capture is halted.
+    API Status: internal
+    Args:
+        NumTraceEntriesPreTrigger:int = 0
+    Command Timeout: 30000
+    Example:EvueSetNumTraceEntriesPreTrigger 14
+    """
+    MessageServerInterface.sendSciCommand("EvueSetNumTraceEntriesPreTrigger",NumTraceEntriesPreTrigger)
+
+
+def EvueGetNumTraceEntriesPreTrigger():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the number of trace log items to preserve prior to the trigger event. With
+    the continuous event capture log in Bluestone, up to {X} events are captured and
+    kept after the trigger event is sensed. Then, events are captured after the
+    trigger event until the trace log is full and then trace capture is halted.
+    API Status: internal
+    Returns:
+        NumTraceEntriesPreTrigger:int
+    Command Timeout: 30000
+    Example:EvueGetNumTraceEntriesPreTrigger
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntriesPreTrigger")
+    return int(rsp[0])
+
+def EvueStartCaptureServoTrace():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts capturing events in the eVue motion capture log. Capture continues until
+    the log is full. However, log entries will overwrite the oldest entry until the
+    trigger event is encountered. Then, {X} events are preserved prior to the
+    trigger event and the oldest events are only overwritten if they are not part of
+    that preserved set.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EvueStartCaptureServoTrace
+    """
+    MessageServerInterface.sendSciCommand("EvueStartCaptureServoTrace")
+
+
+def EvueGetTraceMachineStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current status of the trace machine. Bit fields - bit0 is 1 and bit4 is
+    16, etc. bit0 - active and in pre-trigger state bit1 - active and in post-
+    trigger state bit2 - stopped by servo error, lens crash or lens removal bit3 -
+    stopped on requested server state entry bit4 - stopped by immediate command
+    bit5..31 - reserved
+    API Status: internal
+    Returns:
+        TraceMachineStatus:int
+    Command Timeout: 30000
+    Example:EvueGetTraceMachineStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetTraceMachineStatus")
+    return int(rsp[0])
+
+def EvueSetTraceCaptureStopBits(TraceCaptureStopBits=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets condition bits to trigger servo trace capture. Bit fields - bit0 is 1 and
+    bit4 is 16, etc. bit0 - immediate stop bit1 - stop on servo error, lens crash or
+    lens removal bit2 - stop on requested server state (defined by bits 4..7) bit3 -
+    stop on motor move finish bit4..7 - servo state that triggers a trace stop (not
+    an index but the 4-bit state that, if seen, is the trigger for trace capture)
+    bit8..31 - reserved
+    API Status: internal
+    Args:
+        TraceCaptureStopBits:int = 0
+    Command Timeout: 30000
+    Example:EvueSetTraceCaptureStopBits
+    """
+    MessageServerInterface.sendSciCommand("EvueSetTraceCaptureStopBits",TraceCaptureStopBits)
+
+
+def EvueGetNumTraceEntries():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current status of the trace machine.
+    API Status: internal
+    Returns:
+        TraceEntries:int
+    Command Timeout: 30000
+    Example:EvueGetNumTraceEntries
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntries")
+    return int(rsp[0])
+
+def EvueGetTraceEntry(EntryIdx=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the N'th trace entry in the log.
+    API Status: internal
+    Args:
+        EntryIdx:int = 0
+    Returns:
+        CommandedPositionMotorCounts:int
+        CommandedPositionMicrons:Decimal
+        MeasuredPositionMotorCounts:int
+        MeasuredPositionMicrons:Decimal
+        TimestampMicroseconds:int
+        ServoStatus:int
+        PwmVal:int
+    Command Timeout: 30000
+    Example:EvueGetTraceEntry 32
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetTraceEntry",EntryIdx)
+    global EvueGetTraceEntry_Response
+    if not "EvueGetTraceEntry_Response" in globals(): EvueGetTraceEntry_Response = namedtuple("EvueGetTraceEntry_Response", "CommandedPositionMotorCounts,CommandedPositionMicrons,MeasuredPositionMotorCounts,MeasuredPositionMicrons,TimestampMicroseconds,ServoStatus,PwmVal")
+    return EvueGetTraceEntry_Response(int(rsp[0]),Decimal(rsp[1]),int(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def AutomationRFProbeSearch(ImageFilename=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the distance in X,Y between the center tips of the RF probes.
+    API Status: internal
+    Args:
+        ImageFilename:str = ""
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    Example:AutomationRFProbeSearch
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationRFProbeSearch",ImageFilename)
+    global AutomationRFProbeSearch_Response
+    if not "AutomationRFProbeSearch_Response" in globals(): AutomationRFProbeSearch_Response = namedtuple("AutomationRFProbeSearch_Response", "X,Y")
+    return AutomationRFProbeSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def StartAutoRFCalibration():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts the AutoRF calibration sequence.
+    API Status: internal
+    Command Timeout: 3000
+    Example:StartAutoRFCalibration
+    """
+    MessageServerInterface.sendSciCommand("StartAutoRFCalibration")
+
+
+def StopAutoRFCalibration():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the currently running AutoRF calibraiton.
+    API Status: internal
+    Command Timeout: 10000
+    Example:StopAutoRFCalibration
+    """
+    MessageServerInterface.sendSciCommand("StopAutoRFCalibration")
+
+
+def GetAutoRFCalibrationStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the status of the AutoRF calibration sequence.
+    API Status: internal
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 1000
+    Example:GetAutoRFCalibrationStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutoRFCalibrationStatus")
+    global GetAutoRFCalibrationStatus_Response
+    if not "GetAutoRFCalibrationStatus_Response" in globals(): GetAutoRFCalibrationStatus_Response = namedtuple("GetAutoRFCalibrationStatus_Response", "StatusId,StatusStr")
+    return GetAutoRFCalibrationStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationLastStepDiagnostics(Index=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the diagnostic state information for the provided index.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        DiagnosticInfo:str
+    Command Timeout: 5000
+    Example:GetAutomationLastStepDiagnostics
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationLastStepDiagnostics",Index)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMNanoChamberState(State=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the WLEM Nano Chamber State.
+    API Status: internal
+    Args:
+        State:str = "Free"
+    Command Timeout: 5000
+    Example:SetWLEMNanoChamberState Free
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMNanoChamberState",State)
+
+
+def GetWLEMNanoChamberState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the WLEM Nano Chamber State.
+    API Status: internal
+    Returns:
+        State:str
+    Command Timeout: 5000
+    Example:GetWLEMNanoChamberState
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMNanoChamberState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMState(State="", Value=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the state of a WLEM pneumatic control (valve).
+    API Status: internal
+    Args:
+        State:str = "NCSeal"
+        Value:int = 0
+    Command Timeout: 5000
+    Example:SetWLEMState NCSeal 1
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMState",State,Value)
+
+
+def GetWLEMState(State=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the state of a WLEM pneumatic control (valve).
+    API Status: internal
+    Args:
+        State:str = "NCSeal"
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:GetWLEMState NCSeal
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMState",State)
+    return int(rsp[0])
+
+def GetWLEMSensorValue(Sensor=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the value of a WLEM Sensor.
+    API Status: internal
+    Args:
+        Sensor:str = "O2Concentration"
+    Returns:
+        Value:Decimal
+    Command Timeout: 5000
+    Example:GetWLEMSensorValue O2Concentration
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMSensorValue",Sensor)
+    return Decimal(rsp[0])
+
+def SetWLEMOption(Option="", Value=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets a WLEM Control program option.
+    API Status: internal
+    Args:
+        Option:str = "MinimizeToTray"
+        Value:int = 0
+    Command Timeout: 5000
+    Example:SetWLEMOption MinimizeToTray 1
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMOption",Option,Value)
+
+
+def GetWLEMOption(Option=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets a WLEM Control program option.
+    API Status: internal
+    Args:
+        Option:str = "MinimizeToTray"
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:GetWLEMOption MinimizeToTray
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMOption",Option)
+    return int(rsp[0])
+
+def NewTesterProject(LotID="", TileID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that a new Lot/Tile is to be tested. The tester
+    responds with the correct project name for the test. This is needed because the
+    prober needs to verify that the correct project is loaded. In case no valid
+    project is available, the command is returned with an error.
+    API Status: internal
+    Args:
+        LotID:str = ""
+        TileID:str = ""
+    Returns:
+        ProjectName:str
+    Command Timeout: 30000
+    Example:NewTesterProject Lot01 Tile01
+    """
+    rsp = MessageServerInterface.sendSciCommand("NewTesterProject",LotID,TileID)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StartMeasurement(DieColumn="", DieRow="", ActiveDies=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester to begin measuring (Needles are in correct
+    position and in contact). The command is responded when the measurement has
+    finished. The response string holds the binning information separated by comma.
+    For deactivated dies, a bin value of '0' should be responded.
+    API Status: internal
+    Args:
+        DieColumn:int = 0
+        DieRow:int = 0
+        ActiveDies:str = ""
+    Returns:
+        BinNumbers:str
+    Command Timeout: 100000
+    Example:StartMeasurement 1 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StartMeasurement",DieColumn,DieRow,ActiveDies)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def EndOfWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester, that the test of the current substrate has
+    finished. It enables the tester application to save measurement data and/or
+    prepare for the next substrate.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EndOfWafer
+    """
+    MessageServerInterface.sendSciCommand("EndOfWafer")
+
+
+def EndOfLot():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester, that the test of the current lot has finished. It
+    enables the tester application to save measurement data and/or prepare for the
+    next lot.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EndOfLot
+    """
+    MessageServerInterface.sendSciCommand("EndOfLot")
+
+
+def VerifyProductID(ProductID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the ProductID that is to be tested. The
+    tester can respond with an error in case the ProductID is not allowed for
+    testing.
+    API Status: internal
+    Args:
+        ProductID:str = ""
+    Command Timeout: 30000
+    Example:VerifyProductID Product123
+    """
+    MessageServerInterface.sendSciCommand("VerifyProductID",ProductID)
+
+
+def VerifyLotID(LotID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the LotID that is to be tested. The tester
+    can respond with an error in case the LotID is not allowed for testing.
+    API Status: internal
+    Args:
+        LotID:str = ""
+    Command Timeout: 30000
+    Example:VerifyLotID Lot123
+    """
+    MessageServerInterface.sendSciCommand("VerifyLotID",LotID)
+
+
+def VerifySubstrateID(SubstrateID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the SubstrateID that is to be tested. The
+    tester can respond with an error in case the SubstrateID is not allowed for
+    testing.
+    API Status: internal
+    Args:
+        SubstrateID:str = ""
+    Command Timeout: 30000
+    Example:VerifySubstrateID Substrate123
+    """
+    MessageServerInterface.sendSciCommand("VerifySubstrateID",SubstrateID)
+
+
+def VerifyProbecard(ProbeCard="", Touchdowns=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the ProbecardID and touchdowns that is
+    used for testing. The tester can respond with an error in case the Probecard is
+    not allowed for testing.
+    API Status: internal
+    Args:
+        ProbeCard:str = ""
+        Touchdowns:int = 0
+    Command Timeout: 30000
+    Example:VerifyProbecard Probecard123 10596
+    """
+    MessageServerInterface.sendSciCommand("VerifyProbecard",ProbeCard,Touchdowns)
+
+
+def VerifyUserID(User=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the User ID. The tester can respond with
+    an error in case the User ID is not allowed for testing.
+    API Status: internal
+    Args:
+        User:str = ""
+    Command Timeout: 30000
+    Example:VerifyUserID User123
+    """
+    MessageServerInterface.sendSciCommand("VerifyUserID",User)
+
+
+def TesterAbort():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that the job was aborted and no more test will
+    happen.
+    API Status: internal
+    Command Timeout: 30000
+    Example:TesterAbort
+    """
+    MessageServerInterface.sendSciCommand("TesterAbort")
+
+
+def VerifySOTReady():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that a wafer is ready for testing which will
+    immediately start. This command is sent in the recipe sequence "Verify
+    SOTReady".
+    API Status: internal
+    Command Timeout: 30000
+    Example:VerifySOTReady
+    """
+    MessageServerInterface.sendSciCommand("VerifySOTReady")
+
+
+def VerifyWaferStart(SubstrateID="", CassettePlace="", LotID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is sent in the VeloxPro recipe sequence "Verify Wafer Start" and
+    informs the tester about the current wafer on the chuck.
+    API Status: internal
+    Args:
+        SubstrateID:str = ""
+        CassettePlace:str = ""
+        LotID:str = ""
+    Command Timeout: 30000
+    Example:VerifyWaferStart Wafer01 1 Lot01
+    """
+    MessageServerInterface.sendSciCommand("VerifyWaferStart",SubstrateID,CassettePlace,LotID)
+
+
+def TesterCassetteInfo(CassetteCmd=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command will be sent after the user selected which wafers are to be tested.
+    It contains a string which represents the state of each wafer: 0 = empty, 1 =
+    full (and selected), 2 = error (e.g. double slotted), 3 = unknown, 4 =
+    deselected
+    API Status: internal
+    Args:
+        CassetteCmd:str = ""
+    Returns:
+        CassetteRsp:str
+    Command Timeout: 30000
+    Example:TesterCassetteInfo 0000001110000000010010111
+    """
+    rsp = MessageServerInterface.sendSciCommand("TesterCassetteInfo",CassetteCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def VerifyProject(ProjectName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is sent after selecting a project file in the VeloxPro product
+    setup page. The command sends the name of the project to tester for
+    verification.
+    API Status: internal
+    Args:
+        ProjectName:str = ""
+    Command Timeout: 30000
+    Example:VerifyProject C:/Users/Public/Documents/Velox/Projects/Test.spp
+    """
+    MessageServerInterface.sendSciCommand("VerifyProject",ProjectName)
+
+
+def TesterAbortWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that the test for the current wafer was aborted
+    and no more tests will happen with the current wafer. The job will continue
+    though.
+    API Status: internal
+    Command Timeout: 30000
+    Example:TesterAbortWafer
+    """
+    MessageServerInterface.sendSciCommand("TesterAbortWafer")
+
+
+def DoTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts execution of one test. It returns a bin number or multple bin numbers
+    when clusters are enabled in the WaferMap (one number for each die in a
+    cluster).  The command starts execution of one test. It returns a bin number or
+    multple bin numbers when clusters are enabled in the WaferMap (one number for
+    each die in a cluster).
+    API Status: internal
+    Returns:
+        BitNumber:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DoTTLTest")
+    return int(rsp[0])
+
+def StartTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts the test of a wafer. Depending on the cluster definitions queried from
+    the WaferMap, all clusters or all dies will be tested.  The command starts the
+    test of a wafer. Depending on the cluster definitions queried from the WaferMap
+    all clusters or all dies will be tested.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("StartTTLTest")
+
+
+def CancelTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the wafer test.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CancelTTLTest")
+
+
+def SetTTLLine(Line="", Value=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the selected line of PA port.
+    API Status: internal
+    Args:
+        Line:int = 0
+        Value:int = 0
+    Command Timeout: 10000
+    Example:SetTTLLine 2 0
+    """
+    MessageServerInterface.sendSciCommand("SetTTLLine",Line,Value)
+
+
+def GetTTLLines():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the I/O lines as bit array.
+    API Status: internal
+    Returns:
+        LineA:int
+        LineB:int
+        LineC:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTTLLines")
+    global GetTTLLines_Response
+    if not "GetTTLLines_Response" in globals(): GetTTLLines_Response = namedtuple("GetTTLLines_Response", "LineA,LineB,LineC")
+    return GetTTLLines_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetTTLStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns returns the error 914 if the test is in progress.
+    API Status: internal
+    Returns:
+        ErrCode:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTTLStatus")
+    return int(rsp[0])
+
+def StartScript(ScriptName=""):
+    """
+    Starts the script and returns the response immediately.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Command Timeout: 10000
+    Example:StartScript myscript
+    """
+    MessageServerInterface.sendSciCommand("StartScript",ScriptName)
+
+
+def GetRunStatus(ScriptName=""):
+    """
+    Command returns information about Communicator status.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Returns:
+        Running:int
+        LastError:int
+        Title:str
+    Command Timeout: 5000
+    Example:GetRunStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetRunStatus",ScriptName)
+    global GetRunStatus_Response
+    if not "GetRunStatus_Response" in globals(): GetRunStatus_Response = namedtuple("GetRunStatus_Response", "Running,LastError,Title")
+    return GetRunStatus_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def CloseCommunicator():
+    """
+    Command closes the program. Used during ProjectFile handling.
+    API Status: published
+    Command Timeout: 10000
+    Example:CloseCommunicator
+    """
+    MessageServerInterface.sendSciCommand("CloseCommunicator")
+
+
+def DoScript(ScriptName=""):
+    """
+    Executes the script and returns the response afterwards.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Command Timeout: 10000000
+    Example:DoScript myscript
+    """
+    MessageServerInterface.sendSciCommand("DoScript",ScriptName)
+
+
+def ReadKernelData(SilentMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads Kernel Data to KernelSetup (Left Program pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReadKernelData 0
+    """
+    MessageServerInterface.sendSciCommand("ReadKernelData",SilentMode)
+
+
+def SaveKernelDataAs(FileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves Kernel Data (Left Program pane) to File. An existing File will be
+    overwritten. If the Folder does not exist, it will be created
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:SaveKernelDataAs C:/Temp/RCConfigSample1.xml
+    """
+    MessageServerInterface.sendSciCommand("SaveKernelDataAs",FileName)
+
+
+def LoadConfigFile(FileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Loads File Data to KernelSetup (Right Program pane).
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:LoadConfigFile C:/Temp/RCConfigSample1.xml
+    """
+    MessageServerInterface.sendSciCommand("LoadConfigFile",FileName)
+
+
+def ReplaceKernelDataByFileData(SilentMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Replaces Kernel Data (Left pane) by File Data (Right pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReplaceKernelDataByFileData 0
+    """
+    MessageServerInterface.sendSciCommand("ReplaceKernelDataByFileData",SilentMode)
+
+
+def ReplaceFileTreeByKernelData(SilentMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Replaces File Tree (Right pane) by Kernel Data (Left pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReplaceFileTreeByKernelData 0
+    """
+    MessageServerInterface.sendSciCommand("ReplaceFileTreeByKernelData",SilentMode)
+
+
+def SaveFileTreeAs(FileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves File Tree (Right pane) to File. An existing File will be overwritten. If
+    the Folder does not exist, it will be created.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:SaveFileTreeAs C:/Temp/RCConfigSample2.xml
+    """
+    MessageServerInterface.sendSciCommand("SaveFileTreeAs",FileName)
+
+
+def HeatChuck(Temperature="", Unit="", ReduceContact=""):
+    """
+    Sets a new target temperature and starts the heating or cooling of the chuck. An
+    answer to the command will be returned after reaching the given temperature and
+    waiting the soak time or an unexpected interrupt of the process. Given back is
+    the already reached temperature.
+    API Status: published
+    Args:
+        Temperature:Decimal = 25
+        Unit:str = "Celsius"
+        ReduceContact:int = 1
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 36000000
+    Example:HeatChuck 61.3 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("HeatChuck",Temperature,Unit,ReduceContact)
+    global HeatChuck_Response
+    if not "HeatChuck_Response" in globals(): HeatChuck_Response = namedtuple("HeatChuck_Response", "RespTemperature,RespUnit")
+    return HeatChuck_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetHeaterTemp(Temperature="", Unit="", UseContactSafety=""):
+    """
+    Sets a new target temperature and starts the heating or cooling of the
+    temperature chuck. The new target temperature is returned immediately as the
+    command does not wait until heating is complete.
+    API Status: published
+    Args:
+        Temperature:Decimal = 25
+        Unit:str = "Celsius"
+        UseContactSafety:int = 1
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:SetHeaterTemp 55.5 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetHeaterTemp",Temperature,Unit,UseContactSafety)
+    global SetHeaterTemp_Response
+    if not "SetHeaterTemp_Response" in globals(): SetHeaterTemp_Response = namedtuple("SetHeaterTemp_Response", "RespTemperature,RespUnit")
+    return SetHeaterTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetHeaterTemp(Unit="", ExternalHeaterID=""):
+    """
+    Reads the current temperature of the chuck and determines the status of the
+    thermal system.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+        ExternalHeaterID:int = 0
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+        Status:str
+    Command Timeout: 60000
+    Example:GetHeaterTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHeaterTemp",Unit,ExternalHeaterID)
+    global GetHeaterTemp_Response
+    if not "GetHeaterTemp_Response" in globals(): GetHeaterTemp_Response = namedtuple("GetHeaterTemp_Response", "RespTemperature,RespUnit,Status")
+    return GetHeaterTemp_Response(Decimal(rsp[0]),str(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def EnableHeaterHoldMode(HoldMode=""):
+    """
+    Switches the Temperature Chuck devices hold mode on or off. In hold mode the
+    chuck is heated with a constant current to avoid noise from the temperature
+    control. The hold mode can be enabled only in HoldReady state.
+    API Status: published
+    Args:
+        HoldMode:int = 1
+    Returns:
+        RespHoldMode:int
+    Command Timeout: 60000
+    Example:EnableHeaterHoldMode 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("EnableHeaterHoldMode",HoldMode)
+    return int(rsp[0])
+
+def StopHeatChuck():
+    """
+    Stops a pending heating or cooling process. If the device is not at temperature,
+    the actual temperature is set as target temperature.
+    API Status: published
+    Command Timeout: 60000
+    Example:StopHeatChuck
+    """
+    MessageServerInterface.sendSciCommand("StopHeatChuck")
+
+
+def GetDewPointTemp(Unit=""):
+    """
+    Returns the current dew point temperature, if a dew point sensor is connected.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:GetDewPointTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDewPointTemp",Unit)
+    global GetDewPointTemp_Response
+    if not "GetDewPointTemp_Response" in globals(): GetDewPointTemp_Response = namedtuple("GetDewPointTemp_Response", "RespTemperature,RespUnit")
+    return GetDewPointTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetTemperatureChuckOptions():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the currently set temperature chuck options.
+    API Status: internal
+    Returns:
+        UseSoakTime:int
+        SyncTemp:int
+        CurrConnection:int
+        MinTemperature:Decimal
+        MaxTemperature:Decimal
+        UsePurge:int
+        UseDynamicSoakTime:int
+        UseFixedDieSoakTime:int
+        UseDynamicDieSoakTime:int
+        UseEcoMode:int
+        PurgeOnChamberDoor:int
+        ForceBypassPurge:int
+        DoorClosedTime:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTemperatureChuckOptions")
+    global GetTemperatureChuckOptions_Response
+    if not "GetTemperatureChuckOptions_Response" in globals(): GetTemperatureChuckOptions_Response = namedtuple("GetTemperatureChuckOptions_Response", "UseSoakTime,SyncTemp,CurrConnection,MinTemperature,MaxTemperature,UsePurge,UseDynamicSoakTime,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime")
+    return GetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]))
+
+def SetTemperatureChuckOptions(UseFixedWaferSoak="", SyncTemp="", CurrConnection="", UsePurge="", UseDynamicWaferSoak="", UseFixedDieSoakTime="", UseDynamicDieSoakTime="", UseEcoMode="", PurgeOnChamberDoor="", ForceBypassPurge="", DoorClosedTime=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is used to change the currently set temperature chuck options.
+    API Status: internal
+    Args:
+        UseFixedWaferSoak:int = -1
+        SyncTemp:int = -1
+        CurrConnection:int = -1
+        UsePurge:int = -1
+        UseDynamicWaferSoak:int = -1
+        UseFixedDieSoakTime:int = -1
+        UseDynamicDieSoakTime:int = -1
+        UseEcoMode:int = -1
+        PurgeOnChamberDoor:int = -1
+        ForceBypassPurge:int = -1
+        DoorClosedTime:int = -1
+    Returns:
+        UseFixedWaferSoakRsp:int
+        SyncTempRsp:int
+        CurrConnectionRsp:int
+        UsePurgeRsp:int
+        UseDynamicWaferSoakRsp:int
+        UseFixedDieSoakTimeRsp:int
+        UseDynamicDieSoakTimeRsp:int
+        UseEcoModeRsp:int
+        PurgeOnChamberDoorRsp:int
+        ForceBypassPurgeRsp:int
+        DoorClosedTimeRsp:int
+    Command Timeout: 300000
+    Example:SetTemperatureChuckOptions 1 0 1 1 1 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetTemperatureChuckOptions",UseFixedWaferSoak,SyncTemp,CurrConnection,UsePurge,UseDynamicWaferSoak,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime)
+    global SetTemperatureChuckOptions_Response
+    if not "SetTemperatureChuckOptions_Response" in globals(): SetTemperatureChuckOptions_Response = namedtuple("SetTemperatureChuckOptions_Response", "UseFixedWaferSoakRsp,SyncTempRsp,CurrConnectionRsp,UsePurgeRsp,UseDynamicWaferSoakRsp,UseFixedDieSoakTimeRsp,UseDynamicDieSoakTimeRsp,UseEcoModeRsp,PurgeOnChamberDoorRsp,ForceBypassPurgeRsp,DoorClosedTimeRsp")
+    return SetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]))
+
+def GetHeaterSoak():
+    """
+    Returns the current soak time values in seconds and the soaking status.
+    API Status: published
+    Returns:
+        FixedWaferSoakTime:int
+        FixedWaferSoakStatus:int
+        DynamicWaferSoakTime:Decimal
+        DynamicWaferSoakStatus:int
+        FixedDieSoakTime:Decimal
+        DynamicDieSoakTime:Decimal
+        FixedDieSoakStatus:int
+        DynamicDieSoakStatus:int
+    Command Timeout: 60000
+    Example:GetHeaterSoak
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHeaterSoak")
+    global GetHeaterSoak_Response
+    if not "GetHeaterSoak_Response" in globals(): GetHeaterSoak_Response = namedtuple("GetHeaterSoak_Response", "FixedWaferSoakTime,FixedWaferSoakStatus,DynamicWaferSoakTime,DynamicWaferSoakStatus,FixedDieSoakTime,DynamicDieSoakTime,FixedDieSoakStatus,DynamicDieSoakStatus")
+    return GetHeaterSoak_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),int(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def SetHeaterSoak(FixedWaferSoakTime="", DynamicWaferSoakTime="", FixedDieSoakTime="", DynamicDieSoakTime=""):
+    """
+    Sets the new soak time values. The unit of the values is seconds. If soak time
+    is actually running, it may be affected by the change.
+    API Status: published
+    Args:
+        FixedWaferSoakTime:int = 60
+        DynamicWaferSoakTime:Decimal = -1
+        FixedDieSoakTime:Decimal = -1
+        DynamicDieSoakTime:Decimal = -1
+    Command Timeout: 60000
+    Example:SetHeaterSoak 60
+    """
+    MessageServerInterface.sendSciCommand("SetHeaterSoak",FixedWaferSoakTime,DynamicWaferSoakTime,FixedDieSoakTime,DynamicDieSoakTime)
+
+
+def EnableHeaterStandby(Standby=""):
+    """
+    Switches the power save (standby) mode of the device on or off. If the device is
+    in power save mode, setting and reading temperatures switches off the power save
+    mode automatically.
+    API Status: published
+    Args:
+        Standby:int = 1
+    Returns:
+        RespStandby:int
+    Command Timeout: 60000
+    Example:EnableHeaterStandby 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("EnableHeaterStandby",Standby)
+    return int(rsp[0])
+
+def ReadTemperatureChuckStatus():
+    """
+    Returns values of the temperature chuck status. The status byte gives
+    information about the current controller's action. The dew point sensor status
+    encapsulates information, if such a sensor is connected, and if the actual dew
+    point difference temperature is readable (active). It can be used for purge
+    control. Soak time left (in seconds) is used when soak time is actually running.
+    API Status: published
+    Returns:
+        Status:str
+        DPSensor:int
+        SoakTimeLeft:int
+        HasEcoMode:int
+    Command Timeout: 60000
+    Example:ReadTemperatureChuckStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTemperatureChuckStatus")
+    global ReadTemperatureChuckStatus_Response
+    if not "ReadTemperatureChuckStatus_Response" in globals(): ReadTemperatureChuckStatus_Response = namedtuple("ReadTemperatureChuckStatus_Response", "Status,DPSensor,SoakTimeLeft,HasEcoMode")
+    return ReadTemperatureChuckStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetTargetTemp(Unit=""):
+    """
+    Reads the target temperature of the chuck.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:GetTargetTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTargetTemp",Unit)
+    global GetTargetTemp_Response
+    if not "GetTargetTemp_Response" in globals(): GetTargetTemp_Response = namedtuple("GetTargetTemp_Response", "RespTemperature,RespUnit")
+    return GetTargetTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetThermoWindow(Window=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command sets the window for the target temperture which is the window in which a
+    station is assumed to be at temp. Only supported on Nucleus stations.
+    API Status: internal
+    Args:
+        Window:Decimal = 1
+    Returns:
+        RespWindow:Decimal
+    Command Timeout: 60000
+    Example:SetThermoWindow 2.0
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetThermoWindow",Window)
+    return Decimal(rsp[0])
+
+def GetThermoWindow():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command returns the current thermo window which is the window in which a station
+    is assumed to be at temp. Only supported on Nucleus stations.
+    API Status: internal
+    Returns:
+        RespWindow:Decimal
+    Command Timeout: 60000
+    Example:GetThermoWindow
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetThermoWindow")
+    return Decimal(rsp[0])
+
+def SendThermoCommand(Command=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends a command string to the thermal chuck using the thermal chuck protocol and
+    returns the thermal chucks response as command response. This command can be
+    used to access thermal chuck features that are not exposed as standalone SCI
+    commands. Command is currently implemented for ERS and ATT chucks.
+    API Status: internal
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 5000
+    Example:SendThermoCommand RH
+    """
+    rsp = MessageServerInterface.sendSciCommand("SendThermoCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadAuxStatus(AuxID=""):
+    """
+    Returns the status of a single AUX site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        FlagsMode:int
+        Comp:str
+        PresetHeight:str
+        AuxSiteType:str
+    Command Timeout: 10000
+    Example:ReadAuxStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxStatus",AuxID)
+    global ReadAuxStatus_Response
+    if not "ReadAuxStatus_Response" in globals(): ReadAuxStatus_Response = namedtuple("ReadAuxStatus_Response", "AuxIDEcho,FlagsMode,Comp,PresetHeight,AuxSiteType")
+    return ReadAuxStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ReadAuxPosition(AuxID="", Unit="", PosRef="", Comp=""):
+    """
+    Returns the actual AUX sites position in X, Y and Z. With AUX ID set to 0, the
+    position is read for the chuck stage. If no AUX ID is given, it tries to read
+    the position from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        AuxIDEcho:int
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxPosition 1 Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxPosition",AuxID,Unit,PosRef,Comp)
+    global ReadAuxPosition_Response
+    if not "ReadAuxPosition_Response" in globals(): ReadAuxPosition_Response = namedtuple("ReadAuxPosition_Response", "AuxIDEcho,X,Y,Z")
+    return ReadAuxPosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadAuxHeights(AuxID="", Unit=""):
+    """
+    Returns the actual technology heights from an AUX site. If AUX ID is set to 0,
+    all response values are read from chuck stage. If no AUX ID is given, it tries
+    to read the heights from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxHeights 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxHeights",AuxID,Unit)
+    global ReadAuxHeights_Response
+    if not "ReadAuxHeights_Response" in globals(): ReadAuxHeights_Response = namedtuple("ReadAuxHeights_Response", "AuxIDEcho,Contact,Overtravel,AlignDist,SepDist")
+    return ReadAuxHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetAuxMode(AuxID="", Overtravel=""):
+    """
+    Modes manage the way a stage behaves when it is in contact height. AUX site mode
+    holds only a single flag. Flags can be turned on by using the value 1 or turned
+    off by using the value 0. If you do not want to change the flag - use the value
+    of 2. If AUX ID is set to 0, all flags are set for chuck stage. AUX site will
+    move an additional overtravel on every contact move.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Overtravel:int = 2
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxMode 1 2
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxMode",AuxID,Overtravel)
+    return int(rsp[0])
+
+def SetAuxHome(AuxID="", Mode="", Unit="", XValue="", YValue=""):
+    """
+    Sets the AUX sites Home position in X and Y. It defines the origin of the AUX
+    sites coordinate system for later movements. Usually this position is identical
+    to the die home position.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxHome 1 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxHome",AuxID,Mode,Unit,XValue,YValue)
+    return int(rsp[0])
+
+def SetAuxIndex(AuxID="", XValue="", YValue="", Unit=""):
+    """
+    Sets the AUX sites index size. If AUX ID is set to 0, index size is set for
+    chuck stage.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxIndex 1 1000. 1000. Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxIndex",AuxID,XValue,YValue,Unit)
+    return int(rsp[0])
+
+def SetAuxHeight(AuxID="", PresetHeight="", Mode="", Unit="", Value=""):
+    """
+    Sets the AUX sites contact height and corresponding gaps for overtravel,
+    alignment and separation height. A contact height search gap for contact search
+    with edge sensor can also be set. This search gap is always identical for all
+    AUX sites. Without any optional parameters the command sets contact height to
+    the current position.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxHeight 1 C 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxHeight",AuxID,PresetHeight,Mode,Unit,Value)
+    return int(rsp[0])
+
+def ReadAuxIndex(AuxID="", Unit=""):
+    """
+    Returns the actual AUX sites index values. If AUX ID is set to 0, the index size
+    is read from chuck stage. If no AUX ID is given, it tries to read the index from
+    the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxIndex 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxIndex",AuxID,Unit)
+    global ReadAuxIndex_Response
+    if not "ReadAuxIndex_Response" in globals(): ReadAuxIndex_Response = namedtuple("ReadAuxIndex_Response", "AuxIDEcho,IndexX,IndexY")
+    return ReadAuxIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetAuxThetaHome(AuxID="", Mode="", Unit="", Position=""):
+    """
+    Sets the AUX sites theta home position. It defines the origin of the AUX sites
+    theta coordinate system for later movements. If AUX ID is set to 0, theta home
+    position is set for chuck stage.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Position:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxThetaHome 1 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxThetaHome",AuxID,Mode,Unit,Position)
+    return int(rsp[0])
+
+def EnableOffset(Stage="", Enable="", Move=""):
+    """
+    Enables or disables the Offset XY compensation for the selected stage. If the
+    compensation holds an offset different from zero, the chuck is automatically
+    moved the distance of the offset. The chuck also moves automatically to a safe
+    height. The move can be disabled by the third parameter. This may put the stage
+    outside the software fence.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        Enable:int = 1
+        Move:int = 1
+    Command Timeout: 60000
+    Example:EnableOffset C 1
+    """
+    MessageServerInterface.sendSciCommand("EnableOffset",Stage,Enable,Move)
+
+
+def SetOffset(Stage="", OffsetX="", OffsetY=""):
+    """
+    Sets the offset values for the Offset XY compensation for the selected stage.
+    The changes take effect immediately. Note that the Offset XY compensation must
+    be enabled for the values to take effect. The compensation is enabled or
+    disabled using EnableOffset command.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        OffsetX:Decimal = 0
+        OffsetY:Decimal = 0
+    Command Timeout: 5000
+    Example:SetOffset C 100000.0 0.0
+    """
+    MessageServerInterface.sendSciCommand("SetOffset",Stage,OffsetX,OffsetY)
+
+
+def GetOffsetInfo(Stage=""):
+    """
+    Gets information about the Offset XY compensation of the selected stage,
+    including the stored offset values and whether the compensation is enabled or
+    disabled.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        Enable:int
+        OffsetX:Decimal
+        OffsetY:Decimal
+    Command Timeout: 5000
+    Example:GetOffsetInfo C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetOffsetInfo",Stage)
+    global GetOffsetInfo_Response
+    if not "GetOffsetInfo_Response" in globals(): GetOffsetInfo_Response = namedtuple("GetOffsetInfo_Response", "Enable,OffsetX,OffsetY")
+    return GetOffsetInfo_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetSwitchPosition(Stage="", AuxSite="", X="", Y=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the switch position of a stage. This is the position to move to if an aux
+    site gets active. This is only supported for the chuck and it's aux sites. Aux
+    index 0 means wafer site, 1 means aux site 1 and so on.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxSite:int = 0
+        X:Decimal = 0
+        Y:Decimal = 0
+    Command Timeout: 5000
+    Example:SetSwitchPosition C 0 5000 5000
+    """
+    MessageServerInterface.sendSciCommand("SetSwitchPosition",Stage,AuxSite,X,Y)
+
+
+def MoveAuxSite(AuxID=""):
+    """
+    Moves the chuck to the position of a given AUX site. A safe height is used for
+    the move. If AUX ID is set to 0, the target of the move is the wafer site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 60000
+    Example:MoveAuxSite 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAuxSite",AuxID)
+    return int(rsp[0])
+
+def SetAuxSiteCount(AuxSiteCount=""):
+    """
+    Sets the number of available AUX sites. For preparing for example two cal
+    chucks, the count must be set to 2. For the changes to take effect the system
+    needs to be restarted.
+    API Status: published
+    Args:
+        AuxSiteCount:int = 0
+    Command Timeout: 10000
+    Example:SetAuxSiteCount 2
+    """
+    MessageServerInterface.sendSciCommand("SetAuxSiteCount",AuxSiteCount)
+
+
+def GetAuxSiteCount():
+    """
+    Reads the number of available AUX sites and the ID of the actual active AUX
+    site. If this is 0, the chuck stage is currently active.
+    API Status: published
+    Returns:
+        AuxSiteCount:int
+        ActualAuxSite:int
+    Command Timeout: 10000
+    Example:GetAuxSiteCount
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAuxSiteCount")
+    global GetAuxSiteCount_Response
+    if not "GetAuxSiteCount_Response" in globals(): GetAuxSiteCount_Response = namedtuple("GetAuxSiteCount_Response", "AuxSiteCount,ActualAuxSite")
+    return GetAuxSiteCount_Response(int(rsp[0]),int(rsp[1]))
+
+def SetAuxSiteName(AuxID="", AuxSiteName=""):
+    """
+    Sets the description of an AUX site. With AUX ID zero, the description of the
+    wafer site can be set.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        AuxSiteName:str = ""
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxSiteName 1 Aux site 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxSiteName",AuxID,AuxSiteName)
+    return int(rsp[0])
+
+def GetAuxSiteName(AuxID=""):
+    """
+    This command reads the description of an AUX site. If AUX ID is set to 0, the
+    description of the chuck stage is given back. If no AUX ID is given, it tries to
+    read from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        AuxSiteName:str
+    Command Timeout: 10000
+    Example:GetAuxSiteName 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAuxSiteName",AuxID)
+    global GetAuxSiteName_Response
+    if not "GetAuxSiteName_Response" in globals(): GetAuxSiteName_Response = namedtuple("GetAuxSiteName_Response", "AuxIDEcho,AuxSiteName")
+    return GetAuxSiteName_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def CleanProbeTip(AuxID=""):
+    """
+    Starts a probe tip cleaning on the given AUX site. The cleaning algorithm is
+    dependent from the type of the AUX site and from the duration and the cleaning
+    count that is set in configuration. The cleaning algorithm includes both a move
+    to the pad site and a move back to the source site.
+    API Status: published
+    Args:
+        AuxID:str = "-1"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 300000
+    Example:CleanProbeTip 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("CleanProbeTip",AuxID)
+    return int(rsp[0])
+
+def SetAuxSiteType(AuxID="", AuxSiteType=""):
+    """
+    Sets the type for a given AUX site. It depends on the type of the AUX site, if
+    there is a cleaning algorithm available. It is not possible to set the type of
+    the wafer site (AUX site 0).
+    API Status: published
+    Args:
+        AuxID:int = -1
+        AuxSiteType:str = "AuxUnknown"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxSiteType 1 G
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxSiteType",AuxID,AuxSiteType)
+    return int(rsp[0])
+
+def SetCleaningParams(AuxID="", Count="", Time=""):
+    """
+    Sets the cleaning parameters for a given AUX site. It is not possible to set the
+    cleaning parameters of the wafer site (AUX site 0). If no AUX ID is given, it
+    tries to set the parameters of the active site.     The cleaning count defines,
+    how much times the cleaning is performed repeatedly. The cleaning time defines,
+    how much     milliseconds the needles wait in cleaning position during each
+    cleaning cycle.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Count:int = 1
+        Time:int = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetCleaningParams 1 5 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetCleaningParams",AuxID,Count,Time)
+    return int(rsp[0])
+
+def GetCleaningParams(AuxID=""):
+    """
+    Reads the cleaning parameters of a given AUX site. It is not possible to read
+    cleaning parameters of the wafer site (AUX site 0).
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        Count:int
+        Time:int
+        Remaining:int
+    Command Timeout: 30000
+    Example:GetCleaningParams
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCleaningParams",AuxID)
+    global GetCleaningParams_Response
+    if not "GetCleaningParams_Response" in globals(): GetCleaningParams_Response = namedtuple("GetCleaningParams_Response", "AuxIDEcho,Count,Time,Remaining")
+    return GetCleaningParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def UpdateAuxSitePositions(AuxID="", XOffset="", YOffset=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Rotate the switch, home, and fence positions to match the current chuck theta
+    angle and adjust Home/Switch by XY offset. Should only be used for Aux sites
+    that don't move theta.
+    API Status: internal
+    Args:
+        AuxID:int = -1
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 5000
+    Example:UpdateAuxSitePositions 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("UpdateAuxSitePositions",AuxID,XOffset,YOffset)
+    return int(rsp[0])
+
+def ResetCleaningPosition(AuxID="", OffsetX="", OffsetY=""):
+    """
+    Resets the cleaning position to the beginning of the cleaning aux site (home).
+    API Status: published
+    Args:
+        AuxID:str = "-1"
+        OffsetX:Decimal = 0
+        OffsetY:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:ResetCleaningPosition 5
+    """
+    rsp = MessageServerInterface.sendSciCommand("ResetCleaningPosition",AuxID,OffsetX,OffsetY)
+    return int(rsp[0])
+
+def BnR_EchoData(ControllerID="", TestCmd=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Test Command for the Kernel Communication. It is like a ping command. The given
+    text string is returned unchanged.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        TestCmd:str = "Test"
+    Returns:
+        TestRsp:str
+    Command Timeout: 5000
+    Example:BnR_EchoData 1 Hello World
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_EchoData",ControllerID,TestCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_ReportKernelVersion(ControllerID="", Module=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual version information of the controller software.
+    The 'Version' value contains version number and revision level of the actual
+    implementation.                                    The text string contains a
+    code description, version number and the revision date.
+    The 'Module' byte is optional (default is K).
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Module:str = "K"
+    Returns:
+        Version:Decimal
+        Description:str
+    Command Timeout: 5000
+    Example:BnR_ReportKernelVersion 1 K
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReportKernelVersion",ControllerID,Module)
+    global BnR_ReportKernelVersion_Response
+    if not "BnR_ReportKernelVersion_Response" in globals(): BnR_ReportKernelVersion_Response = namedtuple("BnR_ReportKernelVersion_Response", "Version,Description")
+    return BnR_ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetStationType(ControllerID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns information about the connected station.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        StationType:str
+        Type:str
+    Command Timeout: 5000
+    Example:BnR_GetStationType 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetStationType",ControllerID)
+    global BnR_GetStationType_Response
+    if not "BnR_GetStationType_Response" in globals(): BnR_GetStationType_Response = namedtuple("BnR_GetStationType_Response", "StationType,Type")
+    return BnR_GetStationType_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_ResetController(ControllerID="", Mode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Restarts the BnR controller.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Mode:str = "X"
+    Command Timeout: 10000
+    Example:BnR_ResetController 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_ResetController",ControllerID,Mode)
+
+
+def BnR_SetOutput(ControllerID="", Channel="", State="", CycleTime=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Controls the Velox output channel signals. It can be used to activate/deactivate
+    outputs.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DO_WaferVacuum"
+        State:int = 0
+        CycleTime:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetOutput 1 1000 1 2000
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetOutput",ControllerID,Channel,State,CycleTime)
+
+
+def BnR_GetOutput(ControllerID="", Channel=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the state of an output channel. By using the string identifier DO_ALL, a
+    string list of all outputs is returned in addition
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DO_WaferVacuum"
+    Returns:
+        State:int
+        AllOutputs:str
+    Command Timeout: 5000
+    Example:BnR_GetOutput 1 DO_WaferVacuum
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetOutput",ControllerID,Channel)
+    global BnR_GetOutput_Response
+    if not "BnR_GetOutput_Response" in globals(): BnR_GetOutput_Response = namedtuple("BnR_GetOutput_Response", "State,AllOutputs")
+    return BnR_GetOutput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetInput(ControllerID="", Channel=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the state of an input channel. By using the string identifier DI_ALL, a
+    string list of all outputs is returned in addition
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DI_MotorPower"
+    Returns:
+        State:int
+        AllInputs:str
+    Command Timeout: 5000
+    Example:BnR_GetInput 1 DI_MotorPower
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetInput",ControllerID,Channel)
+    global BnR_GetInput_Response
+    if not "BnR_GetInput_Response" in globals(): BnR_GetInput_Response = namedtuple("BnR_GetInput_Response", "State,AllInputs")
+    return BnR_GetInput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_SetAnalogOutput(ControllerID="", Channel="", OutputPercent=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets an analog output channel to a given value.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "AO_PurgeDewPoint"
+        OutputPercent:Decimal = 50
+    Command Timeout: 5000
+    Example:BnR_SetAnalogOutput 1 AO_PurgeDewPoint 50
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetAnalogOutput",ControllerID,Channel,OutputPercent)
+
+
+def BnR_GetAnalogIO(ControllerID="", Channel=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current value of an analog output or input.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "AO_PurgeDewPoint"
+    Returns:
+        Value:Decimal
+        UnderOverflow:int
+    Command Timeout: 5000
+    Example:BnR_GetAnalogIO 1 AO_PurgeDewPoint
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAnalogIO",ControllerID,Channel)
+    global BnR_GetAnalogIO_Response
+    if not "BnR_GetAnalogIO_Response" in globals(): BnR_GetAnalogIO_Response = namedtuple("BnR_GetAnalogIO_Response", "Value,UnderOverflow")
+    return BnR_GetAnalogIO_Response(Decimal(rsp[0]),int(rsp[1]))
+
+def BnR_GetStartupStatus(ControllerID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the startup status of the BnR controller to determine if the controller
+    is properly booted or still starting.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        StartupStatus:str
+        AdditionalStatusInfo:str
+    Command Timeout: 5000
+    Example:BnR_GetStartupStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetStartupStatus",ControllerID)
+    global BnR_GetStartupStatus_Response
+    if not "BnR_GetStartupStatus_Response" in globals(): BnR_GetStartupStatus_Response = namedtuple("BnR_GetStartupStatus_Response", "StartupStatus,AdditionalStatusInfo")
+    return BnR_GetStartupStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_CreateSdmSystemDump(ControllerID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Creates a Sdm System Dump file on the B&R flash
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Command Timeout: 60000
+    Example:BnR_CreateSdmSystemDump
+    """
+    MessageServerInterface.sendSciCommand("BnR_CreateSdmSystemDump",ControllerID)
+
+
+def BnR_GetControllerData(ControllerID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets controller data from the B&R controller. Currently used for init
+    information.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Command Timeout: 10000
+    Example:BnR_GetControllerData 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_GetControllerData",ControllerID)
+
+
+def BnR_WriteMessage(ControllerID="", MessageType="", Message=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to write a (native) message to Controller
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        MessageType:str = "mtCryoLoader"
+        Message:str = ""
+    Command Timeout: 5000
+    Example:BnR_WriteMessage 1 mtCryoLoader SampleMessage
+    """
+    MessageServerInterface.sendSciCommand("BnR_WriteMessage",ControllerID,MessageType,Message)
+
+
+def BnR_ReadMessage(ControllerID="", MessageType=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to read a (native) message from Controller
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        MessageType:str = "mtCryoLoader"
+    Returns:
+        Message:str
+    Command Timeout: 5000
+    Example:BnR_ReadMessage 1 mtCryoLoader
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReadMessage",ControllerID,MessageType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetDataIterator(ControllerID="", ShowAll=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a data stream handle which represents a data stream of setup parameters
+    and requires the BnR_GetNextDatum command.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        ShowAll:int = 0
+    Returns:
+        IdentityToken:int
+        SizeNoAll:int
+    Command Timeout: 5000
+    Example:BnR_GetDataIterator 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetDataIterator",ControllerID,ShowAll)
+    global BnR_GetDataIterator_Response
+    if not "BnR_GetDataIterator_Response" in globals(): BnR_GetDataIterator_Response = namedtuple("BnR_GetDataIterator_Response", "IdentityToken,SizeNoAll")
+    return BnR_GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def BnR_GetNextDatum(ControllerID="", IdentityToken=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the next parameter from the data stream. Fields are separated by a
+    colon. Structure of the response parameter Value:
+    Path_Path:Name:Description:Value
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        IdentityToken:int = 0
+    Returns:
+        IsLastDatum:int
+        DatumCode:int
+        PathNameDescrValue:str
+    Command Timeout: 10000
+    Example:BnR_GetNextDatum 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetNextDatum",ControllerID,IdentityToken)
+    global BnR_GetNextDatum_Response
+    if not "BnR_GetNextDatum_Response" in globals(): BnR_GetNextDatum_Response = namedtuple("BnR_GetNextDatum_Response", "IsLastDatum,DatumCode,PathNameDescrValue")
+    return BnR_GetNextDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def BnR_SetDatum(ControllerID="", PathNameAndValue=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        PathNameAndValue:str = ""
+    Command Timeout: 20000
+    Example:BnR_SetDatum 1 Chuck_XAxisData:CurrentMaximal:70
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetDatum",ControllerID,PathNameAndValue)
+
+
+def BnR_GetDatum(ControllerID="", PathName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a value string. The Value string consists of the value and the
+    description. The Locator only consists of the path and the name. All fields are
+    separated by a colon.  Structure of the command parameter Locator:
+    Path_Path:Name Structure of the response parameter Value: Value:Description
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        PathName:str = ""
+    Returns:
+        DatumCode:int
+        ValueDesc:str
+    Command Timeout: 5000
+    Example:BnR_GetDatum 1 Chuck_XAxisData:CurrentMaximal
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetDatum",ControllerID,PathName)
+    global BnR_GetDatum_Response
+    if not "BnR_GetDatum_Response" in globals(): BnR_GetDatum_Response = namedtuple("BnR_GetDatum_Response", "DatumCode,ValueDesc")
+    return BnR_GetDatum_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_DoInternalTask(ControllerID="", Task="", PCmdInt1="", PCmdInt2=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes an internal BnR Task
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Task:str = ""
+        PCmdInt1:int = 0
+        PCmdInt2:int = 0
+    Returns:
+        RspInt:int
+        RspString:str
+    Command Timeout: 10000
+    Example:BnR_DoInternalTask 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_DoInternalTask",ControllerID,Task,PCmdInt1,PCmdInt2)
+    global BnR_DoInternalTask_Response
+    if not "BnR_DoInternalTask_Response" in globals(): BnR_DoInternalTask_Response = namedtuple("BnR_DoInternalTask_Response", "RspInt,RspString")
+    return BnR_DoInternalTask_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetPosition(Stage="", Unit=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current positions for the X,Y,Z (or T) axis for the specified stage
+    as well as the commanded positions.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Unit:str = "Microns"
+    Returns:
+        XorT:Decimal
+        Y:Decimal
+        Z:Decimal
+        CommandedXorT:Decimal
+        CommandedY:Decimal
+        CommandedZ:Decimal
+    Command Timeout: 5000
+    Example:BnR_GetPosition 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetPosition",Stage,Unit)
+    global BnR_GetPosition_Response
+    if not "BnR_GetPosition_Response" in globals(): BnR_GetPosition_Response = namedtuple("BnR_GetPosition_Response", "XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ")
+    return BnR_GetPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def BnR_Move(Stage="", XValue="", YValue="", VelX="", VelY="", WaitFinished=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command executes a XY movement for a specified stage. This can be either a
+    blocking or non blocking move.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        VelX:Decimal = 0
+        VelY:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 60000
+    Example:BnR_Move 1 C 5000 5000 Z 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_Move",Stage,XValue,YValue,VelX,VelY,WaitFinished)
+    global BnR_Move_Response
+    if not "BnR_Move_Response" in globals(): BnR_Move_Response = namedtuple("BnR_Move_Response", "X,Y")
+    return BnR_Move_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def BnR_MoveZ(Stage="", ZValue="", Vel="", Dec="", WaitFinished=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the stage Z axis to a new position.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZValue:Decimal = 0
+        Vel:Decimal = 0
+        Dec:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        Z:Decimal
+    Command Timeout: 600000
+    Example:BnR_MoveZ 1 C 12000 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveZ",Stage,ZValue,Vel,Dec,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_ScanMoveZ(ControllerID="", Stage="", ZDistance="", TriggerEveryNthCycle="", Vel=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command executes a scan movement of the Z axis that sets a digital output
+    every couple microns to trigger e.g. a camera. After the move is finished, the
+    command returns a list of Z heights at which the digital output was set.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Stage:str = "Chuck"
+        ZDistance:Decimal = 1000
+        TriggerEveryNthCycle:int = 2
+        Vel:Decimal = 10
+    Command Timeout: 300000
+    Example:BnR_ScanMoveZ 1 C 1000 6 10
+    """
+    MessageServerInterface.sendSciCommand("BnR_ScanMoveZ",ControllerID,Stage,ZDistance,TriggerEveryNthCycle,Vel)
+
+
+def BnR_MoveT(TValue="", Vel="", WaitFinished=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes a movement of the theta axis, either blocking or non blocking
+    API Status: internal
+    Args:
+        TValue:Decimal = 0
+        Vel:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        T:Decimal
+    Command Timeout: 60000
+    Example:BnR_MoveT 1 1.003 10 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveT",TValue,Vel,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_StopAxis(Stage="", FlagsStop=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops 1... all axes of a stage
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        FlagsStop:int = 15
+    Command Timeout: 5000
+    Example:BnR_StopAxis 1 C 7
+    """
+    MessageServerInterface.sendSciCommand("BnR_StopAxis",Stage,FlagsStop)
+
+
+def BnR_InitAxis(Stage="", FlagsInit="", FlagsDirection="", FlagsInitInPlace="", LowLimitX="", LowLimitY="", LowLimitZ="", LowLimitTh="", InitInPlaceMoveRangeX="", InitInPlaceMoveRangeY="", InitInPlaceMoveRangeZ="", InitInPlaceMoveRangeTh=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Machine Coordinate System: X Y Z Theta  - _FlagsInit_: X, Y, Z, Theta -
+    _FlagsDirection_: X, Y, Z, Theta (true means plus direction) -
+    _FlagsInitInPlace_: X, Y, Z, Theta   All flags can be accessed by indirect
+    members. Initializes the stage and resets current coordinate system. Should be
+    used only in cases when the reported coordinates do not correspond to real
+    position of mechanics. Init in Place performs the initialization without any
+    movements.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsInitInPlace:int = 0
+        LowLimitX:Decimal = 0
+        LowLimitY:Decimal = 0
+        LowLimitZ:Decimal = 0
+        LowLimitTh:Decimal = 0
+        InitInPlaceMoveRangeX:Decimal = 0
+        InitInPlaceMoveRangeY:Decimal = 0
+        InitInPlaceMoveRangeZ:Decimal = 0
+        InitInPlaceMoveRangeTh:Decimal = 0
+    Command Timeout: 300000
+    Example:BnR_InitAxis 1 C 7
+    """
+    MessageServerInterface.sendSciCommand("BnR_InitAxis",Stage,FlagsInit,FlagsDirection,FlagsInitInPlace,LowLimitX,LowLimitY,LowLimitZ,LowLimitTh,InitInPlaceMoveRangeX,InitInPlaceMoveRangeY,InitInPlaceMoveRangeZ,InitInPlaceMoveRangeTh)
+
+
+def BnR_GetAxisState(Stage="", Axis=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns the state of an axis (disabled/standstill/errorstop/stoppin
+    g/homing/continuousmotion/discretemotion/synchronizedmotion)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        State:str
+        AdditionalStateInfo:str
+    Command Timeout: 5000
+    Example:BnR_GetAxisState 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisState",Stage,Axis)
+    global BnR_GetAxisState_Response
+    if not "BnR_GetAxisState_Response" in globals(): BnR_GetAxisState_Response = namedtuple("BnR_GetAxisState_Response", "State,AdditionalStateInfo")
+    return BnR_GetAxisState_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetAxisStatus(Stage="", Axis=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns some axis status information
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        Initialized:int
+        PositiveEndlimit:int
+        NegativeEndlimit:int
+    Command Timeout: 5000
+    Example:BnR_GetAxisStatus 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisStatus",Stage,Axis)
+    global BnR_GetAxisStatus_Response
+    if not "BnR_GetAxisStatus_Response" in globals(): BnR_GetAxisStatus_Response = namedtuple("BnR_GetAxisStatus_Response", "Initialized,PositiveEndlimit,NegativeEndlimit")
+    return BnR_GetAxisStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def BnR_SetQuietMode(Stage="", QuietMode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to enable the quiet mode for a stage (quiet turns motors powerless)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        QuietMode:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetQuietMode 1 C 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetQuietMode",Stage,QuietMode)
+
+
+def BnR_GetQuietMode(Stage=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to query the quiet mode for a stage
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        QuietMode:int
+    Command Timeout: 5000
+    Example:BnR_GetQuietMode 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetQuietMode",Stage)
+    return int(rsp[0])
+
+def BnR_GetInternalAxisInfo(Stage="", Axis="", InfoType=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns various axis information, dependent on the InfoType
+    parameter
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        InfoType:str = "StallInfo"
+    Returns:
+        RspString:str
+    Command Timeout: 5000
+    Example:BnR_GetInternalAxisInfo 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetInternalAxisInfo",Stage,Axis,InfoType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetWiringTesterData(Stage="", Axis=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to get various information required for the BnR wiring tester tool.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        STIn_ModuleOK:int
+        STIn_LifeCnt:int
+        STIn_DrvOK:int
+        STIn_OvertemperatureError:int
+        STIn_CurrentError:int
+        STIn_OvercurrentError:int
+        STIn_RefPulsePos:int
+        STIn_RefPulseCnt:int
+        STIn_ModulePowerSupplyError:int
+        STOut_SetTime:int
+        STOut_MotorStep0:int
+        STOut_DriveEnable:int
+        STOut_BoostCurrent:int
+        STOut_StandStillCurrent:int
+        STOut_ClearError:int
+        CMIn_ModuleOK:int
+        CMIn_SDCLifeCount:int
+        CMIn_Encoder:int
+        CMIn_EncoderTimeValid:int
+        CMIn_DigitalInput1:int
+        CMIn_DigitalInput2:int
+        CMIn_BWChannelA:int
+        CMIn_BWChannelB:int
+        CMIn_PowerSupply2:int
+        CMOut_QuitChannelA:int
+        CMOut_QuitChannelB:int
+        SWAxisErrorID:int
+        SWAxisErrorDesc:str
+    Command Timeout: 5000
+    Example:BnR_GetWiringTesterData 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetWiringTesterData",Stage,Axis)
+    global BnR_GetWiringTesterData_Response
+    if not "BnR_GetWiringTesterData_Response" in globals(): BnR_GetWiringTesterData_Response = namedtuple("BnR_GetWiringTesterData_Response", "STIn_ModuleOK,STIn_LifeCnt,STIn_DrvOK,STIn_OvertemperatureError,STIn_CurrentError,STIn_OvercurrentError,STIn_RefPulsePos,STIn_RefPulseCnt,STIn_ModulePowerSupplyError,STOut_SetTime,STOut_MotorStep0,STOut_DriveEnable,STOut_BoostCurrent,STOut_StandStillCurrent,STOut_ClearError,CMIn_ModuleOK,CMIn_SDCLifeCount,CMIn_Encoder,CMIn_EncoderTimeValid,CMIn_DigitalInput1,CMIn_DigitalInput2,CMIn_BWChannelA,CMIn_BWChannelB,CMIn_PowerSupply2,CMOut_QuitChannelA,CMOut_QuitChannelB,SWAxisErrorID,SWAxisErrorDesc")
+    return BnR_GetWiringTesterData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),int(rsp[14]),int(rsp[15]),int(rsp[16]),int(rsp[17]),int(rsp[18]),int(rsp[19]),int(rsp[20]),int(rsp[21]),int(rsp[22]),int(rsp[23]),int(rsp[24]),int(rsp[25]),int(rsp[26]),str("" if len(rsp) < 28 else ' '.join(rsp[27:])))
+
+def BnR_MoveAxis(Stage="", Axis="", Value="", Vel="", Dec="", WaitFinished=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows moving a single axis to and e.g. in case of X does not
+    trigger a Y movement
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        Value:Decimal = 0
+        Vel:Decimal = 0
+        Dec:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        PositionAfterMove:Decimal
+    Command Timeout: 60000
+    Example:BnR_MoveAxis 1 C X 20000 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveAxis",Stage,Axis,Value,Vel,Dec,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_MoveZCombined(ChuckTargetZ="", WaitFinished="", ForcedAbsVelocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move Chuck-Z and (by fixed factor) Scope X, Y and Z
+    API Status: internal
+    Args:
+        ChuckTargetZ:Decimal = 0
+        WaitFinished:int = 1
+        ForcedAbsVelocity:int = 0
+    Returns:
+        ChuckZ:Decimal
+        ScopeX:Decimal
+        ScopeY:Decimal
+        ScopeZ:Decimal
+    Command Timeout: 600000
+    Example:BnR_MoveZCombined 1 17592.5 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveZCombined",ChuckTargetZ,WaitFinished,ForcedAbsVelocity)
+    global BnR_MoveZCombined_Response
+    if not "BnR_MoveZCombined_Response" in globals(): BnR_MoveZCombined_Response = namedtuple("BnR_MoveZCombined_Response", "ChuckZ,ScopeX,ScopeY,ScopeZ")
+    return BnR_MoveZCombined_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def BnR_StepMove(Stage="", ZDown="", XValue="", YValue="", ZUp=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command does a combined Z-XY-Z- move completely on the BnR-controller
+    without WinKernel interaction. This is a part of an ongoing optimization.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZDown:Decimal = 0
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        ZUp:Decimal = 0
+    Command Timeout: 60000
+    Example:BnR_StepMove 1 C 250 1000 1000 250
+    """
+    MessageServerInterface.sendSciCommand("BnR_StepMove",Stage,ZDown,XValue,YValue,ZUp)
+
+
+def BnR_SearchEdgeSensor(SearchEndPos="", Velocity=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a search move until the search end position is reached or the edge
+    sensor triggers. If the edge sensor triggers during the move, the trigger
+    position is returned.Otherwise, an edge sensor not found error is returned.
+    API Status: internal
+    Args:
+        SearchEndPos:Decimal = 0
+        Velocity:Decimal = 0
+    Returns:
+        EdgeSensorTriggerPos:Decimal
+    Command Timeout: 300000
+    Example:BnR_SearchEdgeSensor 3000 10
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_SearchEdgeSensor",SearchEndPos,Velocity)
+    return Decimal(rsp[0])
+
+def BnR_GetTraceData(ControllerID=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a collection of trace data
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 5000
+    Example:BnR_GetTraceData 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetTraceData",ControllerID)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_SetTraceMode(ControllerID="", Mode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Commands sets the trace mode
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Mode:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetTraceMode 1 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetTraceMode",ControllerID,Mode)
+
+
+def BnR_WriteAxisModuleRegister(Stage="", Axis="", MotorModule="", RegisterName="", Value=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Development command to change a module register value without controller restart
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        MotorModule:int = 0
+        RegisterName:str = ""
+        Value:int = 0
+    Command Timeout: 5000
+    Example:BnR_WriteAxisModuleRegister 1 C X 1 ConfigOutput03 70
+    """
+    MessageServerInterface.sendSciCommand("BnR_WriteAxisModuleRegister",Stage,Axis,MotorModule,RegisterName,Value)
+
+
+def BnR_ReadAxisModuleRegister(Stage="", Axis="", MotorModule="", RegisterName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Development command to get any desired module register value
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        MotorModule:int = 0
+        RegisterName:str = ""
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:BnR_ReadAxisModuleRegister 1 C X 1 ConfigOutput03
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReadAxisModuleRegister",Stage,Axis,MotorModule,RegisterName)
+    return int(rsp[0])
+
+def ProcessStationGetStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns process station status (UNKNOWN, IDLE, BUSY, ERROR, PAUSED, Not
+    Initialized) and error code with error message when error.
+    API Status: internal
+    Returns:
+        Status:str
+        SubstratePresent:int
+        LastError:int
+        UseLoaderModule:int
+        WaferSizes:str
+        StatusMessage:str
+        IsLoaderJobRunning:int
+    Command Timeout: 25000
+    Example:ProcessStationGetStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationGetStatus")
+    global ProcessStationGetStatus_Response
+    if not "ProcessStationGetStatus_Response" in globals(): ProcessStationGetStatus_Response = namedtuple("ProcessStationGetStatus_Response", "Status,SubstratePresent,LastError,UseLoaderModule,WaferSizes,StatusMessage,IsLoaderJobRunning")
+    return ProcessStationGetStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ProcessStationInit():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initialize process station machine. This is not the prober init it is a fast
+    program initialization. Only applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 2400000
+    Example:ProcessStationInit
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationInit")
+
+
+def ProcessStationFinish():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Finishes a process station process. This resets some internal test information
+    for the probe station. Some data is only reset in case this command is sent
+    after the last wafer in the job was tested. Only applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 7500000
+    Example:ProcessStationFinish
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationFinish")
+
+
+def ProcessStationPrepareForLoad():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command moves the chuck of the probe station to the secondary load position and
+    if available also checks the table level sensor. Only applies to fully auto
+    systems.
+    API Status: internal
+    Command Timeout: 120000
+    Example:ProcessStationPrepareForLoad
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPrepareForLoad")
+
+
+def ProcessStationLoadComplete():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck out of the load position and checks if a wafer is placed. Only
+    applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationLoadComplete
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationLoadComplete")
+
+
+def ProcessStationPrepareForUnLoad():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The module should do whatever is necessary to prepare the current wafer for
+    unload. Typically this includes things such as moving lift pins and opening
+    doors.
+    API Status: internal
+    Command Timeout: 1000000
+    Example:ProcessStationPrepareForUnLoad
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPrepareForUnLoad")
+
+
+def ProcessStationUnLoadComplete():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The module should so whatever is necessary after a wafer is unloaded. This may
+    for example include closing doors.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationUnLoadComplete
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationUnLoadComplete")
+
+
+def ProcessStationLoadRecipe(ForceReOpenProject="", ProjectFileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The recipe is a zipped archive that includes all project data. This command
+    tells the device to load the recipe.
+    API Status: internal
+    Args:
+        ForceReOpenProject:int = 0
+        ProjectFileName:str = ""
+    Command Timeout: 60000
+    Example:ProcessStationLoadRecipe 1 SampleProject.spp
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationLoadRecipe",ForceReOpenProject,ProjectFileName)
+
+
+def ProcessStationVerifyRecipe(ProjectFileName=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Requests that the device verify that the recipe given can be executed on the
+    device. It should check that the recipe is correctly formed and conforms to the
+    hardware of the device. It should not check for transient things such as whether
+    there is sufficient media or facilities available. those kinds of checks should
+    be done in PrepareForProcess
+    API Status: internal
+    Args:
+        ProjectFileName:str = ""
+    Returns:
+        Verified:int
+        ErrorDescription:str
+    Command Timeout: 60000
+    Example:ProcessStationVerifyRecipe SampleProject.spp
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationVerifyRecipe",ProjectFileName)
+    global ProcessStationVerifyRecipe_Response
+    if not "ProcessStationVerifyRecipe_Response" in globals(): ProcessStationVerifyRecipe_Response = namedtuple("ProcessStationVerifyRecipe_Response", "Verified,ErrorDescription")
+    return ProcessStationVerifyRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ProcessStationStartRecipe(CurrentWaferInJob="", TotalWafersInJob=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells VeloxPro to start the current recipe. The station will switch to error if
+    an error occurs. If VeloxPro recipe execution is currently paused, this command
+    tells the system to continue execution.
+    API Status: internal
+    Args:
+        CurrentWaferInJob:int = -1
+        TotalWafersInJob:int = -1
+    Command Timeout: 25000
+    Example:ProcessStationStartRecipe 1
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationStartRecipe",CurrentWaferInJob,TotalWafersInJob)
+
+
+def ProcessStationStopRecipe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells the device to stop the current recipe. The station will switch to error if
+    an error occurs.
+    API Status: internal
+    Command Timeout: 25000
+    Example:ProcessStationStopRecipe
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationStopRecipe")
+
+
+def ProcessStationRecoverError():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells the module to do whatever is necessary to recover from an error condition.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationRecoverError
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationRecoverError")
+
+
+def ProcessStationGetWaferResult():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get substrate information from process station controller application.
+    API Status: internal
+    Returns:
+        Result:str
+        PercentDone:Decimal
+        AllowSkipWafer:int
+        TestInformation:str
+    Command Timeout: 25000
+    Example:ProcessStationGetWaferResult
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationGetWaferResult")
+    global ProcessStationGetWaferResult_Response
+    if not "ProcessStationGetWaferResult_Response" in globals(): ProcessStationGetWaferResult_Response = namedtuple("ProcessStationGetWaferResult_Response", "Result,PercentDone,AllowSkipWafer,TestInformation")
+    return ProcessStationGetWaferResult_Response(str(rsp[0]),Decimal(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def QueryWaferInfo():
+    """
+    Returns information about the wafer that is currently on the probe station. It
+    will return an error when there is no wafer currently on the chuck.
+    API Status: published
+    Returns:
+        Size:int
+        Angle:Decimal
+        ID:str
+        LotID:str
+        ProductID:str
+    Command Timeout: 25000
+    Example:QueryWaferInfo
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryWaferInfo")
+    global QueryWaferInfo_Response
+    if not "QueryWaferInfo_Response" in globals(): QueryWaferInfo_Response = namedtuple("QueryWaferInfo_Response", "Size,Angle,ID,LotID,ProductID")
+    return QueryWaferInfo_Response(int(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ProcessStationPauseRecipe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the process station to PAUSE mode
+    API Status: internal
+    Command Timeout: 25000
+    Example:ProcessStationPauseRecipe
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPauseRecipe")
+
+
+def GetProbingStatus():
+    """
+    Retrieves the current status of the prober. If probing status is AtFirstDie the
+    tester can take control.
+    API Status: published
+    Returns:
+        Status:str
+    Command Timeout: 25000
+    Example:GetProbingStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProbingStatus")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedProbing():
+    """
+    Tells the prober to proceed the recipe when current status is AtFirstDie.
+    API Status: published
+    Command Timeout: 25000
+    Example:ProceedProbing
+    """
+    MessageServerInterface.sendSciCommand("ProceedProbing")
+
+
+def GetCassetteStatus(Cassette=""):
+    """
+    Provides all available wafer information. It returns a set of data for each
+    wafer in either cassette. The data contains the cassette and the slot number
+    where the wafer is located, the status of the wafer, and identification
+    information.
+    API Status: published
+    Args:
+        Cassette:int = 0
+    Returns:
+        CassetteStatus:str
+    Command Timeout: 25000
+    Example:GetCassetteStatus 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCassetteStatus",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def QueryWaferID(Module="", Slot=""):
+    """
+    Queries the wafer ID of a given module and slot.
+    API Status: published
+    Args:
+        Module:str = "Robot"
+        Slot:int = 0
+    Returns:
+        ID:str
+    Command Timeout: 25000
+    Example:QueryWaferID Cassette1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryWaferID",Module,Slot)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def UpdateWaferID(Module="", Slot="", ID=""):
+    """
+    Overrides the wafer ID of the given module and slot. If the wafer id is empty
+    and the module is a Loadport, the id will be read by the idreader if possible.
+    This process behaves as follows:  - the current wafer id is reset - if the read-
+    wafer-process would be delayed (e.g. there is already a   wafer on the idreader)
+    the process will be aborted and an error         will be returned - if the id-
+    reading fails, the process behaves like a normal inventory  triggered by the UI:
+    skip (returns success), abort (returns error)      or "ask user". It is
+    recomended to use either skip or abort for         remote id reading.  If the
+    module is a Loadport and the slot is set to -1, a regular inventory will be
+    triggered. This behaves similar to an inventory triggered by the UI: The ID
+    won't be reset and already scanned wafers won't be reset. Setting an ID
+    explicitly with slot -1 is an error:  - Okay, read id of wafer in slot 3 even if
+    it is already set: UpdateWaferID Cassette1 3 - Okay, set id of wafer in slot 3
+    to XYZ123: UpdateWaferID Cassette1 3 XYZ123 - Okay, start full inventory:
+    UpdateWaferID Cassette1 -1  - Error: UpdateWaferID Cassette1 -1 XYZ123
+    API Status: published
+    Args:
+        Module:str = "Robot"
+        Slot:int = 0
+        ID:str = ""
+    Command Timeout: 1500000
+    Example:UpdateWaferID Cassette1 1 Wafer01
+    """
+    MessageServerInterface.sendSciCommand("UpdateWaferID",Module,Slot,ID)
+
+
+def ConfirmRecipe(ProjectFileName=""):
+    """
+    Queries whether the given project/flow name is a valid project/flow at the probe
+    station.  Using file and folder names without white spaces is recommended. For
+    folders and files whith white spaces use quotation marks for the path.  Example
+    for using white spaces:  ConfirmRecipe
+    "C:/Users/Public/Documents/Velox/Projects/White Spaces.spp"
+    API Status: published
+    Args:
+        ProjectFileName:str = ""
+    Returns:
+        Verified:int
+        ErrorDescription:str
+    Command Timeout: 25000
+    Example:ConfirmRecipe C:/Temp/Test.spp
+    """
+    rsp = MessageServerInterface.sendSciCommand("ConfirmRecipe",ProjectFileName)
+    global ConfirmRecipe_Response
+    if not "ConfirmRecipe_Response" in globals(): ConfirmRecipe_Response = namedtuple("ConfirmRecipe_Response", "Verified,ErrorDescription")
+    return ConfirmRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def StartWaferJob(RecipeName="", WaferIDs=""):
+    """
+    Creates and starts a new job by specifying the flow/spp file and the wafers to
+    be included in the job.
+    API Status: published
+    Args:
+        RecipeName:str = ""
+        WaferIDs:str = ""
+    Returns:
+        JobID:str
+    Command Timeout: 25000
+    Example:StartWaferJob C:/Users/Public/Documents/Velox/Test.flow 1;1 2;1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StartWaferJob",RecipeName,WaferIDs)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetJobParams(JobID=""):
+    """
+    Get job information for a specific job ID including the flow file and the list
+    of wafers.
+    API Status: published
+    Args:
+        JobID:str = ""
+    Returns:
+        RecipeName:str
+        WaferIDs:str
+    Command Timeout: 25000
+    Example:GetJobParams 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetJobParams",JobID)
+    global GetJobParams_Response
+    if not "GetJobParams_Response" in globals(): GetJobParams_Response = namedtuple("GetJobParams_Response", "RecipeName,WaferIDs")
+    return GetJobParams_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def JobStatus(JobID=""):
+    """
+    Retrieves the status of a specific job by its ID. If the status is ErrorWaiting,
+    an error string is returned.
+    API Status: published
+    Args:
+        JobID:str = ""
+    Returns:
+        Status:str
+        JobStatusInfo:str
+    Command Timeout: 25000
+    Example:JobStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("JobStatus",JobID)
+    global JobStatus_Response
+    if not "JobStatus_Response" in globals(): JobStatus_Response = namedtuple("JobStatus_Response", "Status,JobStatusInfo")
+    return JobStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AbortJob(JobID="", Unload=""):
+    """
+    Aborts the job given by the job ID. The status of the job will be set to
+    "Aborted". The "Unload" parameter defines whether the wafer remains on the chuck
+    or not.
+    API Status: published
+    Args:
+        JobID:str = ""
+        Unload:int = 0
+    Command Timeout: 25000
+    Example:AbortJob 2 1
+    """
+    MessageServerInterface.sendSciCommand("AbortJob",JobID,Unload)
+
+
+def ProcessStationCloseApplication(NoUserPrompt=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the VeloxPro application.
+    API Status: internal
+    Args:
+        NoUserPrompt:int = 0
+    Command Timeout: 25000
+    Example:ProcessStationCloseApplication
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationCloseApplication",NoUserPrompt)
+
+
+def UnloadWafer():
+    """
+    Unolads a Wafer from the chuck to its origin. If no origin is known, the first
+    free Slot of a loadport will be chosen. A Wafer should be on the chuck.
+    API Status: published
+    Command Timeout: 600000
+    Example:UnloadWafer
+    """
+    MessageServerInterface.sendSciCommand("UnloadWafer")
+
+
+def GetJobList(JobType=""):
+    """
+    Returns a string for the relevant JobIDs.
+    API Status: published
+    Args:
+        JobType:str = "Probing"
+    Returns:
+        GetJobList:str
+    Command Timeout: 25000
+    Example:GetJobList
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetJobList",JobType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedJob(ProceedJob=""):
+    """
+    Continues a job that is waiting on an error (Job Status ErrorWaiting). The mode
+    determines how the job continues.
+    API Status: published
+    Args:
+        ProceedJob:str = "AbortJob"
+    Command Timeout: 25000
+    Example:ProceedJob AbortJob
+    """
+    MessageServerInterface.sendSciCommand("ProceedJob",ProceedJob)
+
+
+def QueryCassetteID(Cassette=""):
+    """
+    Returns the ID of a cassette that is placed on the load port. The loadport and
+    the cassette must support RFID reading (additional hardware needed).
+    API Status: published
+    Args:
+        Cassette:int = 1
+    Returns:
+        ID:str
+    Command Timeout: 25000
+    Example:QueryCassetteID 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryCassetteID",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DockCassette(LoadPortId="", DockUndock=""):
+    """
+    Docks or undocks a cassette which is placed on a LoadPort (CM300 only). It will
+    return an error if no cassette is placed: the LoadPort is not ready/available or
+    the docking failed. The command will do the docking/undocking and return when
+    this is done.
+    API Status: published
+    Args:
+        LoadPortId:int = 0
+        DockUndock:int = 0
+    Command Timeout: 60000
+    Example:DockCassette 1 1
+    """
+    MessageServerInterface.sendSciCommand("DockCassette",LoadPortId,DockUndock)
+
+
+def LoadWafer(LoadportID="", SlotID="", AlignmentAngle=""):
+    """
+    Load a wafer from a given loadport onto the prober. If no slot id is defined,
+    the first available wafer with the lowest slot id will be loaded. If no loadport
+    is defined, it will try to use the first loadport. If there is no suitable
+    wafer, it will try the second.  Returns an error if the loading process fails or
+    no suitable wafer is found.  To define an alignment angle and still use the
+    "autoselect" behaviour, use -1 for loadport and slot.
+    API Status: published
+    Args:
+        LoadportID:int = -1
+        SlotID:int = -1
+        AlignmentAngle:Decimal = 0
+    Command Timeout: 600000
+    Example:LoadWafer 1 1
+    """
+    MessageServerInterface.sendSciCommand("LoadWafer",LoadportID,SlotID,AlignmentAngle)
+
+
+def UpdateCassetteStatus(Cassette=""):
+    """
+    Updates the cassette status with a simple scan.
+    API Status: published
+    Args:
+        Cassette:int = 0
+    Returns:
+        CassetteStatus:str
+    Command Timeout: 1200000
+    Example:UpdateCassetteStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("UpdateCassetteStatus",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def TransportWafer(SourceLocation="", SourceSlot="", DestinationLocation="", DestinationSlot=""):
+    """
+    Transport a wafer from one location to another. This command behaves like the
+    wafer-transport inside the LoaderModule. The Slot must always be set.
+    API Status: published
+    Args:
+        SourceLocation:str = "Cassette1"
+        SourceSlot:int = 1
+        DestinationLocation:str = "Cassette1"
+        DestinationSlot:int = 1
+    Command Timeout: 600000
+    Example:TransportWafer Cassette1 1 PreAligner 1
+    """
+    MessageServerInterface.sendSciCommand("TransportWafer",SourceLocation,SourceSlot,DestinationLocation,DestinationSlot)
+
+
+def ProcessWafer(Module="", ProcessParam=""):
+    """
+    "Process" a wafer on a given location. What is done depends on the current
+    station:  - IDReader: read ID - PreAligner: align wafer (alignment angle
+    mandatory) - Prober: Perform current recipe
+    API Status: published
+    Args:
+        Module:str = "Cassette1"
+        ProcessParam:str = ""
+    Command Timeout: 100000
+    Example:ProcessWafer PreAligner 90.0
+    """
+    MessageServerInterface.sendSciCommand("ProcessWafer",Module,ProcessParam)
+
+
+def GetIDReaderPos():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the IDReader
+    API Status: internal
+    Returns:
+        IDReaderPos:str
+    Command Timeout: 2000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetIDReaderPos")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetIDReaderPos(IDReaderPos=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the current position of the IDReader
+    API Status: internal
+    Args:
+        IDReaderPos:str = "Bottom"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetIDReaderPos",IDReaderPos)
+
+
+def CryoCommand(Process=""):
+    """
+    CryoCommand controls automatic cooling and warm up.
+    API Status: published
+    Args:
+        Process:str = "CD"
+    Command Timeout: 60000
+    Example:CryoCommand CD
+    """
+    MessageServerInterface.sendSciCommand("CryoCommand",Process)
+
+
+def CryoReadTemperature(Stage=""):
+    """
+    Reads the current temperature from sensor chuck or shield.
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Returns:
+        Temp:Decimal
+    Command Timeout: 10000
+    Example:CryoReadTemperature C
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadTemperature",Stage)
+    return Decimal(rsp[0])
+
+def CryoSetTemperature(Stage="", Temp=""):
+    """
+    Sets temperature value for TIC chuck or shield. (Only available in process state
+    'Idle' or 'Cold'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+        Temp:Decimal = 320
+    Command Timeout: 10000
+    Example:CryoSetTemperature C 70.5
+    """
+    MessageServerInterface.sendSciCommand("CryoSetTemperature",Stage,Temp)
+
+
+def CryoStartRefill(Stage=""):
+    """
+    Enables refill. (Only available in process state 'Idle'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Command Timeout: 10000
+    Example:CryoStartRefill C
+    """
+    MessageServerInterface.sendSciCommand("CryoStartRefill",Stage)
+
+
+def CryoStopRefill(Stage=""):
+    """
+    Disables refill. (Only available in process state 'Idle'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Command Timeout: 10000
+    Example:CryoStopRefill C
+    """
+    MessageServerInterface.sendSciCommand("CryoStopRefill",Stage)
+
+
+def CryoReadState():
+    """
+    Reads current state.
+    API Status: published
+    Returns:
+        State:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CryoMoveBBPark():
+    """
+    Moves the black body to parking position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveBBPark")
+
+
+def CryoMoveBBWork(NbrPosition=""):
+    """
+    Moves the black body to working position.
+    API Status: published
+    Args:
+        NbrPosition:int = 1
+    Command Timeout: 60000
+    Example:CryoMoveBBWork 1
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveBBWork",NbrPosition)
+
+
+def CryoMoveShutter(Position="", Shutter=""):
+    """
+    Moves one of the two shutters.
+    API Status: published
+    Args:
+        Position:str = "C"
+        Shutter:int = 1
+    Command Timeout: 60000
+    Example:CryoMoveShutter F 1
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveShutter",Position,Shutter)
+
+
+def CryoMoveScopeWork():
+    """
+    Moves the microscope to working position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveScopeWork")
+
+
+def CryoMoveScopePark():
+    """
+    Moves the microscope to parking position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveScopePark")
+
+
+def CryoReadPressure():
+    """
+    Reads the current pressure of the vacuum chamber.
+    API Status: published
+    Returns:
+        Pressure:Decimal
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadPressure")
+    return Decimal(rsp[0])
+
+def MoveZCombined(Height="", Percent="", Async=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move both Chuck and Scope to a new absolute z-Height. The position must be
+    within 0 and a predefined maximum height (e.g. 3000um). Moves are performed with
+    maximum velocity for now
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        Percent:Decimal = 0
+        Async:int = 0
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombined",Height,Percent,Async)
+
+
+def GetSoftwareStop():
+    """
+    Get the state of the software stop.
+    API Status: published
+    Returns:
+        StopState:int
+    Command Timeout: 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwareStop")
+    return int(rsp[0])
+
+def MoveZCombinedSetStatus(Status="", Message=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Used to set the system either in off, on, error or locked state.  For lock, a
+    key is required. To unlock this key, doe a 'SetStatus' with the same key. So,
+    SetStatus without message means enable/ recover from error, with message it
+    means unlock. If the system wasn't enabled or in error state before an unlock,
+    it will remain in this state after the unlock.
+    API Status: internal
+    Args:
+        Status:str = "Off"
+        Message:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombinedSetStatus",Status,Message)
+
+
+def GetScopeWorkingStage():
+    """
+    Get the currently active ScopeWorkingStage or -1 if unknown. Normally, this
+    should be the same as the currently active ScopeSilo
+    API Status: published
+    Returns:
+        ScopeWorkingStage:int
+    Command Timeout: 5000
+    Example:GetScopeWorkingStage
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetScopeWorkingStage")
+    return int(rsp[0])
+
+def SetPerformanceMode(Mode=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the performance mode in use by remote command. If this feature is not
+    supported and the mode is anything but Standard, an error is returned.
+    API Status: internal
+    Args:
+        Mode:str = "Standard"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SetPerformanceMode",Mode)
+
+
+def SetScopeWorkingStage(ScopeWorkingStage=""):
+    """
+    Move to the target working stage
+    API Status: published
+    Args:
+        ScopeWorkingStage:int = -1
+    Command Timeout: 30000
+    Example:SetScopeWorkingStage 1
+    """
+    MessageServerInterface.sendSciCommand("SetScopeWorkingStage",ScopeWorkingStage)
+
+
+def GetPerformanceMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the currently configured performance mode. If this feature is not supported
+    on a station, Standard will be returned
+    API Status: internal
+    Returns:
+        Mode:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPerformanceMode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def MoveZCombinedGetStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the current status of the combined-z-move-system
+    API Status: internal
+    Returns:
+        Status:str
+        PlatenSafe:int
+        Height:Decimal
+        HeightMax:Decimal
+        HeightRelative:Decimal
+        SafeHeight:Decimal
+        Message:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveZCombinedGetStatus")
+    global MoveZCombinedGetStatus_Response
+    if not "MoveZCombinedGetStatus_Response" in globals(): MoveZCombinedGetStatus_Response = namedtuple("MoveZCombinedGetStatus_Response", "Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message")
+    return MoveZCombinedGetStatus_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str("" if len(rsp) < 7 else ' '.join(rsp[6:])))
+
+def LoadScopeFenceConfiguration(Enable="", Path=""):
+    """
+    Load a previously saved Scope-Fence-configuration or remove the current
+    configuration
+    API Status: published
+    Args:
+        Enable:int = 0
+        Path:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LoadScopeFenceConfiguration",Enable,Path)
+
+
+def SetSoftwareStop(StopState=""):
+    """
+    Set the state of the software stop.
+    API Status: published
+    Args:
+        StopState:int = 0
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("SetSoftwareStop",StopState)
+
+
+#End of module
diff --git a/src/FlexSensor/Prober/velox_api/velox/sci35.py b/src/FlexSensor/Prober/velox_api/velox/sci35.py
new file mode 100644
index 0000000000000000000000000000000000000000..655db8fb75f1ddee407da4bee0f5d95a0fe8a6aa
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/sci35.py
@@ -0,0 +1,11999 @@
+from Prober.velox_api.velox.vxmessageserver import *
+from decimal import Decimal
+from collections import namedtuple
+
+"""
+Velox SCI Commands
+This module provides a function interface to the Cascade Microtech Velox software suite. 
+The module was auto-generated from the commands.info.xml file on 2019-11-09.  
+737 SCI commands were found and included.
+
+To use this module, your code must import the veloxsci.py module.
+Create a connection to the Velox Message Server using the 'with MessageServerInterface():' 
+command as shown in the sample below.
+
+The Velox Message Server must be running prior to establishing a connection. 
+To start the Message Server, run Velox.
+
+The sample code to use this module is:
+
+import velox
+with velox.MessageServerInterface() as msgServer:
+
+    # Your Code: try some SCI Commands - such as:
+    response = velox.ReportKernelVersion()
+    print ('The kernel version is', response.Version, 'and', response.Description)
+    
+"""
+def EchoData(TestCmd:str=""):
+    """
+    Test Command for the Kernel Communication. Like a ping command, the given text
+    string is returned unchanged.
+    API Status: published
+    Args:
+        TestCmd:str = "Test"
+    Returns:
+        TestRsp:str
+    Command Timeout: 5000
+    Example:EchoData Test
+    """
+    rsp = MessageServerInterface.sendSciCommand("EchoData",TestCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportKernelVersion(Module:str=""):
+
+    """
+    Returns the version information of the kernel or the control box code. The
+    "Version" value contains version number and revision level of the actual Kernel
+    implementation. The text string contains a code description, version number and
+    the revision date.
+    API Status: published
+    Args:
+        Module:str = "K"
+    Returns:
+        Version:Decimal
+        Description:str
+    Command Timeout: 5000
+    Example:ReportKernelVersion K
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReportKernelVersion",Module)
+    global ReportKernelVersion_Response
+    if not "ReportKernelVersion_Response" in globals(): ReportKernelVersion_Response = namedtuple("ReportKernelVersion_Response", "Version,Description")
+    return ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReadProberStatus():
+    """
+    Returns an actual status information of the prober.
+    API Status: published
+    Returns:
+        FlagsBusy:int
+        FlagsContact:int
+        Mode:str
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadProberStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProberStatus")
+    global ReadProberStatus_Response
+    if not "ReadProberStatus_Response" in globals(): ReadProberStatus_Response = namedtuple("ReadProberStatus_Response", "FlagsBusy,FlagsContact,Mode,IsQuiet")
+    return ReadProberStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]))
+
+def EnableMotorQuiet(WantQuietModeOn:int="", Stage:str=""):
+    """
+    Toggles the motor power for quiet probing. In most applications this feature is
+    not required. However, for special measurements it may be necessary to reduce
+    the noise of the system. Quiet on turns off the motor power for all stages (or
+    the one specified with the optional parameter). Quiet off will turn on the motor
+    power of all stages (or the one specified with the optional parameter) for
+    subsequent movements. A move command will also turn on the motor power of the
+    moved stage automatically. For automatical switching of the quiet mode refer to
+    Auto Quiet functionality.  Sending 'EnableMotorQuiet 1' will enable the quiet
+    mode for all stages. Sending 'EnableMotorQuiet 1 C' will only enable the quiet
+    mode for the chuck stage. Sending 'EnableMotorQuiet 1 1' will only enable the
+    quiet mode for the Positioner1 stage. Sending 'EnableMotorQuiet 0 S' will only
+    disable the quiet mode for the scope stage.
+    API Status: published
+    Args:
+        WantQuietModeOn:int = 0
+        Stage:str = "None"
+    Command Timeout: 10000
+    Example:EnableMotorQuiet 1
+    """
+    MessageServerInterface.sendSciCommand("EnableMotorQuiet",WantQuietModeOn,Stage)
+
+
+def SetChuckVacuum(WantChuckVacuumOn:int=""):
+    """
+    Toggles the chuck vacuum on (1) or off (0). Can return vacuum timeout error for
+    stations with wafer vacuum sensors in case no wafer was detected.
+    API Status: published
+    Args:
+        WantChuckVacuumOn:int = 0
+    Command Timeout: 10000
+    Example:SetChuckVacuum 1
+    """
+    MessageServerInterface.sendSciCommand("SetChuckVacuum",WantChuckVacuumOn)
+
+
+def SetMicroLight(WantIlluminatorOn:int=""):
+    """
+    Toggles the microscope light channel of the peripheral output board and all
+    cameras. Notifications: 7
+    API Status: published
+    Args:
+        WantIlluminatorOn:int = 2
+    Command Timeout: 5000
+    Example:SetMicroLight 1
+    """
+    MessageServerInterface.sendSciCommand("SetMicroLight",WantIlluminatorOn)
+
+
+def SetBeaconStatus(FlagsMode:int="", PulseWidthRed:int="", PulseWidthGreen:int="", PulseWidthYellow:int="", PulseWidthBlue:int="", PulseWidthWhite:int=""):
+    """
+    This command controls the beacon channel of the peripheral output board. All
+    lights can be switched on, off, or blinking. Setting an interval to zero means,
+    that the corresponding light will be statically on or off. The minimum blinking
+    interval is 50ms.
+    API Status: published
+    Args:
+        FlagsMode:int = 0
+        PulseWidthRed:int = 1000
+        PulseWidthGreen:int = 0
+        PulseWidthYellow:int = 0
+        PulseWidthBlue:int = 0
+        PulseWidthWhite:int = 0
+    Command Timeout: 5000
+    Example:SetBeaconStatus 1 1000
+    """
+    MessageServerInterface.sendSciCommand("SetBeaconStatus",FlagsMode,PulseWidthRed,PulseWidthGreen,PulseWidthYellow,PulseWidthBlue,PulseWidthWhite)
+
+
+def SetOutput(Channel:int="", WantOutputOn:int="", PulseTime:int=""):
+    """
+    Controls the Velox output channel signals. It can be used to activate/deactivate
+    outputs.
+    API Status: published
+    Args:
+        Channel:int = 1
+        WantOutputOn:int = 0
+        PulseTime:int = -1
+    Command Timeout: 5000
+    Example:SetOutput 4 0
+    """
+    MessageServerInterface.sendSciCommand("SetOutput",Channel,WantOutputOn,PulseTime)
+
+
+def StopAllMovements():
+    """
+    Stops all Prober movements immediately. The response status value of any pending
+    movement will signify that the stop command was executed.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopAllMovements
+    """
+    MessageServerInterface.sendSciCommand("StopAllMovements")
+
+
+def InkDevice(FlagsInker:int="", PulseWidth:int=""):
+    """
+    Inks the current device under test. The range of PulseWidth is 20ms to 2000ms.
+    For correct function, the inkers have to be linked to default outputs.
+    API Status: published
+    Args:
+        FlagsInker:int = 0
+        PulseWidth:int = 50
+    Command Timeout: 10000
+    Example:InkDevice 1 40
+    """
+    MessageServerInterface.sendSciCommand("InkDevice",FlagsInker,PulseWidth)
+
+
+def ReadProbeSetup():
+    """
+    Returns the current positioner configuration.  The output pattern is:  1. Type
+    Positioner 1 2. Type Positioner 2 3. Type Positioner 3 4. Type Positioner 4 5.
+    Type Positioner 5 6. Axis Positioner 1 (Bit 0: XY, Bit 1: Z) 7. Axis Positioner
+    2 (Bit 0: XY, Bit 1: Z) 8. Axis Positioner 3 (Bit 0: XY, Bit 1: Z) 9. Axis
+    Positioner 4 (Bit 0: XY, Bit 1: Z) 10. Axis Positioner 5 (Bit 0: XY, Bit 1: Z)
+    11. Type Positioner 6 12. Axis Positioner 6 (Bit 0: XY, Bit 1: Z)
+    API Status: published
+    Returns:
+        TypePositioner1:int
+        TypePositioner2:int
+        TypePositioner3:int
+        TypePositioner4:int
+        TypePositioner5:int
+        AxisPositioner1:int
+        AxisPositioner2:int
+        AxisPositioner3:int
+        AxisPositioner4:int
+        AxisPositioner5:int
+        TypePositioner6:int
+        AxisPositioner6:int
+    Command Timeout: 5000
+    Example:ReadProbeSetup
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeSetup")
+    global ReadProbeSetup_Response
+    if not "ReadProbeSetup_Response" in globals(): ReadProbeSetup_Response = namedtuple("ReadProbeSetup_Response", "TypePositioner1,TypePositioner2,TypePositioner3,TypePositioner4,TypePositioner5,AxisPositioner1,AxisPositioner2,AxisPositioner3,AxisPositioner4,AxisPositioner5,TypePositioner6,AxisPositioner6")
+    return ReadProbeSetup_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]))
+
+def ReadSystemStatus():
+    """
+    Returns the system options which are currently enabled at the prober.
+    API Status: published
+    Returns:
+        Name:str
+        System:str
+        ChuckXY:int
+        ChuckZ:int
+        ChuckTheta:int
+        ScopeXY:int
+        ScopeZ:int
+        EdgeSensor:int
+        OperationalMode:str
+        Turret:int
+        TemperatureChuck:int
+        AuxSiteCount:int
+        PlatenXY:int
+        PlatenZ:int
+        LoaderGateState:str
+        NucleusType:str
+    Command Timeout: 10000
+    Example:ReadSystemStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSystemStatus")
+    global ReadSystemStatus_Response
+    if not "ReadSystemStatus_Response" in globals(): ReadSystemStatus_Response = namedtuple("ReadSystemStatus_Response", "Name,System,ChuckXY,ChuckZ,ChuckTheta,ScopeXY,ScopeZ,EdgeSensor,OperationalMode,Turret,TemperatureChuck,AuxSiteCount,PlatenXY,PlatenZ,LoaderGateState,NucleusType")
+    return ReadSystemStatus_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),str(rsp[14]),str("" if len(rsp) < 16 else ' '.join(rsp[15:])))
+
+def SetExternalMode(Mode:str=""):
+    """
+    If 'R' is sent, it sets the external mode of the kernel. This disables most of
+    the control box functions (except the LOCAL function key). Otherwise, this
+    command re-enables all functions of the control box.
+    API Status: published
+    Args:
+        Mode:str = "L"
+    Command Timeout: 5000
+    Example:SetExternalMode L
+    """
+    MessageServerInterface.sendSciCommand("SetExternalMode",Mode)
+
+
+def SetStageLock(Stage:str="", WantStageLock:int="", Application:str=""):
+    """
+    Enables or disables the stage lock functionality. Stages which are locked can't
+    be moved in any way. If the joystick controller is locked, the display and the
+    keys are deactivated. The name of the application can be stored by using the
+    Application Name parameter and is shown in lock-caused error messages.
+    API Status: published
+    Args:
+        Stage:str = "0"
+        WantStageLock:int = 1
+        Application:str = ""
+    Command Timeout: 10000
+    Example:SetStageLock C 0 WaferMap
+    """
+    MessageServerInterface.sendSciCommand("SetStageLock",Stage,WantStageLock,Application)
+
+
+def ReadSensor(Channel:int="", Type:str=""):
+    """
+    Returns the actual status of the specified input channel, output channel or edge
+    sensor. The signal table is described in the Hardware Manual. Each used IO-board
+    has 16 channels (max. 4 IO-boards are supported), what results in a domain of 64
+    channel numbers. Beyond this range there are pseudo channels, which are used for
+    special purposes. Pseudo channels:
+    API Status: published
+    Args:
+        Channel:int = 1
+        Type:str = "Input"
+    Returns:
+        IsSensorOn:int
+    Command Timeout: 10000
+    Example:ReadSensor 11 I
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSensor",Channel,Type)
+    return int(rsp[0])
+
+def GetStageLock(Stage:str=""):
+    """
+    Reads whether stages or joystick controller are locked.
+    API Status: published
+    Args:
+        Stage:str = "0"
+    Returns:
+        Locks:int
+        Application:str
+    Command Timeout: 10000
+    Example:GetStageLock C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetStageLock",Stage)
+    global GetStageLock_Response
+    if not "GetStageLock_Response" in globals(): GetStageLock_Response = namedtuple("GetStageLock_Response", "Locks,Application")
+    return GetStageLock_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetBackSideMode(WantBackSideMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets bottomside mode. In this mode the Z axis is reverse and the
+    command MoveChuckLoad is not allowed.
+    API Status: internal
+    Args:
+        WantBackSideMode:int = 0
+    Command Timeout: 5000
+    Example:SetBackSideMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetBackSideMode",WantBackSideMode)
+
+
+def GetBackSideMode():
+    """
+    Returns the current side mode.
+    API Status: published
+    Returns:
+        IsBackSideModeOn:int
+    Command Timeout: 5000
+    Example:GetBackSideMode
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBackSideMode")
+    return int(rsp[0])
+
+def SetDarkMode(WantSetDarkMode:int=""):
+    """
+    Switches off all LEDs on the Control Box, on the positioners, and on the screen
+    of the Control Box and also the light of the cameras.
+    API Status: published
+    Args:
+        WantSetDarkMode:int = 0
+    Command Timeout: 5000
+    Example:SetDarkMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetDarkMode",WantSetDarkMode)
+
+
+def GetDarkMode():
+    """
+    Returns the current mode of the light sources.
+    API Status: published
+    Returns:
+        IsDarkMode:int
+    Command Timeout: 5000
+    Example:GetDarkMode
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDarkMode")
+    return int(rsp[0])
+
+def DockChuckCamera(ConnectCamera:str="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Connect or disconnect the chuck camera to the chuck stage. The command is only
+    available for the Prober type PA300BEP.
+    API Status: internal
+    Args:
+        ConnectCamera:str = "ParkPos"
+        Velocity:Decimal = 100
+    Command Timeout: 300000
+    Example:DockChuckCamera P 75
+    """
+    MessageServerInterface.sendSciCommand("DockChuckCamera",ConnectCamera,Velocity)
+
+
+def ReadCBoxStage():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current selected stage of the joystick controller.
+    API Status: internal
+    Returns:
+        Stage:str
+    Command Timeout: 5000
+    Example:ReadCBoxStage
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxStage")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxStage(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current stage of the joystick controller.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Command Timeout: 5000
+    Example:SetCBoxStage C
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxStage",Stage)
+
+
+def ReadCBoxPosMonConf(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current setting of the joystick controllers position monitor for the
+    secified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        PosRef:str
+        Unit:str
+    Command Timeout: 5000
+    Example:ReadCBoxPosMonConf C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxPosMonConf",Stage)
+    global ReadCBoxPosMonConf_Response
+    if not "ReadCBoxPosMonConf_Response" in globals(): ReadCBoxPosMonConf_Response = namedtuple("ReadCBoxPosMonConf_Response", "PosRef,Unit")
+    return ReadCBoxPosMonConf_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetCBoxPosMonConf(Stage:str="", PosRef:str="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Configures the joystick controller position monitor for the secified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetCBoxPosMonConf C Z Y
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxPosMonConf",Stage,PosRef,Unit)
+
+
+def ReadCBoxCurrSpeed(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current speed of the joystick controller for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        CBoxSpeed:str
+    Command Timeout: 5000
+    Example:ReadCBoxCurrSpeed C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCBoxCurrSpeed",Stage)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetCBoxCurrSpeed(Stage:str="", CBoxSpeed:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current speed of the joystick controller for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CBoxSpeed:str = "Speed4"
+    Command Timeout: 5000
+    Example:SetCBoxCurrSpeed C 3
+    """
+    MessageServerInterface.sendSciCommand("SetCBoxCurrSpeed",Stage,CBoxSpeed)
+
+
+def MoveChuckAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck stage to the specified X,Y position without waiting for the move
+    to be finished If chuck Z is in contact height or higher, the chuck will drop to
+    separation.
+    API Status: internal
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 5000
+    Example:MoveChuckAsync 5000. 5000. R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeAsync(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the scope stage to the specified X,Y position without waiting for the move
+    to be finished.
+    API Status: internal
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 5000
+    Example:MoveScopeAsync 5000 5000 R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeAsync",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveProbeAsync(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the probe stage to the specified X,Y position without waiting for the move
+    to be finished.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeAsync",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def ReadChuckStatus():
+    """
+    Returns the current chuck status. Every bit in the bit fields works like a
+    boolean value: One &lt;1&gt; means true/on and zero &lt;0&gt; means false/off.
+    Its counted from LSB to MSB.   - _FlagsInit_: X, Y, Z, Theta - _FlagsMode_:
+    HasOvertravel, HasAutoZ, HasInterlock, ContactSearch, IsContactSet,
+    EdgeInterlock, QuietContact, IsLocked - _FlagsLimit_: XHigh, XLow, YHigh, YLow,
+    ZHigh, ZLow, ThetaHigh, ThetaLow - _FlagsMoving_: X, Y, Z, Theta  All parameters
+    are provided as indirect access (e.g. first bit of M_pvecFlagsInit can be
+    accessed by M_pbIsInitX).
+    API Status: published
+    Returns:
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        IsVacuumOn:int
+        PresetHeight:str
+        LoadPos:str
+        IsLiftDown:int
+        CameraConnection:str
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadChuckStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckStatus")
+    global ReadChuckStatus_Response
+    if not "ReadChuckStatus_Response" in globals(): ReadChuckStatus_Response = namedtuple("ReadChuckStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,IsVacuumOn,PresetHeight,LoadPos,IsLiftDown,CameraConnection,IsQuiet")
+    return ReadChuckStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),int(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),str(rsp[9]),int(rsp[10]))
+
+def ReadChuckPosition(Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the current chuck stage position in X, Y and Z.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckPosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckPosition",Unit,PosRef,Comp)
+    global ReadChuckPosition_Response
+    if not "ReadChuckPosition_Response" in globals(): ReadChuckPosition_Response = namedtuple("ReadChuckPosition_Response", "X,Y,Z")
+    return ReadChuckPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadChuckHeights(Unit:str=""):
+    """
+    Returns the current settings used for the chuck Z movement. `Contact` is the
+    contact-height from zero in default compensation. The other heights are relative
+    to this. If no contact is set, the value will be -1.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+        SearchGap:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckHeights",Unit)
+    global ReadChuckHeights_Response
+    if not "ReadChuckHeights_Response" in globals(): ReadChuckHeights_Response = namedtuple("ReadChuckHeights_Response", "Contact,Overtravel,AlignDist,SepDist,SearchGap")
+    return ReadChuckHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def InitChuck(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+    """
+    Machine Coordinate System: Chuck X Y Z Theta  - _FlagsInit_: X, Y, Z, Theta -
+    _FlagsDirection_: X, Y, Z, Theta (true means plus direction) - _FlagsMoveRange_:
+    X, Y, Z, Theta   All flags can be accessed by indirect members.  Initializes the
+    chuck stage and resets current coordinate system. Should be used only in cases
+    when the reported coordinates do not correspond to real position of mechanics.
+    Find Move Range starts the initialization in the defined direction and then
+    moves to the other limit and finds the whole range of the axes.
+    API Status: published
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 150000
+    Example:InitChuck 7 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitChuck",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveChuck(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the chuck stage to the specified X,Y position. If chuck Z is in contact
+    height or higher, Interlock and Auto Z flags will be analyzed and stage will
+    behave correspondingly - can move to separation first or return an error:
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 30000
+    Example:MoveChuck 5000. 5000. R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuck",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveChuckIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck stage in index steps. This command modifies Die Home Position.
+    API Status: published
+    Args:
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckIndex 1 1 R 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveChuckSubsite(XValue:Decimal="", YValue:Decimal="", Unit:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck stage to the specified X, Y sub-site position. Die home position
+    is defined by destination position of last successful MoveChuck or
+    MoveChuckIndex commands. MoveChuckVelocity does not touch die home position. If
+    you have moved chuck with MoveChuckVelocity, "MoveChuckSubsite 0 0" will move it
+    back to die home position.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckSubsite 200 200 Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckSubsite",XValue,YValue,Unit,Velocity)
+
+
+def MoveChuckContact(Velocity:Decimal=""):
+    """
+    Performs a movement of chuck Z axis to preset contact height or will return
+    error if no contact height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckContact 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckContact",Velocity)
+
+
+def MoveChuckAlign(Velocity:Decimal=""):
+    """
+    Moves the chuck Z axis to the align height. If no Contact height is set will
+    return an error.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckAlign",Velocity)
+
+
+def MoveChuckSeparation(Velocity:Decimal=""):
+    """
+    Moves the chuck Z axis to the separation height. Returns error if no Contact
+    height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveChuckSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckSeparation",Velocity)
+
+
+def MoveChuckLoad(LoadPosition:str=""):
+    """
+    Moves the Chuck stage in X, Y, Z and Theta to the load position.
+    API Status: published
+    Args:
+        LoadPosition:str = "First"
+    Command Timeout: 60000
+    Example:MoveChuckLoad 0
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckLoad",LoadPosition)
+
+
+def MoveChuckZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the chuck Z axis to the specified height. If contact is set, only moves up
+    to contact height will be allowed. If overtravel is enabled - up to overtravel
+    height.
+    API Status: published
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 60000
+    Example:MoveChuckZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SearchChuckContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the chuck Z axis to the specified height and sets contact. The move stops
+    immediately if the Contact Sensor ( Edge Sensor) is triggered. If no contact has
+    been found and an old one was set before the old contact will not get lost, it
+    will be reset.
+    API Status: published
+    Args:
+        Height:Decimal = 100
+        PosRef:str = "Relative"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ContactHeight:Decimal
+    Command Timeout: 60000
+    Example:SearchChuckContact 1000 R Y 10
+    """
+    rsp = MessageServerInterface.sendSciCommand("SearchChuckContact",Height,PosRef,Unit,Velocity,Comp)
+    return Decimal(rsp[0])
+
+def MoveChuckVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    Moves the chuck stage in velocity mode. The motion continues until the
+    StopChuckMovement command is received, or the end limit is reached.
+    API Status: published
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 30000
+    Example:MoveChuckVelocity + + 0 100 30 0
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopChuckMovement(FlagsStop:int=""):
+    """
+    Stops chuck movement for the given axis. Notifications: 31 / 32 / 5
+    API Status: published
+    Args:
+        FlagsStop:int = 15
+    Command Timeout: 5000
+    Example:StopChuckMovement 7
+    """
+    MessageServerInterface.sendSciCommand("StopChuckMovement",FlagsStop)
+
+
+def SetChuckMode(Overtravel:int="", AutoZ:int="", Interlock:int="", ContactSearch:int="", EdgeInterlock:int="", QuietContact:int=""):
+    """
+    Mode manages the way the chuck behaves when it is in contact height. Chuck mode
+    is made from 6 flags and you can control all of them using this command. Every
+    flag can be turned on by using value 1 or turned off by using value 0. If you do
+    not want to change a flag - use value of 2.
+    API Status: published
+    Args:
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        ContactSearch:int = 2
+        EdgeInterlock:int = 2
+        QuietContact:int = 2
+    Command Timeout: 5000
+    Example:SetChuckMode 2 2 2 2 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetChuckMode",Overtravel,AutoZ,Interlock,ContactSearch,EdgeInterlock,QuietContact)
+
+
+def SetChuckHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets wafer and die home position, which can be used later as coordinate system
+    for movements.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckHome 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetChuckHome",Mode,Unit,XValue,YValue)
+
+
+def SetChuckIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the wafer index size. Normally the size of one die.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetChuckIndex 5000. 5000. Y
+    """
+    MessageServerInterface.sendSciCommand("SetChuckIndex",XValue,YValue,Unit)
+
+
+def SetChuckHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align and separation. A predefined contact search gap is able to write. No data
+    in the optional parameters sets contact height at current position. If Mode is
+    '0', contact height can be set at current position. The levels O, A, S and T
+    support no Mode '0'. If Mode is 'V' and no value for height is specified -
+    default 0 will be used, what potentially can be not what you expect. If Mode is
+    'R', contact height can be invalidated. The levels O, A, S and T support no Mode
+    'R'.
+    API Status: published
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckHeight C V Y 5000.
+    """
+    MessageServerInterface.sendSciCommand("SetChuckHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadChuckIndex(Unit:str=""):
+    """
+    The command gets the current die size which is stored in the kernel.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckIndex Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckIndex",Unit)
+    global ReadChuckIndex_Response
+    if not "ReadChuckIndex_Response" in globals(): ReadChuckIndex_Response = namedtuple("ReadChuckIndex_Response", "IndexX,IndexY")
+    return ReadChuckIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveChuckTransfer():
+    """
+    Moves the Chuck to the Transfer Position. If the movement starts in Load
+    Position (where it's possible to pull out the chuck) the handling of the Add On
+    Platen or the Pin Chuck is integrated.
+    API Status: published
+    Command Timeout: 90000
+    Example:MoveChuckTransfer
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckTransfer")
+
+
+def MoveChuckLift(SetLift:int=""):
+    """
+    Moves the chuck to the upper (0) or lower = lifted (1) position. This initiates
+    motion only, the actual movement may take some seconds.
+    API Status: published
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MoveChuckLift 1
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckLift",SetLift)
+
+
+def SetChuckThermoScale(ScaleX:Decimal="", ScaleY:Decimal=""):
+    """
+    Thermo drifts of the wafer will be compensated. The compensation is not
+    persistent, (power off - this compensation is deleted). The algorithm works as
+    an additional one.  This is for an iterative usage, so:  1. `ResetProber H` 2.
+    `SetChuckThermoScale 1.5 1.5` 3. `SetChuckThermoScale 1.5 1.5`  will result in a
+    scale of 2.25 in both directions. The thermal scale can also be reset using the
+    command 'SetChcukThermoValue 20 C'
+    API Status: published
+    Args:
+        ScaleX:Decimal = 1
+        ScaleY:Decimal = 1
+    Command Timeout: 5000
+    Example:SetChuckThermoScale 1.000005 1.0000045
+    """
+    MessageServerInterface.sendSciCommand("SetChuckThermoScale",ScaleX,ScaleY)
+
+
+def ReadChuckThermoScale():
+    """
+    Read the linear scaling value of the chuck.
+    API Status: published
+    Returns:
+        ScaleX:Decimal
+        ScaleY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckThermoScale
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoScale")
+    global ReadChuckThermoScale_Response
+    if not "ReadChuckThermoScale_Response" in globals(): ReadChuckThermoScale_Response = namedtuple("ReadChuckThermoScale_Response", "ScaleX,ScaleY")
+    return ReadChuckThermoScale_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetChuckThermoValue(Temperature:Decimal="", Unit:str="", ExpCoeffX:Decimal="", ExpCoeffY:Decimal=""):
+    """
+    Set a temperature and optional the expansion coefficient. The temperature for
+    normal level is 20 degree. The scaling factor at this temperature is 1.0. If you
+    set the temperature directly the controller calculates the stage difference in
+    the coordinate system. For the calculation use the set coefficient of expansion
+    from the controller. The default coefficient of expansion is based on silicon:
+    2.33E-06 1/K.
+    API Status: published
+    Args:
+        Temperature:Decimal = 0
+        Unit:str = "Celsius"
+        ExpCoeffX:Decimal = 0
+        ExpCoeffY:Decimal = 0
+    Command Timeout: 5000
+    Example:SetChuckThermoValue 250 C 2.43 2.32
+    """
+    MessageServerInterface.sendSciCommand("SetChuckThermoValue",Temperature,Unit,ExpCoeffX,ExpCoeffY)
+
+
+def ReadChuckThermoValue(Unit:str=""):
+    """
+    Read the current temperature (either set or calculated) for the thermal scaling.
+    With SetChuckThermoScale in use, the value will be calculated by the current
+    scale and the expansion factor of silicium. The temperature that is read with
+    this command is not identical to the current chuck temperature.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        Temperature:Decimal
+        ExpCoeffX:Decimal
+        ExpCoeffY:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckThermoValue C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckThermoValue",Unit)
+    global ReadChuckThermoValue_Response
+    if not "ReadChuckThermoValue_Response" in globals(): ReadChuckThermoValue_Response = namedtuple("ReadChuckThermoValue_Response", "Temperature,ExpCoeffX,ExpCoeffY")
+    return ReadChuckThermoValue_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetChuckTableID(TableName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return the TableID Number of the stored chuck table or create a new table. The
+    ID Number is unique for the name and the chuck. The table itself has a string
+    name, this name is not case sensitive. This command has to be used before all
+    other table commands can be used. Accesses to the table is possible only with an
+    ID Number (name dependet).
+    API Status: internal
+    Args:
+        TableName:str = "ChuckTable"
+    Returns:
+        TableID:int
+    Command Timeout: 5000
+    Example:GetChuckTableID ChuckTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetChuckTableID",TableName)
+    return int(rsp[0])
+
+def MoveChuckTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move the chuck to the next stored table site.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveChuckTablePoint 3 10 67
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckTablePoint",TableID,PointID,Velocity)
+
+
+def ReadChuckTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read back the table site information for this point from the Kernel.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadChuckTablePoint 10 250 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckTablePoint",TableID,PointID,Unit)
+    global ReadChuckTablePoint_Response
+    if not "ReadChuckTablePoint_Response" in globals(): ReadChuckTablePoint_Response = namedtuple("ReadChuckTablePoint_Response", "CoordX,CoordY,CoordSystem")
+    return ReadChuckTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetChuckTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set one point of the chuck table inside of the Kernel. If there is still a point
+    with this index loaded, the Kernel returns an error. Number of positions and
+    number of tables are dependet on the internal memory. All positions are stored
+    persistent, that means after switching power on or off the positions are still
+    available. The table starts with point number 1 and ends with the ID 16. The
+    table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetChuckTablePoint 10 12000.0 2344.0 Y F
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetChuckTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    return int(rsp[0])
+
+def ClearChuckTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of chuck table site points in the in the Kernel. If Start
+    Point is -1 or negative the whole table will be deleted.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearChuckTablePoint 5 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearChuckTablePoint",TableID,StartPoint,EndPoint)
+    global ClearChuckTablePoint_Response
+    if not "ClearChuckTablePoint_Response" in globals(): ClearChuckTablePoint_Response = namedtuple("ClearChuckTablePoint_Response", "ClearNumber,ValidNumber")
+    return ClearChuckTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def AttachAmbientWafer(MoveTimeMs:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is moved to slowly attach a wafer that is at ambient temperature while
+    the chuck is hot.     The command acts similar to MoveChuckTransfer when moving
+    out of Load 2 but will use a much slower Z velocity.     This is only supported
+    for BnR-machines (CM300 and Summit200) at the moment.
+    API Status: internal
+    Args:
+        MoveTimeMs:Decimal = 30000
+    Command Timeout: 300000
+    Example:AttachAmbientWafer
+    """
+    MessageServerInterface.sendSciCommand("AttachAmbientWafer",MoveTimeMs)
+
+
+def ReadThetaStatus():
+    """
+    Returns the actual status of the chuck Theta axis.
+    API Status: published
+    Returns:
+        IsInit:int
+        FlagsLimit:int
+        IsMoving:int
+    Command Timeout: 5000
+    Example:ReadThetaStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadThetaStatus")
+    global ReadThetaStatus_Response
+    if not "ReadThetaStatus_Response" in globals(): ReadThetaStatus_Response = namedtuple("ReadThetaStatus_Response", "IsInit,FlagsLimit,IsMoving")
+    return ReadThetaStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadThetaPosition(Unit:str="", PosRef:str=""):
+    """
+    Returns the actual Theta position.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+        PosRef:str = "Home"
+    Returns:
+        Position:Decimal
+    Command Timeout: 5000
+    Example:ReadThetaPosition D Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadThetaPosition",Unit,PosRef)
+    return Decimal(rsp[0])
+
+def InitTheta(FlagsDoPlus:int="", FlagsMoveRange:int=""):
+    """
+    Performs an initialization move and resets the coordinate system of the Theta
+    axis.
+    API Status: published
+    Args:
+        FlagsDoPlus:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 120000
+    Example:InitTheta 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitTheta",FlagsDoPlus,FlagsMoveRange)
+
+
+def MoveTheta(Position:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck Theta axis to the specified position. The positive direction is
+    counter-clockwise.
+    API Status: published
+    Args:
+        Position:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Degrees"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveTheta 1000. R E
+    """
+    MessageServerInterface.sendSciCommand("MoveTheta",Position,PosRef,Unit,Velocity)
+
+
+def MoveThetaVelocity(Polarity:str="", Velocity:Decimal=""):
+    """
+    Moves the chuck Theta axis in velocity mode. The positive direction is counter-
+    clockwise. The motion continues until the StopThetaMovement command is received,
+    or the end limit (error condition) is reached. This command is mostly used for
+    joystick movements that do not have a target destination.
+    API Status: published
+    Args:
+        Polarity:str = "Fixed"
+        Velocity:Decimal = 0
+    Command Timeout: 240000
+    Example:MoveThetaVelocity + 67
+    """
+    MessageServerInterface.sendSciCommand("MoveThetaVelocity",Polarity,Velocity)
+
+
+def StopThetaMovement():
+    """
+    Stops any type (velocity, position etc.) of chuck Theta axis movement. This is
+    treated as a smooth stop rather than an emergency stop.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopThetaMovement
+    """
+    MessageServerInterface.sendSciCommand("StopThetaMovement")
+
+
+def SetThetaHome(Mode:str="", Unit:str="", Position:Decimal=""):
+    """
+    Sets the chuck Theta position to home. This position is usable as reference
+    position for other commands.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Degrees"
+        Position:Decimal = 0
+    Command Timeout: 5000
+    Example:SetThetaHome 0
+    """
+    MessageServerInterface.sendSciCommand("SetThetaHome",Mode,Unit,Position)
+
+
+def ScanChuckZ(ZDistance:Decimal="", TriggerEveryNthCycle:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts moving the chuck from the current position with Velocity [%] over
+    ZDistance (sign is important, as a negative sign will move chuck down during
+    scan) - Predefined camera trigger pulses (TTL active high for at least 5us) will
+    be sent during the scan every passed number of BnR cyclics (800us per cyclic)
+    until the ZDistance has been reached.  Command returns number of positions and
+    all compensated Z Positions from Zero, where the trigger was sent.
+    API Status: internal
+    Args:
+        ZDistance:Decimal = 1000
+        TriggerEveryNthCycle:int = 3
+        Velocity:Decimal = 10
+    Returns:
+        NumberOfPositions:int
+        TriggerPositions:str
+    Command Timeout: 60000
+    Example:ScanChuckZ 300 3 1.5
+    """
+    rsp = MessageServerInterface.sendSciCommand("ScanChuckZ",ZDistance,TriggerEveryNthCycle,Velocity)
+    global ScanChuckZ_Response
+    if not "ScanChuckZ_Response" in globals(): ScanChuckZ_Response = namedtuple("ScanChuckZ_Response", "NumberOfPositions,TriggerPositions")
+    return ScanChuckZ_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def MoveChuckZSafe():
+    """
+    Moves the chuck Z axis to a z height considered safe. This is either the lower
+    Z-Fence or the kernel setup item Chuck:SafeTransferHeight (which ever is larger)
+    API Status: published
+    Command Timeout: 60000
+    Example:MoveChuckZSafe
+    """
+    MessageServerInterface.sendSciCommand("MoveChuckZSafe")
+
+
+def SetPlatenMode(Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The mode manages the way the platen behaves when it is in contact height. Platen
+    mode is made up from 5 flags and the user can control all of them by using this
+    command. Every flag can be turned on by setting value 1 or turned off by setting
+    value 0. If no change for a flag is wanted, use the value of 2.
+    API Status: internal
+    Args:
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        AutoZFollow:int = 2
+        AutoQuiet:int = 2
+    Command Timeout: 5000
+    Example:SetPlatenMode 2 2 2 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetPlatenMode",Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+
+
+def MovePlatenLift(SetLift:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen to the high (0) or low = lifted (1) position. This initiates
+    motion; the actual movement may take some seconds.
+    API Status: internal
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MovePlatenLift 1
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenLift",SetLift)
+
+
+def SearchPlatenContact(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", CompLayer:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Searches contact height using the edge sensor using a z movement of the platen
+    stage
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        CompLayer:str = "Default"
+    Returns:
+        ContactHeight:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SearchPlatenContact",Height,PosRef,Unit,Velocity,CompLayer)
+    return Decimal(rsp[0])
+
+def ReadPlatenStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current platen status.
+    API Status: internal
+    Returns:
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        PresetHeight:str
+        IsLiftDown:int
+    Command Timeout: 10000
+    Example:ReadPlatenStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenStatus")
+    global ReadPlatenStatus_Response
+    if not "ReadPlatenStatus_Response" in globals(): ReadPlatenStatus_Response = namedtuple("ReadPlatenStatus_Response", "FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,PresetHeight,IsLiftDown")
+    return ReadPlatenStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ReadPlatenPosition(Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the platens X, Y and Z axes. The default
+    compensation is the currently selected compensation for the stage.
+    API Status: internal
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 10000
+    Example:ReadPlatenPosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenPosition",Unit,PosRef,Comp)
+    global ReadPlatenPosition_Response
+    if not "ReadPlatenPosition_Response" in globals(): ReadPlatenPosition_Response = namedtuple("ReadPlatenPosition_Response", "X,Y,Z")
+    return ReadPlatenPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadPlatenHeights(Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual settings for the probe Z movement.
+    API Status: internal
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 10000
+    Example:ReadPlatenHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadPlatenHeights",Unit)
+    global ReadPlatenHeights_Response
+    if not "ReadPlatenHeights_Response" in globals(): ReadPlatenHeights_Response = namedtuple("ReadPlatenHeights_Response", "Contact,Overtravel,AlignDist,SepDist")
+    return ReadPlatenHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def InitPlaten(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initializes the platens X, Y and Z axes. Currently the initialization in
+    negative direction and the move range scan are not supported.
+    API Status: internal
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 120000
+    Example:InitPlaten 4
+    """
+    MessageServerInterface.sendSciCommand("InitPlaten",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MovePlatenZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the specified height. If contact is set, only moves
+    up to contact height will be allowed. If overtravel is enabled - up to
+    overtravel height.
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 30000
+    Example:MovePlatenZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def MovePlatenContact(Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a movement of platen Z axis to preset contact height or returns an
+    error, if no contact height is set.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenContact 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenContact",Velocity)
+
+
+def MovePlatenAlign(Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the align height. If no contact height is set, the
+    command will return an error.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenAlign",Velocity)
+
+
+def MovePlatenSeparation(Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen Z axis to the separation height. If no contact height is set,
+    the command will return an error.
+    API Status: internal
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MovePlatenSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenSeparation",Velocity)
+
+
+def MovePlatenVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the platen stage in velocity mode. The motion continues until the
+    StopPlatenMovement command is received, or the software fence is reached.
+    API Status: internal
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 240000
+    Example:MovePlatenVelocity + + 0 67 50 0
+    """
+    MessageServerInterface.sendSciCommand("MovePlatenVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopPlatenMovement(FlagsStop:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the movement of a set of platen axes immediately.
+    API Status: internal
+    Args:
+        FlagsStop:int = 7
+    Command Timeout: 10000
+    Example:StopPlatenMovement 4
+    """
+    MessageServerInterface.sendSciCommand("StopPlatenMovement",FlagsStop)
+
+
+def SetPlatenHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align and separation height. A command without data sets contact height at
+    current position.
+    API Status: internal
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 10000
+    Example:SetPlatenHeight C V Y 5000
+    """
+    MessageServerInterface.sendSciCommand("SetPlatenHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadManualPlatenState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads the current status of the manual platen. THis is only supported for
+    Nucleus and Summit200.
+    API Status: internal
+    Returns:
+        IsUp:int
+        IsDown:int
+        IsSafe:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadManualPlatenState")
+    global ReadManualPlatenState_Response
+    if not "ReadManualPlatenState_Response" in globals(): ReadManualPlatenState_Response = namedtuple("ReadManualPlatenState_Response", "IsUp,IsDown,IsSafe")
+    return ReadManualPlatenState_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def ReadScopeStatus():
+    """
+    Returns the current scope status.
+    API Status: published
+    Returns:
+        FlagsInit:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        IsScopeLiftUp:int
+        PresetHeight:str
+        IsScopeLight:int
+        FlagsMode:int
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadScopeStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeStatus")
+    global ReadScopeStatus_Response
+    if not "ReadScopeStatus_Response" in globals(): ReadScopeStatus_Response = namedtuple("ReadScopeStatus_Response", "FlagsInit,FlagsLimit,FlagsMoving,Comp,IsScopeLiftUp,PresetHeight,IsScopeLight,FlagsMode,IsQuiet")
+    return ReadScopeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),str(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def ReadScopePosition(Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the actual scope stage position in X, Y and Z. The default Compensation
+    Mode is the currently activated compensation mode of the kernel.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadScopePosition Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopePosition",Unit,PosRef,Comp)
+    global ReadScopePosition_Response
+    if not "ReadScopePosition_Response" in globals(): ReadScopePosition_Response = namedtuple("ReadScopePosition_Response", "X,Y,Z")
+    return ReadScopePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeHeights(Unit:str=""):
+    """
+    Returns the actual settings of the focus height, align gap, and separation gap
+    for the scope Z axis.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        FocusHeight:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeHeights Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeHeights",Unit)
+    global ReadScopeHeights_Response
+    if not "ReadScopeHeights_Response" in globals(): ReadScopeHeights_Response = namedtuple("ReadScopeHeights_Response", "FocusHeight,AlignDist,SepDist")
+    return ReadScopeHeights_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def InitScope(FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int=""):
+    """
+    Initializes the microscope stage in X, Y and Z. The Axis default is all axes and
+    the Direction default is XY in minus and Z in plus. Should be used only in cases
+    when the reported coordinates do not correspond to real position of mechanics.
+    Find Move Range starts the initialization in the defined direction and then
+    moves to the other limit and finds the whole range of the axes.
+    API Status: published
+    Args:
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+    Command Timeout: 240000
+    Example:InitScope 3 0 0
+    """
+    MessageServerInterface.sendSciCommand("InitScope",FlagsInit,FlagsDirection,FlagsMoveRange)
+
+
+def MoveScope(XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 70000
+    Example:MoveScope 5000 5000 R Y 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScope",XValue,YValue,PosRef,Unit,Velocity,Comp)
+
+
+def MoveScopeIndex(XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+    """
+    Moves the microscope stage in index steps. If no PositionReference byte is
+    passed the scope will step relative to the wafer home position. ('R' means the
+    step relative to current position).
+    API Status: published
+    Args:
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveScopeIndex 1 1 R 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeIndex",XSteps,YSteps,PosRef,Velocity)
+
+
+def MoveScopeZ(Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves the microscope Z axis to the specified height. Default velocity is 100%.
+    API Status: published
+    Args:
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Command Timeout: 120000
+    Example:MoveScopeZ 1000. R Y 67
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeZ",Height,PosRef,Unit,Velocity,Comp)
+
+
+def SetScopeMode(QuietMode:int="", FollowMode:int=""):
+    """
+    Scope mode is made up of two flags which can be controlled using this command.
+    Each flag can be turned on by using value 1 or turned off by using value 0. If
+    you do not want to change a flag, use value of 2.
+    API Status: published
+    Args:
+        QuietMode:int = 2
+        FollowMode:int = 2
+    Command Timeout: 5000
+    Example:SetScopeMode 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetScopeMode",QuietMode,FollowMode)
+
+
+def MoveScopeVelocity(PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    Moves the microscope stage in velocity mode. The motion continues until the
+    StopScopeMovement command is received, or the end limit (error condition) is
+    reached. Axes parameter: '+' move this axis in plus direction '-' move this axis
+    in minus direction '0' Do not change this axis
+    API Status: published
+    Args:
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Command Timeout: 30000
+    Example:MoveScopeVelocity + + 0 67 100 0
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeVelocity",PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+
+
+def StopScopeMovement(FlagsStop:int=""):
+    """
+    Stops scope movement for the given axis. A smooth stop is executed, no emergency
+    stop.
+    API Status: published
+    Args:
+        FlagsStop:int = 7
+    Command Timeout: 5000
+    Example:StopScopeMovement 7
+    """
+    MessageServerInterface.sendSciCommand("StopScopeMovement",FlagsStop)
+
+
+def SetScopeHome(Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets the scope Home position in X and Y. It identifies the scope coordinate
+    system for later movements. Usually this position is identical to the die home
+    location.
+    API Status: published
+    Args:
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeHome 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeHome",Mode,Unit,XValue,YValue)
+
+
+def SetScopeIndex(XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the microscope index size. Normally set in relation to the wafer index
+    size.
+    API Status: published
+    Args:
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Command Timeout: 5000
+    Example:SetScopeIndex 5000. 5000. Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeIndex",XValue,YValue,Unit)
+
+
+def SetScopeHeight(PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    This command defines scope focus height and the corresponding gaps for alignment
+    or separation. No data sets focus height at current position.
+    API Status: published
+    Args:
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeHeight F 0 Y
+    """
+    MessageServerInterface.sendSciCommand("SetScopeHeight",PresetHeight,Mode,Unit,Value)
+
+
+def ReadScopeIndex(Unit:str=""):
+    """
+    Returns the actual scope stage index values in X and Y.
+    API Status: published
+    Args:
+        Unit:str = "Microns"
+    Returns:
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeIndex Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeIndex",Unit)
+    global ReadScopeIndex_Response
+    if not "ReadScopeIndex_Response" in globals(): ReadScopeIndex_Response = namedtuple("ReadScopeIndex_Response", "IndexX,IndexY")
+    return ReadScopeIndex_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def MoveScopeFocus(Velocity:Decimal=""):
+    """
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 25000
+    Example:MoveScopeFocus 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeFocus",Velocity)
+
+
+def MoveScopeAlign(Velocity:Decimal=""):
+    """
+    Moves the Scope Z axis to the alignment height. If no focus height is set an
+    error will bereturned.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 10000
+    Example:MoveScopeAlign 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeAlign",Velocity)
+
+
+def MoveScopeSeparation(Velocity:Decimal=""):
+    """
+    Moves the scope Z axis to the separation height. Returns an error if no focus
+    height is set.
+    API Status: published
+    Args:
+        Velocity:Decimal = 100
+    Command Timeout: 60000
+    Example:MoveScopeSeparation 100
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeSeparation",Velocity)
+
+
+def MoveScopeLift(SetLift:int=""):
+    """
+    Moves the microscope lift to the lower (0) or upper = lifted (1) position. This
+    initiates the motion only, the actual movement may take some seconds.
+    API Status: published
+    Args:
+        SetLift:int = 1
+    Command Timeout: 10000
+    Example:MoveScopeLift 1
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeLift",SetLift)
+
+
+def ReadTurretStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current status of the motorized turret.
+    API Status: internal
+    Returns:
+        IsMoving:int
+    Command Timeout: 5000
+    Example:ReadTurretStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTurretStatus")
+    return int(rsp[0])
+
+def SelectLens(Lens:int=""):
+    """
+    Parfocality and para-centricity are adjusted according to the stored values.
+    This can be used with manual turrets to compensate for XYZ differences between
+    lenses.
+    API Status: published
+    Args:
+        Lens:int = 1
+    Command Timeout: 30000
+    Example:SelectLens 1
+    """
+    MessageServerInterface.sendSciCommand("SelectLens",Lens)
+
+
+def GetScopeTable(TableName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return the TableID Number of the stored chuck table or create a new table. The
+    ID Number is unique for the name and the chuck. The table itself has a string
+    name, this name is not case sensitive. This command has to be used before all
+    other table commands can be used. Accesses to the table is possible only with an
+    ID Number (name dependet).
+    API Status: internal
+    Args:
+        TableName:str = "ScopeTable"
+    Returns:
+        TableID:int
+    Command Timeout: 5000
+    Example:GetScopeTable ScopeTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetScopeTable",TableName)
+    return int(rsp[0])
+
+def MoveScopeTablePoint(TableID:int="", PointID:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the microscope stage to the specified X,Y position relative to the per
+    PosRef specified reference position.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Velocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveScopeTablePoint 10 5 67
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeTablePoint",TableID,PointID,Velocity)
+
+
+def ReadScopeTablePoint(TableID:int="", PointID:int="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read back the scope table site Information for this point from the Kernel.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadScopeTablePoint 2 10 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeTablePoint",TableID,PointID,Unit)
+    global ReadScopeTablePoint_Response
+    if not "ReadScopeTablePoint_Response" in globals(): ReadScopeTablePoint_Response = namedtuple("ReadScopeTablePoint_Response", "CoordX,CoordY,CoordSystem")
+    return ReadScopeTablePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def ReadCurrentLens():
+    """
+    Returns the number of the current microscope lens.
+    API Status: published
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    Example:ReadCurrentLens
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCurrentLens")
+    return int(rsp[0])
+
+def SetScopeTablePoint(TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set one point of the scope table inside of the Kernel. If there is still a point
+    with this index loaded, the Kernel returns an error. Number of positions and
+    number of tables are dependet on the internal memory. All positions are stored
+    persistent, that means after switching power on or off the positions are still
+    available. The table starts with point number 1 and ends with the ID 16. The
+    table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetScopeTablePoint 10 10 8992.5 7883.0 Y H
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetScopeTablePoint",TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    return int(rsp[0])
+
+def ClearScopeTablePoint(TableID:int="", StartPoint:int="", EndPoint:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of scope table site points in the Kernel. If Start Point is
+    -1 or negative the whole table will be deleted.
+    API Status: internal
+    Args:
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearScopeTablePoint 2 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearScopeTablePoint",TableID,StartPoint,EndPoint)
+    global ClearScopeTablePoint_Response
+    if not "ClearScopeTablePoint_Response" in globals(): ClearScopeTablePoint_Response = namedtuple("ClearScopeTablePoint_Response", "ClearNumber,ValidNumber")
+    return ClearScopeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadScopeSiloCount():
+    """
+    Returns the number of silos in the scope fence. Will be zero if no silos are
+    configured.
+    API Status: published
+    Returns:
+        Count:int
+    Command Timeout: 5000
+    Example:ReadScopeSiloCount
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSiloCount")
+    return int(rsp[0])
+
+def ReadProbeStatus(Probe:int=""):
+    """
+    Returns the current positioner's status.
+    API Status: published
+    Args:
+        Probe:int = 1
+    Returns:
+        ProbeEcho:int
+        FlagsInit:int
+        FlagsMode:int
+        FlagsLimit:int
+        FlagsMoving:int
+        Comp:str
+        Side:str
+        PresetHeight:str
+        IsLiftUp:int
+        IsQuiet:int
+    Command Timeout: 5000
+    Example:ReadProbeStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeStatus",Probe)
+    global ReadProbeStatus_Response
+    if not "ReadProbeStatus_Response" in globals(): ReadProbeStatus_Response = namedtuple("ReadProbeStatus_Response", "ProbeEcho,FlagsInit,FlagsMode,FlagsLimit,FlagsMoving,Comp,Side,PresetHeight,IsLiftUp,IsQuiet")
+    return ReadProbeStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str(rsp[5]),str(rsp[6]),str(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadProbePosition(Probe:int="", Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the actual positioner's position in X, Y and Z. The default Compensation
+    Mode is the currently activated compensation mode of the kernel.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadProbePosition 1 Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbePosition",Probe,Unit,PosRef,Comp)
+    global ReadProbePosition_Response
+    if not "ReadProbePosition_Response" in globals(): ReadProbePosition_Response = namedtuple("ReadProbePosition_Response", "ProbeEcho,X,Y,Z")
+    return ReadProbePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadProbeHeights(Probe:int="", Unit:str=""):
+    """
+    Returns the actual settings for the probe Z movement.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeHeights 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeHeights",Probe,Unit)
+    global ReadProbeHeights_Response
+    if not "ReadProbeHeights_Response" in globals(): ReadProbeHeights_Response = namedtuple("ReadProbeHeights_Response", "ProbeEcho,Contact,Overtravel,AlignDist,SepDist")
+    return ReadProbeHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def OrientProbe(Probe:int="", Side:str=""):
+    """
+    Defines the orientation of the positioner's coordinate system and turns the
+    Y-axis of the probe coordinate system.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Side:str = "Left"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:OrientProbe 1 R
+    """
+    rsp = MessageServerInterface.sendSciCommand("OrientProbe",Probe,Side)
+    return int(rsp[0])
+
+def InitProbe(Probe:int="", FlagsInit:int="", FlagsDirection:int="", FlagsMoveRange:int="", FlagsInitInPlace:int=""):
+    """
+    Performs an initialization move and resets the coordinate system of the given
+    positioner.
+    API Status: published
+    Args:
+        Probe:int = 1
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsMoveRange:int = 0
+        FlagsInitInPlace:int = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 120000
+    Example:InitProbe 1 7 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("InitProbe",Probe,FlagsInit,FlagsDirection,FlagsMoveRange,FlagsInitInPlace)
+    return int(rsp[0])
+
+def MoveProbe(Probe:int="", XValue:Decimal="", YValue:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbe 1 1000. 1000. R Y 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbe",Probe,XValue,YValue,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def MoveProbeIndex(Probe:int="", XSteps:int="", YSteps:int="", PosRef:str="", Velocity:Decimal=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        XSteps:int = 0
+        YSteps:int = 0
+        PosRef:str = "Home"
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeIndex 1 1 1 R 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeIndex",Probe,XSteps,YSteps,PosRef,Velocity)
+    return int(rsp[0])
+
+def MoveProbeContact(Probe:int="", Velocity:Decimal=""):
+    """
+    Moves the given ProbeHeads Z axis to the preset contact height. If no contact
+    height is set, the kernel will return a 'Contact height not set' error.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeContact 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeContact",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeAlign(Probe:int="", Velocity:Decimal=""):
+    """
+    Moves the given ProbeHeads Z axis to the align height.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeAlign 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeAlign",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeSeparation(Probe:int="", Velocity:Decimal=""):
+    """
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: published
+    Args:
+        Probe:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeSeparation 1 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeSeparation",Probe,Velocity)
+    return int(rsp[0])
+
+def MoveProbeZ(Probe:int="", Height:Decimal="", PosRef:str="", Unit:str="", Velocity:Decimal="", Comp:str=""):
+    """
+    Moves a given ProbeHeads Z axis to a defined Z height.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Height:Decimal = 0
+        PosRef:str = "Zero"
+        Unit:str = "Microns"
+        Velocity:Decimal = 100
+        Comp:str = "Default"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeZ 1 1000. R Y 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeZ",Probe,Height,PosRef,Unit,Velocity,Comp)
+    return int(rsp[0])
+
+def MoveProbeLift(Probe:int="", SetLift:int=""):
+    """
+    Moves the positioner to the lower (0) or upper = lifted (1) position. The
+    command initiates the motion only, the whole movement may take some seconds.
+    API Status: published
+    Args:
+        Probe:int = 1
+        SetLift:int = 1
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 10000
+    Example:MoveProbeLift 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeLift",Probe,SetLift)
+    return int(rsp[0])
+
+def MoveProbeVelocity(Probe:int="", PolarityX:str="", PolarityY:str="", PolarityZ:str="", VelocityX:Decimal="", VelocityY:Decimal="", VelocityZ:Decimal=""):
+    """
+    '+' Move this axis into plus direction '-' Move this axis into minus direction
+    '0' Do not change this axis
+    API Status: published
+    Args:
+        Probe:int = 1
+        PolarityX:str = "Fixed"
+        PolarityY:str = "Fixed"
+        PolarityZ:str = "Fixed"
+        VelocityX:Decimal = 100
+        VelocityY:Decimal = 0
+        VelocityZ:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeVelocity 1 + + Z 67 100 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeVelocity",Probe,PolarityX,PolarityY,PolarityZ,VelocityX,VelocityY,VelocityZ)
+    return int(rsp[0])
+
+def StopProbeMovement(Probe:int="", FlagsStop:int=""):
+    """
+    Stops positioner movement for the given axes immediately. A smooth stop is
+    performed.
+    API Status: published
+    Args:
+        Probe:int = 1
+        FlagsStop:int = 7
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:StopProbeMovement 1 7
+    """
+    rsp = MessageServerInterface.sendSciCommand("StopProbeMovement",Probe,FlagsStop)
+    return int(rsp[0])
+
+def SetProbeMode(Probe:int="", Overtravel:int="", AutoZ:int="", Interlock:int="", AutoZFollow:int="", AutoQuiet:int=""):
+    """
+    The mode manages the way the chuck behaves when it is in contact height.
+    Positioner mode is made up from 5 flags and the user can control all of them by
+    using this command. Every flag can be turned on by setting value 1, or turned
+    off by setting value 0. Use the value 2 if no change for a flag is needed.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Overtravel:int = 2
+        AutoZ:int = 2
+        Interlock:int = 2
+        AutoZFollow:int = 2
+        AutoQuiet:int = 2
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeMode 1 2 2 2 2
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeMode",Probe,Overtravel,AutoZ,Interlock,AutoZFollow,AutoQuiet)
+    return int(rsp[0])
+
+def SetProbeHome(Probe:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets the positioner's Home position in X and Y. This position identifies the
+    probe coordinate system for later movements. Usually this position is identical
+    to the die home position.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeHome 1 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeHome",Probe,Mode,Unit,XValue,YValue)
+    return int(rsp[0])
+
+def SetProbeIndex(Probe:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the positioner's index size or the location of the reference die relative
+    to the home die.
+    API Status: published
+    Args:
+        Probe:int = 1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeIndex 1 1000. 1000. Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeIndex",Probe,XValue,YValue,Unit)
+    return int(rsp[0])
+
+def SetProbeHeight(Probe:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    Defines the predefined contact height and corresponding gaps for overtravel,
+    align, load and separation height. No data sets contact height at current
+    position.
+    API Status: published
+    Args:
+        Probe:int = 1
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 5000
+    Example:SetProbeHeight 1 C 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeHeight",Probe,PresetHeight,Mode,Unit,Value)
+    return int(rsp[0])
+
+def ReadProbeIndex(Probe:int="", Unit:str=""):
+    """
+    Returns the current positioner's wafer index values or the current positioner's
+    index positions for X and Y.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeIndex 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeIndex",Probe,Unit)
+    global ReadProbeIndex_Response
+    if not "ReadProbeIndex_Response" in globals(): ReadProbeIndex_Response = namedtuple("ReadProbeIndex_Response", "ProbeEcho,IndexX,IndexY")
+    return ReadProbeIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetProbeLED(Probe:int="", NewLEDState:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the positioner LED On or Off.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        NewLEDState:int = 0
+    Returns:
+        ProbeEcho:int
+        LEDState:int
+    Command Timeout: 5000
+    Example:SetProbeLED 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeLED",Probe,NewLEDState)
+    global SetProbeLED_Response
+    if not "SetProbeLED_Response" in globals(): SetProbeLED_Response = namedtuple("SetProbeLED_Response", "ProbeEcho,LEDState")
+    return SetProbeLED_Response(int(rsp[0]),int(rsp[1]))
+
+def GetProbeTableID(Probe:int="", TableName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the ID of a stored probe table or creates a new table. The ID is unique
+    for the name and the probe. The table itself has a string name. This name is not
+    case sensitive. The command has to be used before all other table commands can
+    be used. Access to tables is possible only with an ID Number (name dependent).
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableName:str = "ProbeTable"
+    Returns:
+        ProbeEcho:int
+        TableID:int
+    Command Timeout: 5000
+    Example:GetProbeTableID 1 ProbeTable
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProbeTableID",Probe,TableName)
+    global GetProbeTableID_Response
+    if not "GetProbeTableID_Response" in globals(): GetProbeTableID_Response = namedtuple("GetProbeTableID_Response", "ProbeEcho,TableID")
+    return GetProbeTableID_Response(int(rsp[0]),int(rsp[1]))
+
+def MoveProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves a defined positioner to a X, Y position relative to a per PosRef specified
+    reference position. Notifications: 51 / 52 / 5
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 1
+        PointID:int = 1
+        Velocity:Decimal = 100
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 30000
+    Example:MoveProbeTablePoint 3 14 10 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveProbeTablePoint",Probe,TableID,PointID,Velocity)
+    return int(rsp[0])
+
+def ReadProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads the data from a point of a stored table in the Kernel.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        PointID:int = 0
+        Unit:str = "Microns"
+    Returns:
+        ProbeEcho:int
+        CoordX:Decimal
+        CoordY:Decimal
+        CoordSystem:str
+    Command Timeout: 5000
+    Example:ReadProbeTablePoint 2 4 10 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeTablePoint",Probe,TableID,PointID,Unit)
+    global ReadProbeTablePoint_Response
+    if not "ReadProbeTablePoint_Response" in globals(): ReadProbeTablePoint_Response = namedtuple("ReadProbeTablePoint_Response", "ProbeEcho,CoordX,CoordY,CoordSystem")
+    return ReadProbeTablePoint_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetProbeTablePoint(Probe:int="", TableID:int="", PointID:int="", CoordX:Decimal="", CoordY:Decimal="", Unit:str="", CoordSystem:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets one point of a ProbeHeads table inside the Kernel. If there is still a
+    point with this index loaded, the Kernel returns an error. Number of positions
+    and number of tables are dependet on the internal memory. All positions are
+    stored persistent, that means after switching power on or off the positions are
+    still available. The table starts with point number 1 and ends with the ID 16.
+    The table can contain 65535 points with the ID 0 up to 65534. Overwriting of
+    position points is not possible. The point has to be deleted before other values
+    are set.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        PointID:int = 0
+        CoordX:Decimal = 0
+        CoordY:Decimal = 0
+        Unit:str = "Microns"
+        CoordSystem:str = "HomeSystem"
+    Returns:
+        ProbeEcho:int
+        ValidPoint:int
+    Command Timeout: 5000
+    Example:SetProbeTablePoint 3 12 10 8992.5 7883.0 Y Z M
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetProbeTablePoint",Probe,TableID,PointID,CoordX,CoordY,Unit,CoordSystem)
+    global SetProbeTablePoint_Response
+    if not "SetProbeTablePoint_Response" in globals(): SetProbeTablePoint_Response = namedtuple("SetProbeTablePoint_Response", "ProbeEcho,ValidPoint")
+    return SetProbeTablePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def ClearProbeTablePoint(Probe:int="", TableID:int="", StartPoint:int="", EndPoint:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clear one or a range of ProbeHead table site points in the Kernel. If StartPoint
+    is a negative value, the whole table will be deleted.
+    API Status: internal
+    Args:
+        Probe:int = 1
+        TableID:int = 0
+        StartPoint:int = -1
+        EndPoint:int = 0
+    Returns:
+        ProbeEcho:int
+        ClearNumber:int
+        ValidNumber:int
+    Command Timeout: 5000
+    Example:ClearProbeTablePoint 3 4 10 15
+    """
+    rsp = MessageServerInterface.sendSciCommand("ClearProbeTablePoint",Probe,TableID,StartPoint,EndPoint)
+    global ClearProbeTablePoint_Response
+    if not "ClearProbeTablePoint_Response" in globals(): ClearProbeTablePoint_Response = namedtuple("ClearProbeTablePoint_Response", "ProbeEcho,ClearNumber,ValidNumber")
+    return ClearProbeTablePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def MoveScopeSilo(Index:int=""):
+    """
+    Move the scope to the reference position of the given silo. The reference
+    position should be - if not defined otherwise - 200 um above the safe z-height
+    in the center of the scope.
+    API Status: published
+    Args:
+        Index:int = 1
+    Command Timeout: 70000
+    Example:MoveScopeSilo 1
+    """
+    MessageServerInterface.sendSciCommand("MoveScopeSilo",Index)
+
+
+def SetScopeSiloReference(Index:int="", X:Decimal="", Y:Decimal="", Z:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the reference position of a silo. The next time the scope moves to this
+    silo, it woll go to this position. The Referenceposition must be inside the silo
+    in xy and above the lower Z-Fence of the silo.  Setting the reference position
+    directly on the fence in x, y or z typically leads to errors. Try to keep a
+    safety margin.
+    API Status: internal
+    Args:
+        Index:int = 1
+        X:Decimal = 0
+        Y:Decimal = 0
+        Z:Decimal = 0
+    Command Timeout: 5000
+    Example:SetScopeSiloReference 1 1000 2000 3000
+    """
+    MessageServerInterface.sendSciCommand("SetScopeSiloReference",Index,X,Y,Z)
+
+
+def AlignChuckTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+    """
+    This command causes a chuck Theta axis rotation to align the wafer to the chuck
+    X,Y movements.     It can be used to perform a two point alignment with
+    P1(X1,Y1) and P2(X2,Y2) as two points on a wafer street line.     The units of
+    the distances are not important - but both distances should use the same unit.
+    If one or both distances are zero, the command does not return an error and
+    instead ignore this alignment
+    API Status: published
+    Args:
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignChuckTheta 10000 10 R
+    """
+    MessageServerInterface.sendSciCommand("AlignChuckTheta",XDistance,YDistance,PosRef)
+
+
+def AlignScopeTheta(XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+    """
+    This command causes a virtual rotation of the scope coordinate system to align
+    the scope to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+    perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+    Calculation of X and Y distances:
+    API Status: published
+    Args:
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignScopeTheta 10000 10 R
+    """
+    MessageServerInterface.sendSciCommand("AlignScopeTheta",XDistance,YDistance,PosRef)
+
+
+def AlignProbeTheta(Probe:int="", XDistance:Decimal="", YDistance:Decimal="", PosRef:str=""):
+    """
+    This command causes a rotation of the coordinate system of given probe to align
+    the probe to the chuck X,Y axis or/and to the wafer alignment. It can be used to
+    perform a two point alignment with the points P1(X1,Y1) and P2(X2,Y2).
+    Calculation of Y and Y distances:
+    API Status: published
+    Args:
+        Probe:int = 1
+        XDistance:Decimal = 0
+        YDistance:Decimal = 0
+        PosRef:str = "Relative"
+    Returns:
+        ProbeEcho:int
+    Command Timeout: 10000
+    Example:AlignProbeTheta 1 10000 10 R
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignProbeTheta",Probe,XDistance,YDistance,PosRef)
+    return int(rsp[0])
+
+def AlignCardTheta(Angle:Decimal="", Unit:str="", PosRef:str=""):
+    """
+    This command causes a rotation of the chuck coordinate system to align the chuck
+    X, Y axis to the probecard.     The polarity of the data determines a left or a
+    right rotation of the chuck coordinate system.
+    API Status: published
+    Args:
+        Angle:Decimal = 0
+        Unit:str = "Degrees"
+        PosRef:str = "Relative"
+    Command Timeout: 10000
+    Example:AlignCardTheta 2.5 D R
+    """
+    MessageServerInterface.sendSciCommand("AlignCardTheta",Angle,Unit,PosRef)
+
+
+def ReadCardTheta(Unit:str=""):
+    """
+    Returns the angle between the chuck-coordinate-system and the probecard-
+    coordinate-system.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadCardTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCardTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadChuckTheta(Unit:str=""):
+    """
+    Returns the current chuck alignment angle which is identical to the current
+    value of theta rotation.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadChuckTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadScopeTheta(Unit:str=""):
+    """
+    Returns the scope's alignment angle, which is the angle between the chuck
+    coordinate system and the scope coordinate system.
+    API Status: published
+    Args:
+        Unit:str = "Degrees"
+    Returns:
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeTheta D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeTheta",Unit)
+    return Decimal(rsp[0])
+
+def ReadProbeTheta(Probe:int="", Unit:str=""):
+    """
+    Returns the actual positioner's alignment angle, which is the angle between the
+    chuck coordinate system and the positioner coordinate system.
+    API Status: published
+    Args:
+        Probe:int = 1
+        Unit:str = "Degrees"
+    Returns:
+        ProbeEcho:int
+        Angle:Decimal
+    Command Timeout: 5000
+    Example:ReadProbeTheta 1 D
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeTheta",Probe,Unit)
+    global ReadProbeTheta_Response
+    if not "ReadProbeTheta_Response" in globals(): ReadProbeTheta_Response = namedtuple("ReadProbeTheta_Response", "ProbeEcho,Angle")
+    return ReadProbeTheta_Response(int(rsp[0]),Decimal(rsp[1]))
+
+def ReadJoystickSpeeds(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the preset speeds, which are used by the joystick controller for moving a
+    single stage. The speeds can be read for XY, for Z and for Theta axis
+    separately. Jog timing and index timing are the times, the joystick controller
+    waits between two single jog or index moves.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "X"
+    Returns:
+        JogTime:Decimal
+        Speed2:Decimal
+        Speed3:Decimal
+        Speed4:Decimal
+        IndexTime:Decimal
+    Command Timeout: 5000
+    Example:ReadJoystickSpeeds S Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeeds",Stage,Axis)
+    global ReadJoystickSpeeds_Response
+    if not "ReadJoystickSpeeds_Response" in globals(): ReadJoystickSpeeds_Response = namedtuple("ReadJoystickSpeeds_Response", "JogTime,Speed2,Speed3,Speed4,IndexTime")
+    return ReadJoystickSpeeds_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetJoystickSpeeds(Stage:str="", JogTime:Decimal="", Speed2:Decimal="", Speed3:Decimal="", Speed4:Decimal="", IndexTime:Decimal="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the preset speeds, which are used by the joystick controller for moving a
+    single stage. After setting, the speeds can be selected by pressing the Speed n
+    buttons at the controller. The speeds must be set separately for XY, for Z and
+    for Theta axis. Jog timing and index timing are the times, the joystick
+    controller waits between two single jog or index moves.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        JogTime:Decimal = 0
+        Speed2:Decimal = 0
+        Speed3:Decimal = 0
+        Speed4:Decimal = 0
+        IndexTime:Decimal = 0
+        Axis:str = "X"
+    Command Timeout: 5000
+    Example:SetJoystickSpeeds S 10 20 30 40 50 Z
+    """
+    MessageServerInterface.sendSciCommand("SetJoystickSpeeds",Stage,JogTime,Speed2,Speed3,Speed4,IndexTime,Axis)
+
+
+def SetLoaderGate(Open:int=""):
+    """
+    Opens or closes the loader gate. Automatic handling systems can load wafers to
+    the chuck through the gate.
+    API Status: published
+    Args:
+        Open:int = 0
+    Command Timeout: 5000
+    Example:SetLoaderGate 0
+    """
+    MessageServerInterface.sendSciCommand("SetLoaderGate",Open)
+
+
+def ReadWaferStatus():
+    """
+    Returns whether the system detected a wafer. This feature can be used if the
+    probe station is equipped with a vacuum sensor and while vacuum is activated.
+    API Status: published
+    Returns:
+        SensedByVac:str
+    Command Timeout: 5000
+    Example:ReadWaferStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadWaferStatus")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadContactCount(Stage:str=""):
+    """
+    Returns the number of times this stage moved to contact since the last time the
+    counter was reset.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        Count:int
+    Command Timeout: 5000
+    Example:ReadContactCount C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadContactCount",Stage)
+    return int(rsp[0])
+
+def ResetContactCount(Stage:str=""):
+    """
+    Resets the contact counter for the specified stage to zero. Notifications: 23
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Command Timeout: 5000
+    Example:ResetContactCount C
+    """
+    MessageServerInterface.sendSciCommand("ResetContactCount",Stage)
+
+
+def SetManualMode(Enable:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command enables the manual mode on Elite/Summit/S300 systems. This mode
+    will allow to move the chuck using the knobs.
+    API Status: internal
+    Args:
+        Enable:int = 1
+    Command Timeout: 10000
+    Example:SetManualMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetManualMode",Enable)
+
+
+def GetManualMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns the state of the manual mode on Elite/Summit/S300 stations.
+    API Status: internal
+    Returns:
+        Enable:int
+    Command Timeout: 10000
+    Example:GetManualMode 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetManualMode")
+    return int(rsp[0])
+
+def GetAxisReverse(Stage:str="", Axis:str=""):
+    """
+    Allows reading if an axis is reverse.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        IsReverse:int
+    Command Timeout: 5000
+    Example:GetAxisReverse C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAxisReverse",Stage,Axis)
+    return int(rsp[0])
+
+def EnableEdgeSensor(EdgeSensor:int="", Enable:int=""):
+    """
+    Enables/disables the use of an edge sensor.
+    API Status: published
+    Args:
+        EdgeSensor:int = 1
+        Enable:int = 1
+    Command Timeout: 5000
+    Example:EnableEdgeSensor 1 1
+    """
+    MessageServerInterface.sendSciCommand("EnableEdgeSensor",EdgeSensor,Enable)
+
+
+def SetTypedOutput(Channel:str="", WantOutputOn:int="", PulseTime:int=""):
+    """
+    Controls the kernel valve driver signals and can be used to drive the outputs.
+    API Status: published
+    Args:
+        Channel:str = "NoSensor"
+        WantOutputOn:int = 0
+        PulseTime:int = -1
+    Command Timeout: 5000
+    Example:SetTypedOutput WaferVacuum 1
+    """
+    MessageServerInterface.sendSciCommand("SetTypedOutput",Channel,WantOutputOn,PulseTime)
+
+
+def ReadTypedSensor(Channel:str=""):
+    """
+    Returns the status of the specified input channel, output channel, or edge
+    sensor.
+    API Status: published
+    Args:
+        Channel:str = "NoSensor"
+    Returns:
+        IsSensorOn:int
+    Command Timeout: 10000
+    Example:ReadTypedSensor EmoIn I
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTypedSensor",Channel)
+    return int(rsp[0])
+
+def MoveCoolDownPosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck to the cool down position that is defined in KernelSetup. The
+    cooldown position is used to move the chuck away in XY while the robot is in the
+    chamber and tries to get a hot wafer.
+    API Status: internal
+    Command Timeout: 30000
+    Example:MoveCoolDownPosition
+    """
+    MessageServerInterface.sendSciCommand("MoveCoolDownPosition")
+
+
+def ReadJoystickSpeedsCycle(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the cycling speeds - these are the speeds that are used by
+    the USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        CycleJog:int
+        CycleSpeed2:int
+        CycleSpeed3:int
+        CycleSpeed4:int
+        CycleIndex:int
+    Command Timeout: 5000
+    Example:ReadJoystickSpeedsCycle S
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadJoystickSpeedsCycle",Stage)
+    global ReadJoystickSpeedsCycle_Response
+    if not "ReadJoystickSpeedsCycle_Response" in globals(): ReadJoystickSpeedsCycle_Response = namedtuple("ReadJoystickSpeedsCycle_Response", "CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex")
+    return ReadJoystickSpeedsCycle_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetJoystickSpeedsCycle(Stage:str="", CycleJog:int="", CycleSpeed2:int="", CycleSpeed3:int="", CycleSpeed4:int="", CycleIndex:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets the cycling speeds - these are the speeds that are used by the
+    USB joystick when cycling through the speeds. Can be setup in ControlCenter.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CycleJog:int = 0
+        CycleSpeed2:int = 0
+        CycleSpeed3:int = 0
+        CycleSpeed4:int = 0
+        CycleIndex:int = 0
+    Command Timeout: 5000
+    Example:SetJoystickSpeedsCycle C 1 1 1 1 1
+    """
+    MessageServerInterface.sendSciCommand("SetJoystickSpeedsCycle",Stage,CycleJog,CycleSpeed2,CycleSpeed3,CycleSpeed4,CycleIndex)
+
+
+def SendAUCSCommand(Command:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows sending low level AUCS commands to the ECX box stage. Only
+    applies to Elite/Summit/S300 stations.
+    API Status: internal
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 60000
+    Example:SendAUCSCommand "MM 1 0 INIT 0"
+    """
+    rsp = MessageServerInterface.sendSciCommand("SendAUCSCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadCompensationStatus(Stage:str="", Compensation:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command allows reading if a specific type of compensation is enabled or
+    disabled. Returns an error if this type of compensation is not available for
+    this stage.
+    API Status: internal
+    Args:
+        Stage:str = "None"
+        Compensation:str = "None"
+    Returns:
+        Enabled:int
+        Active:int
+    Command Timeout: 5000
+    Example:ReadCompensationStatus C A
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadCompensationStatus",Stage,Compensation)
+    global ReadCompensationStatus_Response
+    if not "ReadCompensationStatus_Response" in globals(): ReadCompensationStatus_Response = namedtuple("ReadCompensationStatus_Response", "Enabled,Active")
+    return ReadCompensationStatus_Response(int(rsp[0]),int(rsp[1]))
+
+def RegisterNotification(NotificationCode:int="", WantNotification:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Deprecated. All Kernel notifications are now enabled by default.
+    API Status: internal
+    Args:
+        NotificationCode:int = 0
+        WantNotification:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("RegisterNotification",NotificationCode,WantNotification)
+
+
+def AlertNotification(NotificationId:int="", Value1:Decimal="", Value2:Decimal="", Value3:Decimal=""):
+    """
+    This is not a regular command. Asynchronous notifications will be sent from the
+    Kernel controller to the host system only. All notifications can be switched off
+    and on, except the Prober reset notification (ID01).  /warning This is a stub
+    implementation without appropriate handling
+    API Status: published
+    Args:
+        NotificationId:int = 0
+        Value1:Decimal = 0
+        Value2:Decimal = 0
+        Value3:Decimal = 0
+    Command Timeout: 5000
+    Example:AlertNotification 31 195000 160000 0
+    """
+    MessageServerInterface.sendSciCommand("AlertNotification",NotificationId,Value1,Value2,Value3)
+
+
+def SetCompensationStatus(Stage:str="", Compensation:str="", Status:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables a compensation mode for the specified stage
+    API Status: internal
+    Args:
+        Stage:str = "None"
+        Compensation:str = "None"
+        Status:int = -1
+    Command Timeout: 5000
+    Example:SetCompensationStatus C A 1
+    """
+    MessageServerInterface.sendSciCommand("SetCompensationStatus",Stage,Compensation,Status)
+
+
+def GetControllerInfo(ControllerInfo:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command gets the value "Value" for the parameter "Parameter". The unit is
+    parameter specific.
+    API Status: internal
+    Args:
+        ControllerInfo:str = "Unknown"
+    Returns:
+        Value:Decimal
+    Command Timeout: 1000
+    Example:GetControllerInfo HasScanChuckZ
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetControllerInfo",ControllerInfo)
+    return Decimal(rsp[0])
+
+def SetOperationalMode(OperationalMode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    In unprotected mode a number of security features like software fence and
+    initialization necessity are deactivated.          Unprotected mode is
+    deactivated automatically after 5 minutes. Sending 'SetOperationalMode U'
+    anytime before resets the timer back to 5 minutes. It is not necessary to
+    deactivate it before.  **WARNING**: If unprotected mode is enabled, even the
+    most basic safety- and sanity-checks are skipped. Any movement may cause
+    irreparable damage to the prober or attached hardware.
+    API Status: internal
+    Args:
+        OperationalMode:str = "ProtectedMode"
+    Command Timeout: 5000
+    Example:SetOperationalMode P
+    """
+    MessageServerInterface.sendSciCommand("SetOperationalMode",OperationalMode)
+
+
+def GetNanoChamberState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the currently configured Nano-chamber-state.
+    API Status: internal
+    Returns:
+        NanoChamberState:str
+    Command Timeout: 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNanoChamberState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetNanoChamberState(NanoChamberState:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the NanoChamber-state.
+    API Status: internal
+    Args:
+        NanoChamberState:str = "Free"
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("SetNanoChamberState",NanoChamberState)
+
+
+def SetCameraCool(State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows to force activate/deactivate the camera cool output or to let it be set
+    automatically by purge control.
+    API Status: internal
+    Args:
+        State:int = 2
+    Command Timeout: 10000
+    Example:SetCameraCool 0
+    """
+    MessageServerInterface.sendSciCommand("SetCameraCool",State)
+
+
+def ActivateChuckVacuum():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the chuck vacuum and forces it to be on. This command ignores the
+    vacuum sensor and timeout.
+    API Status: internal
+    Command Timeout: 10000
+    Example:ActivateChuckVacuum
+    """
+    MessageServerInterface.sendSciCommand("ActivateChuckVacuum")
+
+
+def ReadMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns a point from the matrix compensation table for the
+    specified axis from the kernel. All command parameters are mandatory.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        MatrixIndexX:int = 0
+        MatrixIndexY:int = 0
+    Returns:
+        XVal:Decimal
+        YVal:Decimal
+    Command Timeout: 5000
+    Example:ReadMatrixValues C 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMatrixValues",Stage,MatrixIndexX,MatrixIndexY)
+    global ReadMatrixValues_Response
+    if not "ReadMatrixValues_Response" in globals(): ReadMatrixValues_Response = namedtuple("ReadMatrixValues_Response", "XVal,YVal")
+    return ReadMatrixValues_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetMatrixValues(Stage:str="", MatrixIndexX:int="", MatrixIndexY:int="", XVal:Decimal="", YVal:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Downloads a point of the matrix compensation table for a specified stage to the
+    kernel. All command parameters are mandatory.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        MatrixIndexX:int = 0
+        MatrixIndexY:int = 0
+        XVal:Decimal = 0
+        YVal:Decimal = 0
+    Command Timeout: 5000
+    Example:SetMatrixValues C 0 0 5000.0 5000.0 2500.0
+    """
+    MessageServerInterface.sendSciCommand("SetMatrixValues",Stage,MatrixIndexX,MatrixIndexY,XVal,YVal)
+
+
+def ReadMEAStatus(Stage:str="", Type:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads if the MEA file for a stage is loaded/enabled (Nucleus legacy stations
+    only)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Type:int = 0
+    Returns:
+        Enable:int
+    Command Timeout: 5000
+    Example:ReadMEAStatus C 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMEAStatus",Stage,Type)
+    return int(rsp[0])
+
+def LoadMEAFile(Stage:str="", Type:int="", Load:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Load the MEA file for a stage (Nucleus legacy stations only)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Type:int = 0
+        Load:int = 0
+    Command Timeout: 5000
+    Example:LoadMEAFile C 0 1
+    """
+    MessageServerInterface.sendSciCommand("LoadMEAFile",Stage,Type,Load)
+
+
+def ReadSoftwareLimits(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The command returns the positions of the actual software limits (end of move
+    range) for each axis of the specified stage in microns. If the Theta stage is
+    selected Z1 and Z2 include the values for the Theta limits.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        ZLowValue:Decimal
+        ZHighValue:Decimal
+        X1Value:Decimal
+        Y1Value:Decimal
+        X2Value:Decimal
+        Y2Value:Decimal
+        X3Value:Decimal
+        Y3Value:Decimal
+        X4Value:Decimal
+        Y4Value:Decimal
+    Command Timeout: 5000
+    Example:ReadSoftwareLimits C
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadSoftwareLimits",Stage)
+    global ReadSoftwareLimits_Response
+    if not "ReadSoftwareLimits_Response" in globals(): ReadSoftwareLimits_Response = namedtuple("ReadSoftwareLimits_Response", "ZLowValue,ZHighValue,X1Value,Y1Value,X2Value,Y2Value,X3Value,Y3Value,X4Value,Y4Value")
+    return ReadSoftwareLimits_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def SetSoftwareFence(Stage:str="", AuxID:int="", FenceForm:str="", XBase:Decimal="", YBase:Decimal="", XDist:Decimal="", YDist:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command sets types and dimensions of technological software fences. It can
+    also be used for enabling and disabling the software fence.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxID:int = 0
+        FenceForm:str = "None"
+        XBase:Decimal = 0
+        YBase:Decimal = 0
+        XDist:Decimal = 0
+        YDist:Decimal = 0
+    Command Timeout: 10000
+    Example:SetSoftwareFence C 0 R 5000 5000 25000 25000
+    """
+    MessageServerInterface.sendSciCommand("SetSoftwareFence",Stage,AuxID,FenceForm,XBase,YBase,XDist,YDist)
+
+
+def GetSoftwareFence(Stage:str="", AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the type and the dimensions of an actual set technological
+    software fence. In case of a rectangular software fence, X and Y coordinates of
+    the four edge points of the fence are given back. In case of a circular software
+    fence, X and Y coordinates of the center point and the radius are given back.
+    All other return values are filled with zeros. All position values are in
+    microns from zero.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxID:int = 0
+    Returns:
+        FenceForm:str
+        XValue1:Decimal
+        YValue1:Decimal
+        XValue2:Decimal
+        YValue2:Decimal
+        XValue3:Decimal
+        YValue3:Decimal
+        XValue4:Decimal
+        YValue4:Decimal
+    Command Timeout: 10000
+    Example:GetSoftwareFence C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwareFence",Stage,AuxID)
+    global GetSoftwareFence_Response
+    if not "GetSoftwareFence_Response" in globals(): GetSoftwareFence_Response = namedtuple("GetSoftwareFence_Response", "FenceForm,XValue1,YValue1,XValue2,YValue2,XValue3,YValue3,XValue4,YValue4")
+    return GetSoftwareFence_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]))
+
+def GetZFence(Stage:str="", CompLayer:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This commands reads if the Z-Fence is activated and the currently set Z-fence
+    values for the specified stage.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        CompLayer:str = "Default"
+    Returns:
+        Enabled:int
+        ZLow:Decimal
+        ZHigh:Decimal
+    Command Timeout: 10000
+    Example:GetZFence S
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZFence",Stage,CompLayer)
+    global GetZFence_Response
+    if not "GetZFence_Response" in globals(): GetZFence_Response = namedtuple("GetZFence_Response", "Enabled,ZLow,ZHigh")
+    return GetZFence_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetZFence(Stage:str="", Enabled:int="", ZLow:Decimal="", ZHigh:Decimal="", CompLayer:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This commands sets Z-Fence and the Z-fence values for the specified stage.
+    Values are stored uncompensated internally and set default compensated as
+    default.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Enabled:int = 0
+        ZLow:Decimal = 0
+        ZHigh:Decimal = 0
+        CompLayer:str = "Default"
+    Command Timeout: 10000
+    Example:SetZFence S 1 5000 10000
+    """
+    MessageServerInterface.sendSciCommand("SetZFence",Stage,Enabled,ZLow,ZHigh,CompLayer)
+
+
+def ResetProber(Mode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Restarts the Prober and replaces the current configuration with a formerly
+    written recovery file. If no recovery file was written, the configuration is
+    reset to the version of the last Prober restart. For ProberBench electronics,
+    'H' will restart the Operating system, 'S' will only restart the Kernel
+    application. For Windows Kernel, 'H' and 'S' are identical.
+    API Status: internal
+    Args:
+        Mode:str = "S"
+    Command Timeout: 20000
+    Example:ResetProber S
+    """
+    MessageServerInterface.sendSciCommand("ResetProber",Mode)
+
+
+def ResetCBox(ResetMode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reboots the operation system inside the Joystick Controller and restarts the
+    functionality. The restart will need a time of around 20 seconds.
+    API Status: internal
+    Args:
+        ResetMode:str = "S"
+    Command Timeout: 20000
+    Example:ResetCBox S
+    """
+    MessageServerInterface.sendSciCommand("ResetCBox",ResetMode)
+
+
+def ReadStageLocations(Stage:str="", LocationType:str="", AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The Home Position on the Chuck or ProbeHead Z axis is also called contact
+    height. The Home Position on the Scope Z axis is also called focus height.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        LocationType:str = "Center"
+        AuxID:int = 0
+    Returns:
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 5000
+    Example:ReadStageLocations C C 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadStageLocations",Stage,LocationType,AuxID)
+    global ReadStageLocations_Response
+    if not "ReadStageLocations_Response" in globals(): ReadStageLocations_Response = namedtuple("ReadStageLocations_Response", "X,Y,Z")
+    return ReadStageLocations_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def GetDataIterator(ShowAll:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a data stream handle which represents a data stream of setup parameters.
+    and requires the GetNextDatum command.
+    API Status: internal
+    Args:
+        ShowAll:int = 0
+    Returns:
+        IdentityToken:int
+        SizeNoAll:int
+    Command Timeout: 10000
+    Example:GetDataIterator 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDataIterator",ShowAll)
+    global GetDataIterator_Response
+    if not "GetDataIterator_Response" in globals(): GetDataIterator_Response = namedtuple("GetDataIterator_Response", "IdentityToken,SizeNoAll")
+    return GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def GetNextDatum(IdentityToken:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the next parameter from the data stream. Fields are separated by a
+    colon. Structure of the response parameter Value:
+    Path_Path:Name:Description:Value
+    API Status: internal
+    Args:
+        IdentityToken:int = 0
+    Returns:
+        IsLastDatum:int
+        DatumCode:int
+        Attributes:int
+        PathNameDescrValue:str
+    Command Timeout: 10000
+    Example:GetNextDatum 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNextDatum",IdentityToken)
+    global GetNextDatum_Response
+    if not "GetNextDatum_Response" in globals(): GetNextDatum_Response = namedtuple("GetNextDatum_Response", "IsLastDatum,DatumCode,Attributes,PathNameDescrValue")
+    return GetNextDatum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetDatum(PathNameAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        PathNameAndValue:str = ""
+    Command Timeout: 20000
+    Example:SetDatum Chuck:AlignGap:25
+    """
+    MessageServerInterface.sendSciCommand("SetDatum",PathNameAndValue)
+
+
+def GetDatum(PathName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a value string. The Value string consists of the value and the
+    description. The Locator only consists of the path and the name. All fields are
+    separated by a colon.  Structure of the command parameter Locator:
+    Path_Path:Name Structure of the response parameter Value: Value:Description
+    API Status: internal
+    Args:
+        PathName:str = ""
+    Returns:
+        Attributes:int
+        DatumCode:int
+        ValueDesc:str
+    Command Timeout: 5000
+    Example:GetDatum Chuck:AlignGap
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDatum",PathName)
+    global GetDatum_Response
+    if not "GetDatum_Response" in globals(): GetDatum_Response = namedtuple("GetDatum_Response", "Attributes,DatumCode,ValueDesc")
+    return GetDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def SetRecoveryDatum(PathNameAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        PathNameAndValue:str = ""
+    Command Timeout: 5000
+    Example:SetRecoveryDatum Chuck:AlignGap:25
+    """
+    MessageServerInterface.sendSciCommand("SetRecoveryDatum",PathNameAndValue)
+
+
+def TraceStart(Controller:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the motion recording. The recording parameters are set in dynamic
+    kernel setup.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Command Timeout: 10000
+    Example:TraceStart C
+    """
+    MessageServerInterface.sendSciCommand("TraceStart",Controller)
+
+
+def TraceStatus(Controller:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Checks the motion recording status for one stage.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Returns:
+        IsReady:int
+        SizeCh0Raw:int
+        SizeCh0Comp:int
+        SizeCh1Raw:int
+        SizeCh1Comp:int
+        SizeCh2Raw:int
+        SizeCh2Comp:int
+        SizeCh3Raw:int
+        SizeCh3Comp:int
+    Command Timeout: 10000
+    Example:TraceStatus C
+    """
+    rsp = MessageServerInterface.sendSciCommand("TraceStatus",Controller)
+    global TraceStatus_Response
+    if not "TraceStatus_Response" in globals(): TraceStatus_Response = namedtuple("TraceStatus_Response", "IsReady,SizeCh0Raw,SizeCh0Comp,SizeCh1Raw,SizeCh1Comp,SizeCh2Raw,SizeCh2Comp,SizeCh3Raw,SizeCh3Comp")
+    return TraceStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]))
+
+def TraceGetData(Controller:str="", Channel:int="", PointOne:int="", IsCompress:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get a collection of five data pairs. A pair is the index and the value of a
+    recording point. If the stream is empty or at the end the index is 1 and the
+    value 0. The index is relative to the start of the motion recording. The
+    recording is clocked by the motion controller cycle. The cycle time is contained
+    in the Kernel setup. In the raw stream all recorded trace points are contained.
+    But in the compressed stream only the non-linear depending trace points are
+    contained. To reload the recording points the stream must be reset to the first
+    recording point.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+        Channel:int = 0
+        PointOne:int = 1
+        IsCompress:int = 1
+    Returns:
+        Point1:int
+        Value1:int
+        Point2:int
+        Value2:int
+        Point3:int
+        Value3:int
+        Point4:int
+        Value4:int
+        Point5:int
+        Value5:int
+    Command Timeout: 10000
+    Example:TraceGetData C 0 0 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("TraceGetData",Controller,Channel,PointOne,IsCompress)
+    global TraceGetData_Response
+    if not "TraceGetData_Response" in globals(): TraceGetData_Response = namedtuple("TraceGetData_Response", "Point1,Value1,Point2,Value2,Point3,Value3,Point4,Value4,Point5,Value5")
+    return TraceGetData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def TraceSetDataPosition(Controller:str="", Channel:int="", NewPos:int="", IsCompress:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the index position in the raw or compressed stream for the next call of the
+    command TraceGetData.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+        Channel:int = 0
+        NewPos:int = 0
+        IsCompress:int = 1
+    Command Timeout: 10000
+    Example:TraceSetDataPosition C 0 1000 1
+    """
+    MessageServerInterface.sendSciCommand("TraceSetDataPosition",Controller,Channel,NewPos,IsCompress)
+
+
+def TraceStop(Controller:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the motion recording.
+    API Status: internal
+    Args:
+        Controller:str = "Chuck"
+    Command Timeout: 10000
+    Example:TraceStop C
+    """
+    MessageServerInterface.sendSciCommand("TraceStop",Controller)
+
+
+def SetZProfilePoint(Stage:str="", XValue:Decimal="", YValue:Decimal="", ZGap:Decimal="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set a point for the Z height profile. If this profile is enabled, the Z height
+    depends on a X and Y coordinate. The Z value is a gap to the current Z height.
+    Positive values are elevated spots, negative values are hollows. The height
+    profile is used to adjust the Z height. The adjusted Z height at a X and Y
+    position is derivated from the nearest profile point. The Z contact level will
+    be calculated from the contact height and the stored Z gap at this point.  See
+    GetZProfilePoint for details.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        ZGap:Decimal = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        ZProfileType:int = 0
+    Returns:
+        ValueCount:int
+    Command Timeout: 5000
+    Example:SetZProfilePoint C 5000 5000 -3 H Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetZProfilePoint",Stage,XValue,YValue,ZGap,PosRef,Unit,ZProfileType)
+    return int(rsp[0])
+
+def ReadZProfilePoint(Stage:str="", Index:int="", PosRef:str="", Unit:str="", ZProfileType:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get a single point and the corresponding Z gap of the Z height profile.  The
+    different z profiles are:  - transient: meant to be used on a per-wafer-basis,
+    default - persistent: configured once, stays in memory - persistent-offset: same
+    as persistent, active when offset is enabled - scratch: not used internaly. Can
+    be used to translate KernelDatums <-> ZProfile-Points
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Index:int = 0
+        PosRef:str = "Home"
+        Unit:str = "Microns"
+        ZProfileType:int = 0
+    Returns:
+        XValue:Decimal
+        YValue:Decimal
+        ZGap:Decimal
+        ValueCount:int
+    Command Timeout: 5000
+    Example:ReadZProfilePoint C 1 H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadZProfilePoint",Stage,Index,PosRef,Unit,ZProfileType)
+    global ReadZProfilePoint_Response
+    if not "ReadZProfilePoint_Response" in globals(): ReadZProfilePoint_Response = namedtuple("ReadZProfilePoint_Response", "XValue,YValue,ZGap,ValueCount")
+    return ReadZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]))
+
+def ClearZProfile(Stage:str="", ZProfileType:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Clears all profile points. See GetZProfile for type description.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZProfileType:int = 0
+    Command Timeout: 5000
+    Example:ClearZProfile C
+    """
+    MessageServerInterface.sendSciCommand("ClearZProfile",Stage,ZProfileType)
+
+
+def ReadScopeSilo(Index:int=""):
+    """
+    Returns the definition of a silo. If the type is rectangle, center means
+    _Point1_. If the type is circle, the meaning of Pos2X and Pos2Y is undefined.
+    API Status: published
+    Args:
+        Index:int = 1
+    Returns:
+        Type:str
+        CenterX:Decimal
+        CenterY:Decimal
+        Radius:Decimal
+        Pos2X:Decimal
+        Pos2Y:Decimal
+        ZHigh:Decimal
+        RefX:Decimal
+        RefY:Decimal
+        RefZ:Decimal
+    Command Timeout: 5000
+    Example:ReadScopeSilo 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSilo",Index)
+    global ReadScopeSilo_Response
+    if not "ReadScopeSilo_Response" in globals(): ReadScopeSilo_Response = namedtuple("ReadScopeSilo_Response", "Type,CenterX,CenterY,Radius,Pos2X,Pos2Y,ZHigh,RefX,RefY,RefZ")
+    return ReadScopeSilo_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]),Decimal(rsp[8]),Decimal(rsp[9]))
+
+def NewProjectFile(FileName:str=""):
+    """
+    Alerts applications if the project file was changed.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("NewProjectFile",FileName)
+
+
+def SaveProjectFile(FileName:str=""):
+    """
+    Alerts applications to save the current project.  This notification _MUST_ only
+    be invoked by CommonCommands. Sending this notification directly _WILL_ give
+    erroneous results.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectFile",FileName)
+
+
+def NewAccessLevel(AccessLevel:str="", UserName:str="", VeloxLocked:int=""):
+    """
+    Alerts applications of new access level.
+    API Status: published
+    Args:
+        AccessLevel:str = "Engineer"
+        UserName:str = ""
+        VeloxLocked:int = 0
+    Command Timeout: 5000
+    Example:NewAccessLevel 1
+    """
+    MessageServerInterface.sendSciCommand("NewAccessLevel",AccessLevel,UserName,VeloxLocked)
+
+
+def LicenseInfo(AnnualEnabled:int="", AnnualDaysLeft:int="", VeloxProEnabled:int="", VueTrackEnabled:int="", VueTrack4PEnabled:int="", ReAlignEnabled:int="", AutomationEnabled:int="", IdToolsEnabled:int="", IVistaEnabled:int="", IVistaProEnabled:int="", LaserCutterEnabled:int="", SiPToolsEnabled:int="", AutoRfEnabled:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifys the listener about the licensed Velox features. Is sent cyclically by
+    CommonCommands.
+    API Status: internal
+    Args:
+        AnnualEnabled:int = 1
+        AnnualDaysLeft:int = 460
+        VeloxProEnabled:int = 0
+        VueTrackEnabled:int = 0
+        VueTrack4PEnabled:int = 0
+        ReAlignEnabled:int = 0
+        AutomationEnabled:int = 0
+        IdToolsEnabled:int = 0
+        IVistaEnabled:int = 0
+        IVistaProEnabled:int = 0
+        LaserCutterEnabled:int = 0
+        SiPToolsEnabled:int = 0
+        AutoRfEnabled:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LicenseInfo",AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled)
+
+
+def RegisterProberAppChange(AppName:str="", SecName:str="", NewRegistered:int=""):
+    """
+    Alerts applications that an application is registered or unregistered on
+    MsgServer.
+    API Status: published
+    Args:
+        AppName:str = "SharedTest"
+        SecName:str = "SharedTest"
+        NewRegistered:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("RegisterProberAppChange",AppName,SecName,NewRegistered)
+
+
+def AlignmentModeChange(AlignmentMode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications of a change of the current alignment mode
+    API Status: internal
+    Args:
+        AlignmentMode:str = "OnAxis"
+    Command Timeout: 5000
+    Example:AlignmentModeChange OnAxis
+    """
+    MessageServerInterface.sendSciCommand("AlignmentModeChange",AlignmentMode)
+
+
+def KernelConnectionStatus(ControllerNum:int="", Type:str="", Result:str="", Desc:str=""):
+    """
+    An example of Kernel Connection Status is &quot;Windows Socket Error Number and
+    Error Description.&quot;
+    API Status: published
+    Args:
+        ControllerNum:int = 1
+        Type:str = "Socket"
+        Result:str = "Disconnected"
+        Desc:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelConnectionStatus",ControllerNum,Type,Result,Desc)
+
+
+def KernelCompensationStatusChange(Stage:str="", Compensation:str="", Enabled:int="", Active:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications that a Kernel compensation has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Compensation:str = "None"
+        Enabled:int = 0
+        Active:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelCompensationStatusChange",Stage,Compensation,Enabled,Active)
+
+
+def KernelCompensationLevelChange(Stage:str="", Comp:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Alerts applications that a Kernel compensation level has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Comp:str = "None"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelCompensationLevelChange",Stage,Comp)
+
+
+def MoveZCombinedStatusChange(Status:str="", PlatenSafe:int="", Height:Decimal="", HeightMax:Decimal="", HeightRelative:Decimal="", SafeHeight:Decimal="", Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies about changes in the combined-z-move-system
+    API Status: internal
+    Args:
+        Status:str = "Off"
+        PlatenSafe:int = 0
+        Height:Decimal = 0
+        HeightMax:Decimal = 0
+        HeightRelative:Decimal = 0
+        SafeHeight:Decimal = 0
+        Message:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombinedStatusChange",Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message)
+
+
+def MachineStateChange(MachineState:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies about changes in the machine state
+    API Status: internal
+    Args:
+        MachineState:str = "Off"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MachineStateChange",MachineState)
+
+
+def ChuckVacuumChangeRequest(VacuumState:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies if the user requests a chuck vacuum change
+    API Status: internal
+    Args:
+        VacuumState:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ChuckVacuumChangeRequest",VacuumState)
+
+
+def SoftwareStopChangedNotify(SoftwareStopState:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies if software stop was activated or deactivated
+    API Status: internal
+    Args:
+        SoftwareStopState:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SoftwareStopChangedNotify",SoftwareStopState)
+
+
+def KernelQuietModeChange(IsQuiet:int="", Stage:str="", IsStageQuiet:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Informs if the overall quiet mode changes and about changes of single stages
+    API Status: internal
+    Args:
+        IsQuiet:int = 0
+        Stage:str = "None"
+        IsStageQuiet:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("KernelQuietModeChange",IsQuiet,Stage,IsStageQuiet)
+
+
+def ConfigurationChanged(ParameterChanged:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies that a configuration item has changed by some application
+    API Status: internal
+    Args:
+        ParameterChanged:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ConfigurationChanged",ParameterChanged)
+
+
+def ScopeWorkingStageChanged(ScopeWorkingStage:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Informs that a new working stage is active
+    API Status: internal
+    Args:
+        ScopeWorkingStage:int = -1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ScopeWorkingStageChanged",ScopeWorkingStage)
+
+
+def BnR_AxisNotify(Stage:str="", Axis:str="", State:str="", AdditionalStateInfo:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the user Interface and Kernel if the state of the axis has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        State:str = "NotExisting"
+        AdditionalStateInfo:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AxisNotify",Stage,Axis,State,AdditionalStateInfo)
+
+
+def BnR_StageNotify(Stage:str="", State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the stage status has changed.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_StageNotify",Stage,State)
+
+
+def BnR_InputNotify(Channel:str="", State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state of an input channel has changed.
+    API Status: internal
+    Args:
+        Channel:str = "0"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_InputNotify",Channel,State)
+
+
+def BnR_OutputNotify(Channel:str="", State:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state of an output channel has changed.
+    API Status: internal
+    Args:
+        Channel:str = "0"
+        State:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_OutputNotify",Channel,State)
+
+
+def BnR_AxisStatusNotify(Stage:str="", Axis:str="", Initialized:int="", PositiveLimit:int="", NegativeLimit:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifys the listener that an axis status has changed. Currently used to notify
+    the Kernel about the init state of a BnR axis.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        Initialized:int = 0
+        PositiveLimit:int = 0
+        NegativeLimit:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AxisStatusNotify",Stage,Axis,Initialized,PositiveLimit,NegativeLimit)
+
+
+def AutoXYModeChange(AutoXYModeOn:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent by Spectrum if Automation was enabled or disabled. This can be AutoXY,
+    AutoZ or VueTrack. Handled by WaferMap to ensure that automation is executed
+    when stepping.
+    API Status: internal
+    Args:
+        AutoXYModeOn:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("AutoXYModeChange",AutoXYModeOn)
+
+
+def ZoomLevelChange(ZoomLevel:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent by OpticalControl when the AZoom zoom level is changed. Spectrum should
+    handle this so it doesn't have to poll OpticalControl for the current zoom
+    level.
+    API Status: internal
+    Args:
+        ZoomLevel:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ZoomLevelChange",ZoomLevel)
+
+
+def BnR_AnalogIONotify(AnalogIO:str="", ValuePercent:Decimal="", UnderOverflow:int="", Error:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notify the listener that the state or value of an analog input or output channel
+    has changed.
+    API Status: internal
+    Args:
+        AnalogIO:str = "AO_PurgeDewPoint"
+        ValuePercent:Decimal = 0
+        UnderOverflow:int = 0
+        Error:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_AnalogIONotify",AnalogIO,ValuePercent,UnderOverflow,Error)
+
+
+def BnR_ControllerInfoNotify(ControllerNum:int="", ControllerInfo:str="", Value:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notifies the listener about changed controller info. Currently used to inform
+    Toolbar about the battery state of the BnR controller.
+    API Status: internal
+    Args:
+        ControllerNum:int = 1
+        ControllerInfo:str = "BatteryOK"
+        Value:Decimal = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_ControllerInfoNotify",ControllerNum,ControllerInfo,Value)
+
+
+def BnR_PositionNotify(Stage:str="", XorT:Decimal="", Y:Decimal="", Z:Decimal="", CommandedXorT:Decimal="", CommandedY:Decimal="", CommandedZ:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent by BnR controller if a axis position has changed. Currently
+    used to notify the Kernel about the new axis position.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XorT:Decimal = 0
+        Y:Decimal = 0
+        Z:Decimal = 0
+        CommandedXorT:Decimal = 0
+        CommandedY:Decimal = 0
+        CommandedZ:Decimal = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_PositionNotify",Stage,XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ)
+
+
+def BnR_InfoNotify(InfoType:str="", Info:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Generic Information Notification
+    API Status: internal
+    Args:
+        InfoType:str = ""
+        Info:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("BnR_InfoNotify",InfoType,Info)
+
+
+def WMNewCurrentDie(DieX:int="", DieY:int="", XFromHome:Decimal="", YFromHome:Decimal="", CurSite:int="", LastSiteIndex:int=""):
+    """
+    Alerts applications that WaferMap has a new position.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        XFromHome:Decimal = 0
+        YFromHome:Decimal = 0
+        CurSite:int = 1
+        LastSiteIndex:int = 1
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("WMNewCurrentDie",DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex)
+
+
+def WMSetupChange():
+    """
+    Alerts applications that a wafer's parameters have been changed.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("WMSetupChange")
+
+
+def ButtonPress(TargetIdent:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent when button instrumented for guided workflow is pressed. The TargetIdent is
+    the identifier for the button as defined for the guided workflow.
+    API Status: internal
+    Args:
+        TargetIdent:int = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("ButtonPress",TargetIdent)
+
+
+def CryoCmdReady(State:str="", Error:int="", ErrorDescription:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sent when the cooling or heating process was terminated successfully or
+    incorrectly. Returns the status with which the process was finished (IDLE, COLD,
+    COOL DOWN, WARMUP) and sends the error code and error message.
+    API Status: internal
+    Args:
+        State:str = "IDLE"
+        Error:int = 0
+        ErrorDescription:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CryoCmdReady",State,Error,ErrorDescription)
+
+
+def VMProjectLoaded():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification sent when Spectrum VS project has finished loading.
+    API Status: internal
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("VMProjectLoaded")
+
+
+def VMProbeCardData(Access:str="", FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent when a probe card file is loaded.
+    API Status: internal
+    Args:
+        Access:str = "L"
+        FileName:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("VMProbeCardData",Access,FileName)
+
+
+def TTLTestDone():
+    """
+    Alerts applications that the TTL Test is ready.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("TTLTestDone")
+
+
+def PSStateChanged(State:str="", SubState:str="", Message:str="", Error:int=""):
+    """
+    Notification sent when VeloxPro changes its running state.
+    API Status: published
+    Args:
+        State:str = "Unknown"
+        SubState:str = "Unknown"
+        Message:str = ""
+        Error:int = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSStateChanged",State,SubState,Message,Error)
+
+
+def PSProgressChanged(ProgressPercent:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification sent during wafer stepping process. It updates the progress
+    information. 'Progress' is the relationship of dies tested to dies to be tested.
+    API Status: internal
+    Args:
+        ProgressPercent:Decimal = 0
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSProgressChanged",ProgressPercent)
+
+
+def PSLoaderUsage(UseLoader:int="", UseAutoWafer:int="", WaferSizes:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent to notify the listener about usage of Loader, usage of
+    fully/semiautomatic mode and supported wafer sizes of process station.
+    API Status: internal
+    Args:
+        UseLoader:int = 0
+        UseAutoWafer:int = 0
+        WaferSizes:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("PSLoaderUsage",UseLoader,UseAutoWafer,WaferSizes)
+
+
+def LoaderMessage(Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Notification is sent by loader to display a message on the process station.
+    API Status: internal
+    Args:
+        Message:str = ""
+    Command Timeout: 30000
+    """
+    MessageServerInterface.sendSciCommand("LoaderMessage",Message)
+
+
+def OpenProjectDialog(ProjectFilename:str="", Option:int=""):
+    """
+    Asks if the current project should be saved and then brings up the Open Project
+    window which opens the selected project file if the user clicks ok.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+        Option:int = 0
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("OpenProjectDialog",ProjectFilename,Option)
+
+
+def SaveProjectAsDialog():
+    """
+    Brings up the Save Project window which saves the project if the user clicks ok.
+    API Status: published
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectAsDialog")
+
+
+def LoginDialog(LevelToOffer:str=""):
+    """
+    Brings up the Login window and sends a New Access Level alert if the user enters
+    a valid password.
+    API Status: published
+    Args:
+        LevelToOffer:str = "1"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LoginDialog",LevelToOffer)
+
+
+def GetStatus():
+    """
+    Returns the current software status. The server holds and maintains the software
+    status. Status can be changed by using any of the following commands:
+    BeginProbing, LoginDialog, AbortProbing, SetExternalMode, PauseProbing,
+    UnloadWafer, ResumeProbing
+    API Status: published
+    Returns:
+        DummyCommonMode:int
+        RunningMode:str
+        AccessLevel:str
+        ExternalMode:int
+        LicenseDaysLeft:int
+        MKH:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetStatus")
+    global GetStatus_Response
+    if not "GetStatus_Response" in globals(): GetStatus_Response = namedtuple("GetStatus_Response", "DummyCommonMode,RunningMode,AccessLevel,ExternalMode,LicenseDaysLeft,MKH")
+    return GetStatus_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def LicensingDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the Licensing window.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LicensingDialog")
+
+
+def GetLicenseInfo():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current license information.
+    API Status: internal
+    Returns:
+        AnnualEnabled:int
+        AnnualDaysLeft:int
+        VeloxProEnabled:int
+        VueTrackEnabled:int
+        VueTrack4PEnabled:int
+        ReAlignEnabled:int
+        AutomationEnabled:int
+        IdToolsEnabled:int
+        IVistaEnabled:int
+        IVistaProEnabled:int
+        LaserCutterEnabled:int
+        SiPToolsEnabled:int
+        AutoRfEnabled:int
+        SecsGemEnabled:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLicenseInfo")
+    global GetLicenseInfo_Response
+    if not "GetLicenseInfo_Response" in globals(): GetLicenseInfo_Response = namedtuple("GetLicenseInfo_Response", "AnnualEnabled,AnnualDaysLeft,VeloxProEnabled,VueTrackEnabled,VueTrack4PEnabled,ReAlignEnabled,AutomationEnabled,IdToolsEnabled,IVistaEnabled,IVistaProEnabled,LaserCutterEnabled,SiPToolsEnabled,AutoRfEnabled,SecsGemEnabled")
+    return GetLicenseInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]))
+
+def GetProjectFile():
+    """
+    Returns the current project file.
+    API Status: published
+    Returns:
+        ProjectFilename:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProjectFile")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReportSoftwareVersion():
+    """
+    Returns the Velox software version as string.
+    API Status: published
+    Returns:
+        SoftwareVersion:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReportSoftwareVersion")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OpenProject(ProjectFilename:str=""):
+    """
+    The OpenProject command opens the specified project.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("OpenProject",ProjectFilename)
+
+
+def IsAppRegistered(Application:str=""):
+    """
+    Checks the server to see if the application "AppName" is registered with the
+    server.
+    API Status: published
+    Args:
+        Application:str = ""
+    Returns:
+        IsAppRegistered:int
+    Command Timeout: 5000
+    Example:IsAppRegistered WaferMap
+    """
+    rsp = MessageServerInterface.sendSciCommand("IsAppRegistered",Application)
+    return int(rsp[0])
+
+def SaveProject(ProjectFilename:str=""):
+    """
+    Saves the current data to the project file.
+    API Status: published
+    Args:
+        ProjectFilename:str = ""
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("SaveProject",ProjectFilename)
+
+
+def GetSoftwarePath(PathType:str=""):
+    """
+    Returns the path for either the applications/data or project files.
+    API Status: published
+    Args:
+        PathType:str = "User"
+    Returns:
+        SoftwarePath:str
+    Command Timeout: 5000
+    Example:GetSoftwarePath User
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwarePath",PathType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CCSelectLens(Lens:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Internal AZoom Helper Command.
+    API Status: internal
+    Args:
+        Lens:int = 1
+    Command Timeout: 10000
+    Example:CCSelectLens 1
+    """
+    MessageServerInterface.sendSciCommand("CCSelectLens",Lens)
+
+
+def CCReadCurrentLens():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Internal AZoom Helper Command. Probably no longer used.
+    API Status: internal
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CCReadCurrentLens")
+    return int(rsp[0])
+
+def CCMoveAuxSite(AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command calls the Kernel command MoveAuxSite to move the chuck to the
+    position of a given AUX site. For the transfer move a safe height is used. If
+    AUX ID is set to 0, the target of the move is the wafer site. If the flag 'Auto
+    Align by Spectrum' in ControlCenter-SystemSetup-Aux Sites is True, the Spectrum
+    command AlignAux is executed after MoveAuxSite to align the site automatically.
+    The flag is only visible, if the aux site type is CalSubstrate and Spectrum is
+    installed. AUX ID in the response is the ID of the new active site.
+    API Status: internal
+    Args:
+        AuxID:int = 1
+    Command Timeout: 200000
+    """
+    MessageServerInterface.sendSciCommand("CCMoveAuxSite",AuxID)
+
+
+def ExecuteCleaningSequence(SequenceName:str="", AllowMediaReuse:int="", SkipAlignAux:int="", SkipReturnMove:int=""):
+    """
+    This command moves to the single cleaning site, executes CleanProbeTip, moves to
+    the contact verify site, and then moves to contact. Returns an error if the
+    clean or verify sites aren't defined.
+    API Status: published
+    Args:
+        SequenceName:str = ""
+        AllowMediaReuse:int = 0
+        SkipAlignAux:int = 0
+        SkipReturnMove:int = 0
+    Command Timeout: 1800000
+    Example:ExecuteCleaningSequence "DeepClean"
+    """
+    MessageServerInterface.sendSciCommand("ExecuteCleaningSequence",SequenceName,AllowMediaReuse,SkipAlignAux,SkipReturnMove)
+
+
+def GetAlignmentMode():
+    """
+    Get the active alignment mode (either on axis or off axis).
+    API Status: published
+    Returns:
+        AlignmentMode:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAlignmentMode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetAlignmentMode(AlignmentMode:str=""):
+    """
+    Sets the active alignment mode (either on axis or off axis).
+    API Status: published
+    Args:
+        AlignmentMode:str = "OnAxis"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SetAlignmentMode",AlignmentMode)
+
+
+def GetLoginData(CmdUserName:str=""):
+    """
+    Gets the Velox user data: name, full name, group, access level.     If the
+    commanded user name is empty, the data of the current user will be responded
+    API Status: published
+    Args:
+        CmdUserName:str = ""
+    Returns:
+        UserName:str
+        LongUserName:str
+        UserGroup:str
+        AccessLevel:str
+        VeloxLocked:int
+    Command Timeout: 5000
+    Example:GetLoginData
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLoginData",CmdUserName)
+    global GetLoginData_Response
+    if not "GetLoginData_Response" in globals(): GetLoginData_Response = namedtuple("GetLoginData_Response", "UserName,LongUserName,UserGroup,AccessLevel,VeloxLocked")
+    return GetLoginData_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]))
+
+def NucleusInitChuck():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up message box to warn user of chuck initialization for Nucleus stations.
+    Allows user to OK/Cancel.
+    API Status: internal
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("NucleusInitChuck")
+
+
+def ShutdownVeloxWithSave():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up message box to allow saving project before shutting down Velox. Allows
+    user to OK/Cancel.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("ShutdownVeloxWithSave")
+
+
+def WinCalAutoCal():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalAutoCal command to WinCal.
+    API Status: internal
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalAutoCal")
+
+
+def WinCalCheckAutoRFStability(AllowMove:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalCheckAutoRFStability command to WinCal.
+    API Status: internal
+    Args:
+        AllowMove:int = 0
+    Returns:
+        StabilityPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalCheckAutoRFStability",AllowMove)
+    return int(rsp[0])
+
+def WinCalCloseRFStabilityReport():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalCloseRFStabilityReport command to WinCal.
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalCloseRFStabilityReport")
+
+
+def WinCalMoveToIssRef(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalMoveToIssRef command to WinCal to move to the specified ISS
+    reference.     The ISS index is the IssIdxMap index as returned from
+    WinCalGetIssListForAuxSite.
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("WinCalMoveToIssRef",IssIdx)
+
+
+def WinCalVerifyIssRefLocAtHome(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalVerifyIssRefLocAtHome command to WinCal and returns AllRefAtHome
+    as 1 if stage and positioners at home.
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Returns:
+        AllRefAtHome:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalVerifyIssRefLocAtHome",IssIdx)
+    return int(rsp[0])
+
+def WinCalGetIssForAuxSite(AuxID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalGetIssForAuxSite command to WinCal and returns the ISS
+    information for the given aux site ID.
+    API Status: internal
+    Args:
+        AuxID:int = 0
+    Returns:
+        IssIdx:int
+        IssPN:str
+        IssDescription:str
+        IssEnabled:int
+        AuxSiteName:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetIssForAuxSite",AuxID)
+    global WinCalGetIssForAuxSite_Response
+    if not "WinCalGetIssForAuxSite_Response" in globals(): WinCalGetIssForAuxSite_Response = namedtuple("WinCalGetIssForAuxSite_Response", "IssIdx,IssPN,IssDescription,IssEnabled,AuxSiteName")
+    return WinCalGetIssForAuxSite_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def WinCalGetNameAndVersion():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalGetNameAndVersion command to WinCal.
+    API Status: internal
+    Returns:
+        ServerName:str
+        Version:str
+        MajorVersion:int
+        MinorVersion:int
+        Revision:int
+        Build:int
+    Command Timeout: 30000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNameAndVersion")
+    global WinCalGetNameAndVersion_Response
+    if not "WinCalGetNameAndVersion_Response" in globals(): WinCalGetNameAndVersion_Response = namedtuple("WinCalGetNameAndVersion_Response", "ServerName,Version,MajorVersion,MinorVersion,Revision,Build")
+    return WinCalGetNameAndVersion_Response(str(rsp[0]),str(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def WinCalMonitorNoMove():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalMonitorNoMove command to WinCal. Triggers WinCal to measure the
+    monitor portion of the current calibration setup.
+    API Status: internal
+    Returns:
+        MonitorPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalMonitorNoMove")
+    return int(rsp[0])
+
+def WinCalValidateAdvanced(ProbeSpacing:Decimal="", ResetTrace:int="", AllowMove:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalValidateAdvanced command to WinCal. Performs the validation step of
+    the currently selected calibration setup.     Resets the controller used in WinCal
+    for validataion.
+    API Status: internal
+    Args:
+        ProbeSpacing:Decimal = 130
+        ResetTrace:int = 1
+        AllowMove:int = 1
+    Returns:
+        ValidationPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalValidateAdvanced",ProbeSpacing,ResetTrace,AllowMove)
+    return int(rsp[0])
+
+def WinCalMeasureMonitorReference(AllowMove:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalMeasureMonitorReference command to WinCal.
+    API Status: internal
+    Args:
+        AllowMove:int = 0
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalMeasureMonitorReference",AllowMove)
+
+
+def WinCalGetNumValidationPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumValidationPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumValidationPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumValidationPorts")
+    return int(rsp[0])
+
+def WinCalSetNumValidationPorts(NumValidationPorts:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumValidationPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumValidationPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumValidationPorts",NumValidationPorts)
+
+
+def WinCalGetNumMonitoringPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumMonitoringPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumMonitoringPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumMonitoringPorts")
+    return int(rsp[0])
+
+def WinCalSetNumMonitoringPorts(NumMonitoringPorts:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumMonitoringPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumMonitoringPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumMonitoringPorts",NumMonitoringPorts)
+
+
+def WinCalGetNumRepeatabilityPorts():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetNumRepeatabilityPorts command to WinCal.
+    API Status: internal
+    Returns:
+        NumRepeatabilityPorts:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumRepeatabilityPorts")
+    return int(rsp[0])
+
+def WinCalSetNumRepeatabilityPorts(NumRepeatabilityPorts:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalSetNumRepeatabilityPorts command to WinCal.
+    API Status: internal
+    Args:
+        NumRepeatabilityPorts:int = 2
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalSetNumRepeatabilityPorts",NumRepeatabilityPorts)
+
+
+def WinCalValidate():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalValidate command to WinCal. Performs the validation step of the
+    currently selected calibration setup in WinCal.
+    API Status: internal
+    Returns:
+        ValidationPassed:int
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalValidate")
+    return int(rsp[0])
+
+def WinCalGetValidationSetup(Port:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends CalGetValidationSetup command to WinCal. Returns calibration setup
+    parameters.
+    API Status: internal
+    Args:
+        Port:int = 1
+    Returns:
+        StandardType:str
+        StandardPorts:int
+        StandardCompareType:int
+        StructureType:str
+        PostCorrect:int
+        PostCorrectMatching:int
+        AutoConfigure:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetValidationSetup",Port)
+    global WinCalGetValidationSetup_Response
+    if not "WinCalGetValidationSetup_Response" in globals(): WinCalGetValidationSetup_Response = namedtuple("WinCalGetValidationSetup_Response", "StandardType,StandardPorts,StandardCompareType,StructureType,PostCorrect,PostCorrectMatching,AutoConfigure")
+    return WinCalGetValidationSetup_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def WinCalAutoCalNoValidation(ProbeSpacing:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalAutoCalNoValidation command to WinCal. Performs an AutoCal
+    without the validation step
+    API Status: internal
+    Args:
+        ProbeSpacing:Decimal = 130
+    Command Timeout: 300000
+    """
+    MessageServerInterface.sendSciCommand("WinCalAutoCalNoValidation",ProbeSpacing)
+
+
+def WinCalHideAllWindows():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalHideAllWindows command to WinCal. This minimizes all the WinCal
+    windows
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalHideAllWindows")
+
+
+def WinCalGetReferenceStructureInfo(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalGetReferenceStructureInfo command to WinCal. Given the WinCal ISS
+    index it will return a string with the reference information
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Returns:
+        ReferenceInfo:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetReferenceStructureInfo",IssIdx)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def WinCalSystemSetupHasUnappliedChanges(ShowErrors:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the WinCalSystemSetupHasUnappliedChanges command to WinCal. Returns true
+    if WinCal has unapplied changes
+    API Status: internal
+    Args:
+        ShowErrors:int = 0
+    Returns:
+        HasUnappliedChanges:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalSystemSetupHasUnappliedChanges",ShowErrors)
+    return int(rsp[0])
+
+def WinCalRecordIssRefAtCurrentLoc(IssIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends the CalRecordIssRefAtCurrentLoc command to WinCal. Record the ISS,
+    indicated by the index, reference as being the current location
+    API Status: internal
+    Args:
+        IssIdx:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("WinCalRecordIssRefAtCurrentLoc",IssIdx)
+
+
+def SaveProjectAsTemplateDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the Save Project as Template window which saves the project template
+    if the user clicks ok.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SaveProjectAsTemplateDialog")
+
+
+def CreateProjectFromTemplateDialog():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Brings up the New Project from Template dialog which allows the user to select a
+    template and create a new project.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CreateProjectFromTemplateDialog")
+
+
+def WinCalGetNumPortsAndProbes():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns Max Ports and Number of probes connected to a port
+    API Status: internal
+    Returns:
+        MaxPorts:int
+        NumPortsConnectedtoProbes:int
+    Command Timeout: 1000
+    Example:WinCalGetNumPortsAndProbes
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetNumPortsAndProbes")
+    global WinCalGetNumPortsAndProbes_Response
+    if not "WinCalGetNumPortsAndProbes_Response" in globals(): WinCalGetNumPortsAndProbes_Response = namedtuple("WinCalGetNumPortsAndProbes_Response", "MaxPorts,NumPortsConnectedtoProbes")
+    return WinCalGetNumPortsAndProbes_Response(int(rsp[0]),int(rsp[1]))
+
+def WinCalGetProbeInfoForPort(VnaPortNum:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the properties from one probe, based on the passed in index. Pass in a
+    physical VNA port number that is less than or equal to Max Probes from the call
+    to CalGetNumPortsAndProbes
+    API Status: internal
+    Args:
+        VnaPortNum:int = 1
+    Returns:
+        IsSelected:int
+        BaseProbe:str
+        Options:str
+        PhysicalOrient:str
+        IsDual:int
+        IsSymmetric:int
+        SignalConfig:str
+        SelectedPitch:int
+    Command Timeout: 1000
+    Example:WinCalGetProbeInfoForPort 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalGetProbeInfoForPort",VnaPortNum)
+    global WinCalGetProbeInfoForPort_Response
+    if not "WinCalGetProbeInfoForPort_Response" in globals(): WinCalGetProbeInfoForPort_Response = namedtuple("WinCalGetProbeInfoForPort_Response", "IsSelected,BaseProbe,Options,PhysicalOrient,IsDual,IsSymmetric,SignalConfig,SelectedPitch")
+    return WinCalGetProbeInfoForPort_Response(int(rsp[0]),str(rsp[1]),str(rsp[2]),str(rsp[3]),int(rsp[4]),int(rsp[5]),str(rsp[6]),int(rsp[7]))
+
+def GetMachineState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current state of the machine.
+    API Status: internal
+    Returns:
+        MachineState:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMachineState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowAboutDialog(Pid:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shows the help about dialog for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ShowAboutDialog",Pid)
+
+
+def ShowSplashScreen(Pid:int="", TimeoutMs:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shows the splash screen for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+        TimeoutMs:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ShowSplashScreen",Pid,TimeoutMs)
+
+
+def CloseSplashScreen(Pid:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the splash screen for the given application
+    API Status: internal
+    Args:
+        Pid:int = -1
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("CloseSplashScreen",Pid)
+
+
+def GetLastFourProjects():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the last four project files that were opened.
+    API Status: internal
+    Returns:
+        ProjectFile1:str
+        ProjectFile2:str
+        ProjectFile3:str
+        ProjectFile4:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLastFourProjects")
+    global GetLastFourProjects_Response
+    if not "GetLastFourProjects_Response" in globals(): GetLastFourProjects_Response = namedtuple("GetLastFourProjects_Response", "ProjectFile1,ProjectFile2,ProjectFile3,ProjectFile4")
+    return GetLastFourProjects_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def WinCalExecuteCommand(Command:str=""):
+    """
+    Sends the WinCalExecuteCommand command to WinCal and returns the response
+    string.
+    API Status: published
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 300000
+    """
+    rsp = MessageServerInterface.sendSciCommand("WinCalExecuteCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDemoMode(TurnOnDemoMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+    This command will return an error if its called with any other parameter as 0.
+    API Status: internal
+    Args:
+        TurnOnDemoMode:int = 1
+    Command Timeout: 5000
+    Example:SetDemoMode 0
+    """
+    MessageServerInterface.sendSciCommand("SetDemoMode",TurnOnDemoMode)
+
+
+def ChangeDemoRsp(Param:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Override a command with a demo response. The command will not reach its
+    destination but the supplied demo response will be returned. An active overide
+    for a command will be removed if the provided timeout is negative. Format:  [ID]
+    [Time] [ErrorCode]:[Response]  - Id: command id in hex withoud leding 0x - Time:
+    time in ms between command and response, negativ to reset demo mode for this
+    command - Errorcode: 0 for success, everything else indicates an error -
+    Response: response string
+    API Status: internal
+    Args:
+        Param:str = ""
+    Command Timeout: 5000
+    Example:ChangeDemoRsp 31 200 0:5000.0 5000.0 8500
+    """
+    MessageServerInterface.sendSciCommand("ChangeDemoRsp",Param)
+
+
+def GetDemoMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The DemoMode is not supported anymore. Use ChangeDemoRsp to install a demo mode.
+    This command will always return 0.
+    API Status: internal
+    Returns:
+        DemoModeOn:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDemoMode")
+    return int(rsp[0])
+
+def ResetNetworkPort(Param:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    (Re)sets the IP address and listen port of the socket to which the NetworkDriver
+    tries to connect to (IP address and listen port of Kernel socket). Dummy
+    implementation for Kernel to support backwards.
+    API Status: internal
+    Args:
+        Param:str = ""
+    Command Timeout: 10000
+    Example:ResetNetworkPort 192.168.3.1 10000
+    """
+    MessageServerInterface.sendSciCommand("ResetNetworkPort",Param)
+
+
+def GetNDriverClientStatus(ClientNum:int="", Param:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets status information about the connection NetworkDriver to Kernel. Socket
+    Error is the Windows socket error, Description the Windows socket error
+    description. If Socket Error is 0, the description 'Registered' informs that the
+    Kernel is ready to receive Remote Commands.
+    API Status: internal
+    Args:
+        ClientNum:int = 1
+        Param:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 5000
+    Example:GetNDriverClientStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNDriverClientStatus",ClientNum,Param)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def OverrideCommandTimeout(CmdID:int="", TimeoutMilliSec:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows specifying a separate command timeout for a single instance
+    of a command. This is especially useful if the application that receives a
+    command knows how long a command will take.  This command had been added for
+    SoakTime-handling of StepNextDie. A safe guess for the timeout of StepNextDie is
+    5s.
+    API Status: internal
+    Args:
+        CmdID:int = 0
+        TimeoutMilliSec:int = 1000
+    Command Timeout: 5000
+    Example:OverrideCommandTimeout 3234 20000
+    """
+    MessageServerInterface.sendSciCommand("OverrideCommandTimeout",CmdID,TimeoutMilliSec)
+
+
+def ShutdownVelox(IgnorePID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Shutdown all Velox applications in an ordered fashion. When this command returns
+    success, all non-mandatory apps are closed and the mandatory ones will follow
+    shortly
+    API Status: internal
+    Args:
+        IgnorePID:int = 0
+    Command Timeout: 120000
+    Example:ShutdownVelox
+    """
+    MessageServerInterface.sendSciCommand("ShutdownVelox",IgnorePID)
+
+
+def InitializationDone(CommandGroup:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Registration of an application can be delayed. To trigger this behavior,
+    RegisterProberApp has to be called with flag 3 set (0x04). From
+    RegisterProberApp to the time this command is sent, the application can send
+    commands but can't receive commands. This is necessary because some application
+    have to communicate with others during initialization and can not handle
+    commands properly during this time.  The command group is necessary because of
+    architectural reasons (By design, the command receiver does not now the sender
+    of a command).
+    API Status: internal
+    Args:
+        CommandGroup:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("InitializationDone",CommandGroup)
+
+
+def StepFirstZProfilePoint(XPos:Decimal="", YPos:Decimal="", NumberOfPoints:int="", NumberOfEPoints:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command goes to the first Z Profile Point, adjusts Z (in the automatic mode
+    only) and pauses after it (even in the automatic mode)
+    API Status: internal
+    Args:
+        XPos:Decimal = 0
+        YPos:Decimal = 0
+        NumberOfPoints:int = 0
+        NumberOfEPoints:int = 0
+    Command Timeout: 60000
+    Example:StepFirstZProfilePoint 10000 20000 5 5
+    """
+    MessageServerInterface.sendSciCommand("StepFirstZProfilePoint",XPos,YPos,NumberOfPoints,NumberOfEPoints)
+
+
+def StepNextZProfilePoint(Point:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command calculates a delta value for the current point and then moves to
+    the specified point (if it's presented) or to the next one. Note, that in case
+    of the automatic Z detecting a return ZDelta parameter is a value for the
+    current point, but in case of the semiautomatic mode the command returns ZDelta
+    as a value for a previous tested point. If the profiling is finished this
+    command will return #807 error (End of the profile). Point indices are started
+    from 1 (1 is first, 2 is second, and so on).
+    API Status: internal
+    Args:
+        Point:int = 0
+    Returns:
+        XPos:Decimal
+        YPos:Decimal
+        Delta:Decimal
+        CurPoint:int
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 60000
+    Example:StepNextZProfilePoint 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextZProfilePoint",Point)
+    global StepNextZProfilePoint_Response
+    if not "StepNextZProfilePoint_Response" in globals(): StepNextZProfilePoint_Response = namedtuple("StepNextZProfilePoint_Response", "XPos,YPos,Delta,CurPoint,NumberOfPoints,NumberOfEPoints")
+    return StepNextZProfilePoint_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]))
+
+def SetZProfileOptions(ProfileMode:str="", SepSpeed:Decimal="", ProfileSensor:str="", Stage:str="", SearchSpeed:Decimal="", Gap:Decimal="", Units:str="", ClearElectronics:int="", ClearRefZ:int="", Inaccuracy:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets some Z Profile Program Options remotely.
+    API Status: internal
+    Args:
+        ProfileMode:str = "S"
+        SepSpeed:Decimal = 25
+        ProfileSensor:str = "E"
+        Stage:str = "C"
+        SearchSpeed:Decimal = 50
+        Gap:Decimal = 10
+        Units:str = "Y"
+        ClearElectronics:int = 1
+        ClearRefZ:int = 1
+        Inaccuracy:Decimal = 0
+    Command Timeout: 10000
+    Example:SetZProfileOptions S 25 E C 50 10 Y 1 1 0
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileOptions",ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy)
+
+
+def GetZProfileOptions():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Return predefined settings of the Z Profile Program.
+    API Status: internal
+    Returns:
+        ProfileMode:str
+        SepSpeed:Decimal
+        ProfileSensor:str
+        Stage:str
+        SearchSpeed:Decimal
+        Gap:Decimal
+        Units:str
+        ClearElectronics:int
+        ClearRefZ:int
+        Inaccuracy:Decimal
+    Command Timeout: 10000
+    Example:GetZProfileOptions
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileOptions")
+    global GetZProfileOptions_Response
+    if not "GetZProfileOptions_Response" in globals(): GetZProfileOptions_Response = namedtuple("GetZProfileOptions_Response", "ProfileMode,SepSpeed,ProfileSensor,Stage,SearchSpeed,Gap,Units,ClearElectronics,ClearRefZ,Inaccuracy")
+    return GetZProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str(rsp[6]),int(rsp[7]),int(rsp[8]),Decimal(rsp[9]))
+
+def OpenZProfileFile(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command opens the file inside of the Z Profiling.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 240000
+    Example:OpenZProfileFile Profile1
+    """
+    rsp = MessageServerInterface.sendSciCommand("OpenZProfileFile",FileName)
+    global OpenZProfileFile_Response
+    if not "OpenZProfileFile_Response" in globals(): OpenZProfileFile_Response = namedtuple("OpenZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+    return OpenZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def SaveZProfileFile(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves the current profile in the specified file.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:SaveZProfileFile Profile1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SaveZProfileFile",FileName)
+    global SaveZProfileFile_Response
+    if not "SaveZProfileFile_Response" in globals(): SaveZProfileFile_Response = namedtuple("SaveZProfileFile_Response", "NumberOfPoints,NumberOfEPoints")
+    return SaveZProfileFile_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadZProfile(NewOrigin:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Read a profile from the ProberBench Electronics II to the application. Return a
+    number of available points.
+    API Status: internal
+    Args:
+        NewOrigin:str = "Z"
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:ReadZProfile H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadZProfile",NewOrigin)
+    return int(rsp[0])
+
+def SetZProfile():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Uploads the current profile to the ProberBench Electronics II. Returns a number
+    of written points.
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:SetZProfile
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetZProfile")
+    return int(rsp[0])
+
+def CloseZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the Z-Profiling application.
+    API Status: internal
+    Command Timeout: 5000
+    Example:CloseZProfiling
+    """
+    MessageServerInterface.sendSciCommand("CloseZProfiling")
+
+
+def SetZProfileStartPoint(X:Decimal="", Y:Decimal="", PosRef:str="", Units:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets new start point for the profile. All points of the profile will be shifted
+    accordingly.
+    API Status: internal
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        PosRef:str = "Z"
+        Units:str = "Y"
+    Command Timeout: 10000
+    Example:SetZProfileStartPoint 0 0 H Y
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileStartPoint",X,Y,PosRef,Units)
+
+
+def GetZProfilingStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a status of the profiling process. If this status is true it means the
+    process is started.
+    API Status: internal
+    Returns:
+        Started:int
+    Command Timeout: 10000
+    Example:GetZProfilingStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfilingStatus")
+    return int(rsp[0])
+
+def StopZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the profiling process.
+    API Status: internal
+    Command Timeout: 10000
+    Example:StopZProfiling
+    """
+    MessageServerInterface.sendSciCommand("StopZProfiling")
+
+
+def SetZProfileOrigin(Pos:str="", X:Decimal="", Y:Decimal="", Z:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets an origin for the profile. If the origin position is H the command ignores
+    X and Y parameters. If Z is None the command clears Z value of the origin.
+    Otherwise it tries to extract a double value from the string and set it.
+    API Status: internal
+    Args:
+        Pos:str = "H"
+        X:Decimal = 0
+        Y:Decimal = 0
+        Z:str = "None"
+    Command Timeout: 10000
+    Example:SetZProfileOrigin H 0 0 None
+    """
+    MessageServerInterface.sendSciCommand("SetZProfileOrigin",Pos,X,Y,Z)
+
+
+def GetZProfileOrigin():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current parameters of the profile origin. If the origin Z has no value
+    the return string for it will be None, otherwise it consists a double value of
+    the profile Z.
+    API Status: internal
+    Returns:
+        Pos:str
+        X:Decimal
+        Y:Decimal
+        Z:str
+    Command Timeout: 10000
+    Example:GetZProfileOrigin
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileOrigin")
+    global GetZProfileOrigin_Response
+    if not "GetZProfileOrigin_Response" in globals(): GetZProfileOrigin_Response = namedtuple("GetZProfileOrigin_Response", "Pos,X,Y,Z")
+    return GetZProfileOrigin_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def StartZProfiling():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command works in the automatic mode only. It starts the profiling process,
+    profiles the entire wafer and then returns a number of tested points. This
+    command does upload the current profile to the ProberBench Electronics II. To do
+    it please use SetZProfile command
+    API Status: internal
+    Command Timeout: 10000
+    Example:StartZProfiling
+    """
+    MessageServerInterface.sendSciCommand("StartZProfiling")
+
+
+def ZProfileWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command works in the automatic mode only. It starts the profiling process,
+    profiles the entire wafer and then returns a number of tested points. This
+    command does upload the current profile to the ProberBench Electronics II. To do
+    it please use SetZProfile command
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 36000000
+    Example:ZProfileWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("ZProfileWafer")
+    global ZProfileWafer_Response
+    if not "ZProfileWafer_Response" in globals(): ZProfileWafer_Response = namedtuple("ZProfileWafer_Response", "NumberOfPoints,NumberOfEPoints")
+    return ZProfileWafer_Response(int(rsp[0]),int(rsp[1]))
+
+def GetZProfileStartPoint(PosRef:str="", Units:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current start point of the profile by using given units and a
+    reference position.
+    API Status: internal
+    Args:
+        PosRef:str = "Z"
+        Units:str = "Y"
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 10000
+    Example:GetZProfileStartPoint H Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfileStartPoint",PosRef,Units)
+    global GetZProfileStartPoint_Response
+    if not "GetZProfileStartPoint_Response" in globals(): GetZProfileStartPoint_Response = namedtuple("GetZProfileStartPoint_Response", "X,Y")
+    return GetZProfileStartPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AddZProfilePoint(X:Decimal="", Y:Decimal="", After:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Adds new point to the profile at the end (default) or after the given point.
+    Returns an index of new point and a number of all points in the profile. Point
+    indices are started from 1.
+    API Status: internal
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        After:int = 0
+    Returns:
+        Index:int
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:AddZProfilePoint 50000 50000
+    """
+    rsp = MessageServerInterface.sendSciCommand("AddZProfilePoint",X,Y,After)
+    global AddZProfilePoint_Response
+    if not "AddZProfilePoint_Response" in globals(): AddZProfilePoint_Response = namedtuple("AddZProfilePoint_Response", "Index,NumberOfPoints,NumberOfEPoints")
+    return AddZProfilePoint_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def DeleteZProfilePoint(Index:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Deletes the point from the profile. Returns a number of all and enabled points
+    in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        NumberOfPoints:int
+        NumberOfEPoints:int
+    Command Timeout: 10000
+    Example:DeleteZProfilePoint 11
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteZProfilePoint",Index)
+    global DeleteZProfilePoint_Response
+    if not "DeleteZProfilePoint_Response" in globals(): DeleteZProfilePoint_Response = namedtuple("DeleteZProfilePoint_Response", "NumberOfPoints,NumberOfEPoints")
+    return DeleteZProfilePoint_Response(int(rsp[0]),int(rsp[1]))
+
+def SetZProfilePointStatus(Index:int="", Status:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables the point in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+        Status:str = "0"
+    Command Timeout: 10000
+    Example:SetZProfilePointStatus 11 E
+    """
+    MessageServerInterface.sendSciCommand("SetZProfilePointStatus",Index,Status)
+
+
+def GetZProfilePointStatus(Index:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a status of the point in the profile. Point indices are started from 1.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    Example:GetZProfilePointStatus 11
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetZProfilePointStatus",Index)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def PreciseZProfile():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    All points are covered by triangles, each vertex of the triangle is a point of
+    the profile. The centers of the triangles are new points of the profile. If all
+    three vertexes of the triangle are tested points the new point will be marked as
+    tested also and has Z value equal to average Z of all three vertexes. Otherwise
+    the new point will be marked as untested. The command returns a number of points
+    in the profile after the update.
+    API Status: internal
+    Returns:
+        NumberOfPoints:int
+    Command Timeout: 10000
+    Example:PreciseZProfile
+    """
+    rsp = MessageServerInterface.sendSciCommand("PreciseZProfile")
+    return int(rsp[0])
+
+def CloseTableView():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the TableView application.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CloseTableView")
+
+
+def StepChuckSite(Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the wafer chuck stage to the requested Site no. of the chuck table view.
+    If no Site no is specified the chuck will step automatically to the next logical
+    site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepChuckSite",Site)
+    return int(rsp[0])
+
+def StepChuckSubsite(Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the wafer chuck stage to the requested Subsite no. of the chuck subsite
+    table view. If no Subsite no. is specified the chuck will step automatically to
+    the next logical site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepChuckSubsite",Site)
+    return int(rsp[0])
+
+def StepScopeSite(Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the microscope stage to the requested Site no. of the scope table view. If
+    no Site no is specified the scope will step automatically to the next logical
+    site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Site:int = -1
+    Returns:
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepScopeSite",Site)
+    return int(rsp[0])
+
+def StepProbeSite(Probe:int="", Site:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Steps the specified probe to the requested Site no. of the Probe no table view.
+    If no Site no. is specified the Probe no. will step automatically to the next
+    logical site location. The first site in the table is site 1.
+    API Status: internal
+    Args:
+        Probe:int = -1
+        Site:int = -1
+    Returns:
+        ProbeRet:int
+        SiteRet:int
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepProbeSite",Probe,Site)
+    global StepProbeSite_Response
+    if not "StepProbeSite_Response" in globals(): StepProbeSite_Response = namedtuple("StepProbeSite_Response", "ProbeRet,SiteRet")
+    return StepProbeSite_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadChuckSitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual chuck site position. The first site in the table is site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckSitePosition")
+    global ReadChuckSitePosition_Response
+    if not "ReadChuckSitePosition_Response" in globals(): ReadChuckSitePosition_Response = namedtuple("ReadChuckSitePosition_Response", "Site,X,Y")
+    return ReadChuckSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadScopeSitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the site position of the specified probe. The first site in the table is
+    site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadScopeSitePosition")
+    global ReadScopeSitePosition_Response
+    if not "ReadScopeSitePosition_Response" in globals(): ReadScopeSitePosition_Response = namedtuple("ReadScopeSitePosition_Response", "Site,X,Y")
+    return ReadScopeSitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ReadProbeSitePosition(Probe:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the site position of the specified probe. The first site in the table is
+    site 1.
+    API Status: internal
+    Args:
+        Probe:int = -1
+    Returns:
+        ProbeRet:int
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadProbeSitePosition",Probe)
+    global ReadProbeSitePosition_Response
+    if not "ReadProbeSitePosition_Response" in globals(): ReadProbeSitePosition_Response = namedtuple("ReadProbeSitePosition_Response", "ProbeRet,Site,X,Y")
+    return ReadProbeSitePosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadChuckSubsitePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the chuck subsite position. The first site in the table is site 1.
+    API Status: internal
+    Returns:
+        Site:int
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadChuckSubsitePosition")
+    global ReadChuckSubsitePosition_Response
+    if not "ReadChuckSubsitePosition_Response" in globals(): ReadChuckSubsitePosition_Response = namedtuple("ReadChuckSubsitePosition_Response", "Site,X,Y")
+    return ReadChuckSubsitePosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def StepFirstDie(ClearBins:int="", RecalcRoute:int=""):
+    """
+    Steps the chuck to the first die of the wafer map. Returns the row and column
+    number of the actual die location after the move is completed. If ClearBins is
+    1, all binning data will be cleared from dies. If yes the route will be
+    recalculated. All dies marked to skip during the last test (marked to skip with
+    SetDieStatus) will be eliminated from the route.
+    API Status: published
+    Args:
+        ClearBins:int = 1
+        RecalcRoute:int = 1
+    Returns:
+        DieX:int
+        DieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFirstDie",ClearBins,RecalcRoute)
+    global StepFirstDie_Response
+    if not "StepFirstDie_Response" in globals(): StepFirstDie_Response = namedtuple("StepFirstDie_Response", "DieX,DieY,CurSite,LastSiteIndex")
+    return StepFirstDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def StepNextDie(CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Steps the chuck to the specified x,y die location of the wafer map. If no
+    command data is passed, the chuck automatically steps to the next logical wafer
+    map die location. Returns the row and column number of the actual die location
+    after the move is completed. In addition, the SubDie location, and total number
+    of SubDies is also returned.  If Site (i.e. SubDie) is -1, the chuck will move
+    to SubDie 0, on the next die; in this case, the first 2 parameters are ignored.
+    If sent without parameters, it will literally 'step to the next die'. When using
+    this command from shared code, use SendWithoutParameter().
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextDie",CDieX,CDieY,Site)
+    global StepNextDie_Response
+    if not "StepNextDie_Response" in globals(): StepNextDie_Response = namedtuple("StepNextDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return StepNextDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinMapDie(Bin:int="", CDieX:int="", CDieY:int=""):
+    """
+    Assigns the bin information to the wafer map at the current die, unless a row
+    and column is specified. Inks the device if the real time inking option (of the
+    wafer map) is enabled.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+    Command Timeout: 30000
+    Example:BinMapDie 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinMapDie",Bin,CDieX,CDieY)
+    global BinMapDie_Response
+    if not "BinMapDie_Response" in globals(): BinMapDie_Response = namedtuple("BinMapDie_Response", "RDieX,RDieY")
+    return BinMapDie_Response(int(rsp[0]),int(rsp[1]))
+
+def AssignMapBins(Bins:str=""):
+    """
+    Assigns the pass or fail information to the actual bin value. Redundant to
+    SetBinCode.
+    API Status: published
+    Args:
+        Bins:str = ""
+    Command Timeout: 10000
+    Example:AssignMapBins PFFFFFF
+    """
+    MessageServerInterface.sendSciCommand("AssignMapBins",Bins)
+
+
+def StepFailedBack():
+    """
+    Steps the chuck back the number of consecutive failed dies (goes back to the
+    last known good die) and returns the number of consecutive failed dies.
+    API Status: published
+    Returns:
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedBack")
+    return int(rsp[0])
+
+def StepFailedForward():
+    """
+    Steps the chuck forward the number of consecutive failed dies (goes to next
+    untested die).
+    API Status: published
+    Returns:
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedForward")
+    return int(rsp[0])
+
+def ReadMapPosition(Pos:int="", FromPos:str=""):
+    """
+    Returns the actual Wafer Map chuck position. The SubDie collection is 1-based,
+    the first value is 1, not 0.     M_pnCurSite returns the currently selected
+    Subdie (1-based) or 0 if no Subdie is currently selected. This command (i.e.
+    ReadMapPosition) has been included for legacy support.       ReadMapPosition2 is
+    the preferred method for reading Wafer Map chuck position.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        DieX:int
+        DieY:int
+        XFromHome:Decimal
+        YFromHome:Decimal
+        CurSite:int
+        LastSiteIndex:int
+        CurDie:int
+        DiesCount:int
+        CurCluster:int
+        ClustersCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapPosition",Pos,FromPos)
+    global ReadMapPosition_Response
+    if not "ReadMapPosition_Response" in globals(): ReadMapPosition_Response = namedtuple("ReadMapPosition_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+    return ReadMapPosition_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def ReadMapYield():
+    """
+    Returns the actual wafer map yield data information.
+    API Status: published
+    Returns:
+        TotalDies:int
+        TestedDies:int
+        Passed:int
+        Failed:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapYield")
+    global ReadMapYield_Response
+    if not "ReadMapYield_Response" in globals(): ReadMapYield_Response = namedtuple("ReadMapYield_Response", "TotalDies,TestedDies,Passed,Failed")
+    return ReadMapYield_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def BinStepDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Bins the current die and steps the chuck to the next selected die location of
+    the wafer map (default) or steps to the specified Column and Row position, if
+    these values are passed.  In contrast to StepNextDie, the BinStepDie command
+    will only step from die to die while staying on the current subdie. It will not
+    step through the subdies so it cannot be used for subdie stepping.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    Example:BinStepDie 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinStepDie",Bin,CDieX,CDieY,Site)
+    global BinStepDie_Response
+    if not "BinStepDie_Response" in globals(): BinStepDie_Response = namedtuple("BinStepDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return BinStepDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetMapHome(DieX:int="", DieY:int=""):
+    """
+    If the command has no parameters it sets the current position as home position
+    both for the wafer map and for the chuck. Otherwise, it changes the wafer map
+    home position using the given die coordinates.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapHome",DieX,DieY)
+
+
+def SaveMapFile(FileName:str="", FileType:str=""):
+    """
+    Saves current map file with specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+        FileType:str = "m"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SaveMapFile",FileName,FileType)
+
+
+def SetWaferMapMode(Mode:str=""):
+    """
+    Enables or disables an external mode for the application. In the external mode,
+    all controls are disabled. The application handles all its remote commands in
+    both modes. Special interactive modes can also be turned on.
+    API Status: published
+    Args:
+        Mode:str = ""
+    Returns:
+        ModeType:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetWaferMapMode",Mode)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetWaferMapMode(ModeType:str=""):
+    """
+    Returns whether the application is in external mode or not.
+    API Status: published
+    Args:
+        ModeType:str = ""
+    Returns:
+        Mode:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapMode",ModeType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferNum(Number:str=""):
+    """
+    Specifies the wafer number.
+    API Status: published
+    Args:
+        Number:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferNum",Number)
+
+
+def GetWaferNum():
+    """
+    Returns the wafer number for the current wafer.
+    API Status: published
+    Returns:
+        Number:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferNum")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWaferID(ID:str=""):
+    """
+    Specifies the ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferID",ID)
+
+
+def GetWaferID():
+    """
+    Returns the wafer ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetProductID(ID:str=""):
+    """
+    Specifies the product ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetProductID",ID)
+
+
+def GetProductID():
+    """
+    Displays the product ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProductID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DoInkerRun():
+    """
+    Instructs the WaferMap to perform an ink run on the current wafer. Returns the
+    number of dies which were inked during the inker run.
+    API Status: published
+    Returns:
+        InkedDies:int
+    Command Timeout: 30000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DoInkerRun")
+    return int(rsp[0])
+
+def CloseWaferMap():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the Wafer Map application.
+    API Status: internal
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("CloseWaferMap")
+
+
+def GetNumSelectedDies():
+    """
+    Gets the number of dies in the map which are selected for probing.
+    API Status: published
+    Returns:
+        SelectedDies:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNumSelectedDies")
+    return int(rsp[0])
+
+def GetSelectedDieCoords(Die:int=""):
+    """
+    Given the index of a selected die in the range [1..NumSelectedDies], returns the
+    column and row indices for the selected die.
+    API Status: published
+    Args:
+        Die:int = 0
+    Returns:
+        DieX:int
+        DieY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSelectedDieCoords",Die)
+    global GetSelectedDieCoords_Response
+    if not "GetSelectedDieCoords_Response" in globals(): GetSelectedDieCoords_Response = namedtuple("GetSelectedDieCoords_Response", "DieX,DieY")
+    return GetSelectedDieCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def StepNextDieOffset(XOffset:Decimal="", YOffset:Decimal="", CDieX:int="", CDieY:int=""):
+    """
+    Moves to a user-specified offset within a die. The optional col row params can
+    be used to specify the die. If they are omitted, WaferMap moves to the specified
+    offset within the next selected die.
+    API Status: published
+    Args:
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextDieOffset",XOffset,YOffset,CDieX,CDieY)
+    global StepNextDieOffset_Response
+    if not "StepNextDieOffset_Response" in globals(): StepNextDieOffset_Response = namedtuple("StepNextDieOffset_Response", "RDieX,RDieY")
+    return StepNextDieOffset_Response(int(rsp[0]),int(rsp[1]))
+
+def ReadMapPosition2(Pos:int="", FromPos:str=""):
+    """
+    Returns the actual Wafer Map chuck position. The SubDie collection is 0-based,
+    the first value is 0, not 1. M_pnCurSite returns the currently selected Subdie
+    (0-based) or -1 if no Subdie is currently selected.  This command is the
+    preferred method for reading Wafer Map chuck position.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        DieX:int
+        DieY:int
+        XFromHome:Decimal
+        YFromHome:Decimal
+        CurSite:int
+        LastSiteIndex:int
+        CurDie:int
+        DiesCount:int
+        CurCluster:int
+        ClustersCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadMapPosition2",Pos,FromPos)
+    global ReadMapPosition2_Response
+    if not "ReadMapPosition2_Response" in globals(): ReadMapPosition2_Response = namedtuple("ReadMapPosition2_Response", "DieX,DieY,XFromHome,YFromHome,CurSite,LastSiteIndex,CurDie,DiesCount,CurCluster,ClustersCount")
+    return ReadMapPosition2_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]))
+
+def DeleteSubDie2(Site:int=""):
+    """
+    Deletes selected subdie. The SubDie collection is 0-based, the first value is 0,
+    not 1.       This command is the preferred method for deleting a selected
+    subdie.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteSubDie2",Site)
+    return int(rsp[0])
+
+def DeleteAllSubDie():
+    """
+    Deletes all subdies for all dies.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("DeleteAllSubDie")
+
+
+def GetDieLabel(DieX:int="", DieY:int=""):
+    """
+    Returns a label from the wafer map at the current die, unless a row and column
+    are specified.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieLabel",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabel(Label:str="", DieX:int="", DieY:int=""):
+    """
+    Assigns a label to the wafer map at the current die, unless a row and column are
+    specified.
+    API Status: published
+    Args:
+        Label:str = ""
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieLabel",Label,DieX,DieY)
+
+
+def StepNextSubDie(Site:int=""):
+    """
+    Steps the chuck to the specified SubDie number relative to the current die
+    origin of the wafer map. Returns the SubDie number of the actual die location
+    after the move is completed and the total number of subdies.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextSubDie",Site)
+    global StepNextSubDie_Response
+    if not "StepNextSubDie_Response" in globals(): StepNextSubDie_Response = namedtuple("StepNextSubDie_Response", "CurSite,LastSiteIndex")
+    return StepNextSubDie_Response(int(rsp[0]),int(rsp[1]))
+
+def OpenWaferMap(FileName:str=""):
+    """
+    Opens a Wafer Map file.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("OpenWaferMap",FileName)
+
+
+def SetDieResult(Result:str="", DieX:int="", DieY:int=""):
+    """
+    Assigns a measurement result to the wafer map at the current die, unless a row
+    and column are specified.
+    API Status: published
+    Args:
+        Result:str = ""
+        DieX:int = 0
+        DieY:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieResult",Result,DieX,DieY)
+
+
+def GetDieResult(DieX:int="", DieY:int=""):
+    """
+    Returns a measurement result from the wafer map at the current die, unless a row
+    and column are specified.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieResult",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResult(Result:str="", DieX:int="", DieY:int="", Site:int=""):
+    """
+    Assigns a measurement result to the wafer die map at the current die and the
+    current subdie, unless a subdie, row, and column are specified. The SubDie
+    collection is 0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Result:str = ""
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieMapResult",Result,DieX,DieY,Site)
+
+
+def GetDieMapResult(DieX:int="", DieY:int="", Site:int=""):
+    """
+    Returns a measurement result from the wafer map at the current die and current
+    subdie, unless a row, column, and subdie are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieMapResult",DieX,DieY,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BinSubDie(Bin:int="", CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Assigns the bin information for the current subdie in the current die, unless a
+    subdie, row, and column are specified. The SubDie collection is 0-based, the
+    first value is 0, not 1.
+    API Status: published
+    Args:
+        Bin:int = 0
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("BinSubDie",Bin,CDieX,CDieY,Site)
+    global BinSubDie_Response
+    if not "BinSubDie_Response" in globals(): BinSubDie_Response = namedtuple("BinSubDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return BinSubDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SetSubDieData(Site:int="", X:Decimal="", Y:Decimal="", Label:str=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        Site:int = 0
+        X:Decimal = 0
+        Y:Decimal = 0
+        Label:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieData",Site,X,Y,Label)
+
+
+def GetSubDieData(Site:int=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        CurSite:int
+        X:Decimal
+        Y:Decimal
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieData",Site)
+    global GetSubDieData_Response
+    if not "GetSubDieData_Response" in globals(): GetSubDieData_Response = namedtuple("GetSubDieData_Response", "CurSite,X,Y,Label")
+    return GetSubDieData_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def GetMapHome():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the home die location of the WaferMap.
+    API Status: internal
+    Returns:
+        DieX:int
+        DieY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapHome")
+    global GetMapHome_Response
+    if not "GetMapHome_Response" in globals(): GetMapHome_Response = namedtuple("GetMapHome_Response", "DieX,DieY")
+    return GetMapHome_Response(int(rsp[0]),int(rsp[1]))
+
+def GetMapDims():
+    """
+    Returns the parameters for the current wafer.
+    API Status: published
+    Returns:
+        MapType:str
+        XIndex:Decimal
+        YIndex:Decimal
+        Columns:int
+        Rows:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapDims")
+    global GetMapDims_Response
+    if not "GetMapDims_Response" in globals(): GetMapDims_Response = namedtuple("GetMapDims_Response", "MapType,XIndex,YIndex,Columns,Rows")
+    return GetMapDims_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetWaferMapParams(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+    """
+    Creates the circle wafer with specified parameters. If parameter is omitted,
+    then zero is used. For this version of the command, units for XOffset and
+    YOffset are percentages.
+    API Status: published
+    Args:
+        Diameter:Decimal = 200
+        DieWidth:Decimal = 10000
+        DieHeight:Decimal = 10000
+        FlatLength:Decimal = 20
+        FlatAngle:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        EdgeArea:Decimal = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferMapParams",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def SetRectMapParams(DieWidth:Decimal="", DieHeight:Decimal="", Columns:int="", Rows:int=""):
+    """
+    Creates the rectangle wafer with specified parameters.
+    API Status: published
+    Args:
+        DieWidth:Decimal = 0
+        DieHeight:Decimal = 0
+        Columns:int = 0
+        Rows:int = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetRectMapParams",DieWidth,DieHeight,Columns,Rows)
+
+
+def StepToDie(DieNumber:int="", Site:int=""):
+    """
+    Steps the chuck to the die location specified by the die number of the wafer
+    map. If no command data is passed, the chuck automatically steps to the next
+    logical wafer map die location. Returns the row and column number of the actual
+    die location after the move is completed. In addition, the SubDie location, and
+    total number of SubDies is also returned.
+    API Status: published
+    Args:
+        DieNumber:int = -1
+        Site:int = 0
+    Returns:
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        LastSiteIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepToDie",DieNumber,Site)
+    global StepToDie_Response
+    if not "StepToDie_Response" in globals(): StepToDie_Response = namedtuple("StepToDie_Response", "RDieX,RDieY,CurSite,LastSiteIndex")
+    return StepToDie_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetMapOrientation(UseOrientationCornerForShift:int=""):
+    """
+    Returns parameters of the map coordinate system.
+    API Status: published
+    Args:
+        UseOrientationCornerForShift:int = 0
+    Returns:
+        Orientation:int
+        OriginShiftX:int
+        OriginShiftY:int
+        UseAlphas:int
+        UseIOs:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapOrientation",UseOrientationCornerForShift)
+    global GetMapOrientation_Response
+    if not "GetMapOrientation_Response" in globals(): GetMapOrientation_Response = namedtuple("GetMapOrientation_Response", "Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs")
+    return GetMapOrientation_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]))
+
+def SetMapOrientation(Orientation:int="", OriginShiftX:int="", OriginShiftY:int="", UseAlphas:int="", UseIOs:int="", UseOrientationCornerForShift:int=""):
+    """
+    Sets up new map origin and new coordinate system after that.
+    API Status: published
+    Args:
+        Orientation:int = 0
+        OriginShiftX:int = 0
+        OriginShiftY:int = 0
+        UseAlphas:int = 0
+        UseIOs:int = 1
+        UseOrientationCornerForShift:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapOrientation",Orientation,OriginShiftX,OriginShiftY,UseAlphas,UseIOs,UseOrientationCornerForShift)
+
+
+def SetDieStatus(DieX:int="", DieY:int="", Status:str=""):
+    """
+    Sets the die status.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Status:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieStatus",DieX,DieY,Status)
+
+
+def GetDieStatus(DieX:int="", DieY:int=""):
+    """
+    Gets the die status.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieStatus",DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieStatus(Site:int="", Status:str=""):
+    """
+    Sets the SubDie status. The SubDie collection is 0-based, the first value is 0,
+    not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+        Status:str = "0"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieStatus",Site,Status)
+
+
+def GetSubDieStatus(Site:int=""):
+    """
+    Returns the SubDie status. The SubDie collection is 0-based, the first value is
+    0, not 1.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieStatus",Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetBinCode(Bin:int=""):
+    """
+    Returns the Die size from the current map.
+    API Status: published
+    Args:
+        Bin:int = 0
+    Returns:
+        Chars:str
+        Color:int
+        Status:str
+        Inker1:int
+        Inker2:int
+        Inker3:int
+        Inker4:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBinCode",Bin)
+    global GetBinCode_Response
+    if not "GetBinCode_Response" in globals(): GetBinCode_Response = namedtuple("GetBinCode_Response", "Chars,Color,Status,Inker1,Inker2,Inker3,Inker4")
+    return GetBinCode_Response(str(rsp[0]),int(rsp[1]),str(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetBinCode(Bin:int="", Chars:str="", Color:int="", Status:str="", Inker1:int="", Inker2:int="", Inker3:int="", Inker4:int=""):
+    """
+    Appends the Bin information to a bin code.
+    API Status: published
+    Args:
+        Bin:int = 0
+        Chars:str = ""
+        Color:int = 0
+        Status:str = ""
+        Inker1:int = 0
+        Inker2:int = 0
+        Inker3:int = 0
+        Inker4:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetBinCode",Bin,Chars,Color,Status,Inker1,Inker2,Inker3,Inker4)
+
+
+def GetDieDataAsNum(CDieIndex:int=""):
+    """
+    Returns the Die Information in the Row Column format. If the Die Number is
+    invalid it returns an error. If the Die Number is absent it uses the current die
+    on the wafer.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        RDieIndex:int
+        DieX:int
+        DieY:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieDataAsNum",CDieIndex)
+    global GetDieDataAsNum_Response
+    if not "GetDieDataAsNum_Response" in globals(): GetDieDataAsNum_Response = namedtuple("GetDieDataAsNum_Response", "RDieIndex,DieX,DieY,Bin,Result")
+    return GetDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsNum(DieIndex:int="", Bin:int="", Result:str=""):
+    """
+    Sets the Die Information. If the Die Number is invalid it returns an error.
+    API Status: published
+    Args:
+        DieIndex:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieDataAsNum",DieIndex,Bin,Result)
+
+
+def GetSubDieDataAsNum(CDieIndex:int="", Site:int=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        RDieIndex:int
+        DieX:int
+        DieY:int
+        CurSite:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsNum",CDieIndex,Site)
+    global GetSubDieDataAsNum_Response
+    if not "GetSubDieDataAsNum_Response" in globals(): GetSubDieDataAsNum_Response = namedtuple("GetSubDieDataAsNum_Response", "RDieIndex,DieX,DieY,CurSite,Bin,Result")
+    return GetSubDieDataAsNum_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsNum(DieIndex:int="", Site:int="", Bin:int="", Result:str=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        DieIndex:int = 0
+        Site:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieDataAsNum",DieIndex,Site,Bin,Result)
+
+
+def GetDieDataAsColRow(CDieX:int="", CDieY:int=""):
+    """
+    Returns the Die Information in the Row Column format. If the Die Number is
+    invalid it returns an error. If the Die Column and Row are absent it uses the
+    current die on the wafer.
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+    Returns:
+        DieIndex:int
+        RDieX:int
+        RDieY:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieDataAsColRow",CDieX,CDieY)
+    global GetDieDataAsColRow_Response
+    if not "GetDieDataAsColRow_Response" in globals(): GetDieDataAsColRow_Response = namedtuple("GetDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,Bin,Result")
+    return GetDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def SetDieDataAsColRow(DieX:int="", DieY:int="", Bin:int="", Result:str=""):
+    """
+    Sets the Data in the Row Column format. If the Die is invalid it returns an
+    error.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieDataAsColRow",DieX,DieY,Bin,Result)
+
+
+def GetSubDieDataAsColRow(CDieX:int="", CDieY:int="", Site:int=""):
+    """
+    Returns the information of a SubDie. The SubDie collection is 0-based, the first
+    value is 0, not 1.
+    API Status: published
+    Args:
+        CDieX:int = 0
+        CDieY:int = 0
+        Site:int = 0
+    Returns:
+        DieIndex:int
+        RDieX:int
+        RDieY:int
+        CurSite:int
+        Bin:int
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieDataAsColRow",CDieX,CDieY,Site)
+    global GetSubDieDataAsColRow_Response
+    if not "GetSubDieDataAsColRow_Response" in globals(): GetSubDieDataAsColRow_Response = namedtuple("GetSubDieDataAsColRow_Response", "DieIndex,RDieX,RDieY,CurSite,Bin,Result")
+    return GetSubDieDataAsColRow_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def SetSubDieDataAsColRow(DieX:int="", DieY:int="", Site:int="", Bin:int="", Result:str=""):
+    """
+    Sets up SubDie data. The SubDie collection is 0-based, the first value is 0, not
+    1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+        Bin:int = 0
+        Result:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieDataAsColRow",DieX,DieY,Site,Bin,Result)
+
+
+def SelectAllDiesForProbing(DoSelectAll:int="", DoEdgeDies:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables all dies.
+    API Status: internal
+    Args:
+        DoSelectAll:int = 0
+        DoEdgeDies:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SelectAllDiesForProbing",DoSelectAll,DoEdgeDies)
+
+
+def GetMapName():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current WaferMap Filename.
+    API Status: internal
+    Returns:
+        Name:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapName")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetLotID(ID:str=""):
+    """
+    Specifies the ID for the current wafer.
+    API Status: published
+    Args:
+        ID:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetLotID",ID)
+
+
+def GetLotID():
+    """
+    Returns the Lot ID for the current wafer.
+    API Status: published
+    Returns:
+        ID:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetLotID")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StepFirstCluster(ClearBins:int="", RecalcRoute:int=""):
+    """
+    Steps the chuck to the first die cluster of the cluster map. If clusters are not
+    defined, the first Die is used. Returns the row and column information of the
+    actual cluster and die location after the move is completed. Switches to remote
+    control if the "Disable Velox" flag is set in the external options window.
+    API Status: published
+    Args:
+        ClearBins:int = 1
+        RecalcRoute:int = 1
+    Returns:
+        ClusterX:int
+        ClusterY:int
+        ClusterIndex:int
+        IncompleteCluster:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFirstCluster",ClearBins,RecalcRoute)
+    global StepFirstCluster_Response
+    if not "StepFirstCluster_Response" in globals(): StepFirstCluster_Response = namedtuple("StepFirstCluster_Response", "ClusterX,ClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+    return StepFirstCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def StepNextCluster(CClusterX:int="", CClusterY:int=""):
+    """
+    Steps the chuck to the specified x,y cluster die location of the cluster map. If
+    no command data is passed, the chuck automatically steps to the next logical
+    cluster map location. If clusters are not defined, the Die information is used.
+    Returns the row and column number of the actual die location after the move is
+    completed.
+    API Status: published
+    Args:
+        CClusterX:int = 0
+        CClusterY:int = 0
+    Returns:
+        RClusterX:int
+        RClusterY:int
+        ClusterIndex:int
+        IncompleteCluster:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepNextCluster",CClusterX,CClusterY)
+    global StepNextCluster_Response
+    if not "StepNextCluster_Response" in globals(): StepNextCluster_Response = namedtuple("StepNextCluster_Response", "RClusterX,RClusterY,ClusterIndex,IncompleteCluster,DieX,DieY,DieIndex")
+    return StepNextCluster_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def SetMapRoute(MoveMode:str="", StartColumn:str="", StartRow:str="", MoveParam:str=""):
+    """
+    Specifies the Move Path for the probe station inside the Wafer Map. Optimization
+    is done for the shortest move way for the station.
+    API Status: published
+    Args:
+        MoveMode:str = "B"
+        StartColumn:str = "L"
+        StartRow:str = "T"
+        MoveParam:str = "H"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetMapRoute",MoveMode,StartColumn,StartRow,MoveParam)
+
+
+def GetMapRoute():
+    """
+    Returns the specified move path for the probe station inside the Wafer Map.
+    API Status: published
+    Returns:
+        MoveMode:str
+        StartColumn:str
+        StartRow:str
+        MoveParam:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetMapRoute")
+    global GetMapRoute_Response
+    if not "GetMapRoute_Response" in globals(): GetMapRoute_Response = namedtuple("GetMapRoute_Response", "MoveMode,StartColumn,StartRow,MoveParam")
+    return GetMapRoute_Response(str(rsp[0]),str(rsp[1]),str(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def SetClusterParams(UseClusters:int="", ClusterWidth:int="", ClusterHeight:int="", TestIncomplete:int=""):
+    """
+    Specifies the clusters parameters.
+    API Status: published
+    Args:
+        UseClusters:int = 0
+        ClusterWidth:int = 1
+        ClusterHeight:int = 1
+        TestIncomplete:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetClusterParams",UseClusters,ClusterWidth,ClusterHeight,TestIncomplete)
+
+
+def GetClusterParams():
+    """
+    Returns current clusters parameters.
+    API Status: published
+    Returns:
+        UseClusters:int
+        ClusterWidth:int
+        ClusterHeight:int
+        TestIncomplete:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterParams")
+    global GetClusterParams_Response
+    if not "GetClusterParams_Response" in globals(): GetClusterParams_Response = namedtuple("GetClusterParams_Response", "UseClusters,ClusterWidth,ClusterHeight,TestIncomplete")
+    return GetClusterParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def NewWaferMap():
+    """
+    Deletes current wafer map, sub dies and binning information; then creates new
+    wafer map with defaults parameters.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("NewWaferMap")
+
+
+def AddSubDie(X:Decimal="", Y:Decimal="", Label:str=""):
+    """
+    Adds new subdie at the end of the table.
+    API Status: published
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+        Label:str = ""
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("AddSubDie",X,Y,Label)
+    return int(rsp[0])
+
+def DeleteSubDie(Site:int=""):
+    """
+    Deletes selected subdie. The SubDie collection is 1-based, the first value is 1,
+    not 0. If 0 is passed in as the subdie index, WaferMap will delete all subdies
+    for all dies.This command (i.e. DeleteSubDie) has been included for legacy
+    support.       DeleteSubDie2 is the preferred method for deleting a selected
+    subdie. DeleteAllSubDie is the preferred method for deleting all subdies for all
+    dies.
+    API Status: published
+    Args:
+        Site:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DeleteSubDie",Site)
+    return int(rsp[0])
+
+def GetNumSelectedClusters():
+    """
+    Gets the number of clusters in the map which are selected for probing.
+    API Status: published
+    Returns:
+        SelectedClusters:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetNumSelectedClusters")
+    return int(rsp[0])
+
+def GetSelectedClusterCoords(ClusterIndex:int=""):
+    """
+    Given the index of a selected cluster in the range [1..NumSelectedClusters],
+    returns the column and row indices for the selected cluster.
+    API Status: published
+    Args:
+        ClusterIndex:int = 0
+    Returns:
+        ClusterX:int
+        ClusterY:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSelectedClusterCoords",ClusterIndex)
+    global GetSelectedClusterCoords_Response
+    if not "GetSelectedClusterCoords_Response" in globals(): GetSelectedClusterCoords_Response = namedtuple("GetSelectedClusterCoords_Response", "ClusterX,ClusterY")
+    return GetSelectedClusterCoords_Response(int(rsp[0]),int(rsp[1]))
+
+def GetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int=""):
+    """
+    Gets the die status in the cluster. Die coordinates are internal for the cluster
+    using the wafer map coordinate system. (0,0) die in the cluster is left top
+    corner (whether this die exists or not).
+    API Status: published
+    Args:
+        ClusterX:int = 0
+        ClusterY:int = 0
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        Status:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterDieStatus",ClusterX,ClusterY,DieX,DieY)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetClusterDieStatus(ClusterX:int="", ClusterY:int="", DieX:int="", DieY:int="", Status:str=""):
+    """
+    Sets the die status in the cluster. Die coordinates are internal for the cluster
+    using the wafer map coordinate system. (0,0) die in the cluster is left top
+    corner (whether this die exists or not).
+    API Status: published
+    Args:
+        ClusterX:int = 0
+        ClusterY:int = 0
+        DieX:int = 0
+        DieY:int = 0
+        Status:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetClusterDieStatus",ClusterX,ClusterY,DieX,DieY,Status)
+
+
+def OpenBinCodeTable(FileName:str=""):
+    """
+    Opens a Bin Code Table file (.bct) with the specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("OpenBinCodeTable",FileName)
+
+
+def SaveBinCodeTable(FileName:str=""):
+    """
+    Saves bin code table to a file with the specified name.
+    API Status: published
+    Args:
+        FileName:str = ""
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SaveBinCodeTable",FileName)
+
+
+def SetBinTableSize(BinsSize:int=""):
+    """
+    Sets size of the bin code table. This is the size of bins used in statistics and
+    binning.
+    API Status: published
+    Args:
+        BinsSize:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetBinTableSize",BinsSize)
+
+
+def GetBinTableSize():
+    """
+    Gets size of the bin code table.
+    API Status: published
+    Returns:
+        BinsSize:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetBinTableSize")
+    return int(rsp[0])
+
+def StepFailedClusterBack():
+    """
+    Steps the chuck the consecutive failed clusters back (goes back to the last
+    known good cluster) and returns the number of consecutive failed clusters.
+    API Status: published
+    Returns:
+        FailedClusters:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedClusterBack")
+    return int(rsp[0])
+
+def StepFailedClusterForward():
+    """
+    Steps the chuck the consecutive failed clusters forward and returns the number
+    of consecutive failed clusters (goes to next untested cluster).
+    API Status: published
+    Returns:
+        FailedClusters:int
+    Command Timeout: 6000000
+    """
+    rsp = MessageServerInterface.sendSciCommand("StepFailedClusterForward")
+    return int(rsp[0])
+
+def GoToWaferHome():
+    """
+    Moves the chuck to the wafer home position.
+    API Status: published
+    Command Timeout: 6000000
+    """
+    MessageServerInterface.sendSciCommand("GoToWaferHome")
+
+
+def GetWaferInfo():
+    """
+    Returns a number of all units marked to test. Note that TestSites is a number of
+    all sites for all dies.
+    API Status: published
+    Returns:
+        ClustersCount:int
+        DiesCount:int
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferInfo")
+    global GetWaferInfo_Response
+    if not "GetWaferInfo_Response" in globals(): GetWaferInfo_Response = namedtuple("GetWaferInfo_Response", "ClustersCount,DiesCount,SitesCount")
+    return GetWaferInfo_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetClusterInfo(Cluster:int=""):
+    """
+    Returns a number of all dies and sites marked to test in the given cluster.
+    API Status: published
+    Args:
+        Cluster:int = 0
+    Returns:
+        DiesCount:int
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetClusterInfo",Cluster)
+    global GetClusterInfo_Response
+    if not "GetClusterInfo_Response" in globals(): GetClusterInfo_Response = namedtuple("GetClusterInfo_Response", "DiesCount,SitesCount")
+    return GetClusterInfo_Response(int(rsp[0]),int(rsp[1]))
+
+def GetDieInfo(Die:int=""):
+    """
+    Returns a number of sites marked to test in the given die.
+    API Status: published
+    Args:
+        Die:int = 0
+    Returns:
+        SitesCount:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieInfo",Die)
+    return int(rsp[0])
+
+def ConvertToAlphas(Start:int="", Finish:int=""):
+    """
+    Returns a string of the alpha column coordinates for the given range divided by
+    spaces.
+    API Status: published
+    Args:
+        Start:int = 0
+        Finish:int = 0
+    Returns:
+        Alphas:str
+    Command Timeout: 240000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ConvertToAlphas",Start,Finish)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetActiveLayer(Layer:str=""):
+    """
+    Sets new active layer.
+    API Status: published
+    Args:
+        Layer:str = ""
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetActiveLayer",Layer)
+
+
+def GetActiveLayer():
+    """
+    Returns current active layer.
+    API Status: published
+    Returns:
+        Layer:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetActiveLayer")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieRefPoint(RefX:Decimal="", RefY:Decimal=""):
+    """
+    Sets a new reference point for the die. This point is NOT used for die stepping,
+    nor for subdie stepping. When using the "Chuck Position from Reference" WaferMap
+    GUI setting, the Die Reference Point can be set to be more representative of the
+    actual reference location within the die. A setting of (0.0, 0.0) is defined as
+    the upper left corner of the die. All subdie coordinates are relative to upper
+    left corner of the die.
+    API Status: published
+    Args:
+        RefX:Decimal = 0
+        RefY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieRefPoint",RefX,RefY)
+
+
+def GetDieRefPoint():
+    """
+    Returns current reference point for the die. For details see SetDieRefPoint
+    command.
+    API Status: published
+    Returns:
+        RefX:Decimal
+        RefY:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieRefPoint")
+    global GetDieRefPoint_Response
+    if not "GetDieRefPoint_Response" in globals(): GetDieRefPoint_Response = namedtuple("GetDieRefPoint_Response", "RefX,RefY")
+    return GetDieRefPoint_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ClearAllBins():
+    """
+    Clears all binning data in the wafer map.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("ClearAllBins")
+
+
+def SetWindowState(State:str="", Window:str=""):
+    """
+    Has sense in the application only (not for ActiveX controls). It shows or hides
+    a window. All parameters are case-insensitive.
+    API Status: published
+    Args:
+        State:str = "s"
+        Window:str = "setup"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWindowState",State,Window)
+
+
+def SetCurrentBin(Bin:int="", ButtonStatus:int=""):
+    """
+    Sets the current bin for the application. Second parameter allows to enable or
+    disable "Mark with Bin" mode in the application.
+    API Status: published
+    Args:
+        Bin:int = 0
+        ButtonStatus:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetCurrentBin",Bin,ButtonStatus)
+
+
+def GetCurrentBin():
+    """
+    Returns the current bin in the application.
+    API Status: published
+    Returns:
+        Bin:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCurrentBin")
+    return int(rsp[0])
+
+def ReadClusterPosition(Pos:int="", FromPos:str=""):
+    """
+    Returns the actual wafer map cluster position. If the cluster probing is
+    disabled, the command will assume a cluster of size 1x1.
+    API Status: published
+    Args:
+        Pos:int = 0
+        FromPos:str = "R"
+    Returns:
+        ClusterX:int
+        ClusterY:int
+        ClusterIndex:int
+        DieX:int
+        DieY:int
+        DieIndex:int
+        ClusterWidth:int
+        ClusterHeight:int
+        EnabledDies:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadClusterPosition",Pos,FromPos)
+    global ReadClusterPosition_Response
+    if not "ReadClusterPosition_Response" in globals(): ReadClusterPosition_Response = namedtuple("ReadClusterPosition_Response", "ClusterX,ClusterY,ClusterIndex,DieX,DieY,DieIndex,ClusterWidth,ClusterHeight,EnabledDies")
+    return ReadClusterPosition_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),str("" if len(rsp) < 9 else ' '.join(rsp[8:])))
+
+def GetWaferMapParams():
+    """
+    Returns the circle wafer parameters. For this version of the command, units for
+    XOffset and YOffset are percentages.
+    API Status: published
+    Returns:
+        Diameter:Decimal
+        DieWidth:Decimal
+        DieHeight:Decimal
+        FlatLength:Decimal
+        FlatAngle:int
+        XOffset:Decimal
+        YOffset:Decimal
+        EdgeArea:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams")
+    global GetWaferMapParams_Response
+    if not "GetWaferMapParams_Response" in globals(): GetWaferMapParams_Response = namedtuple("GetWaferMapParams_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+    return GetWaferMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def GetRectMapParams():
+    """
+    Creates a rectangular wafermap with specified parameters.
+    API Status: published
+    Returns:
+        DieWidth:Decimal
+        DieHeight:Decimal
+        Columns:int
+        Rows:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetRectMapParams")
+    global GetRectMapParams_Response
+    if not "GetRectMapParams_Response" in globals(): GetRectMapParams_Response = namedtuple("GetRectMapParams_Response", "DieWidth,DieHeight,Columns,Rows")
+    return GetRectMapParams_Response(Decimal(rsp[0]),Decimal(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def SyncMapHome(X:Decimal="", Y:Decimal=""):
+    """
+    Tries to find an appropriate position in the wafer for the current chuck
+    position. X and Y describe the chuck position of the wafer center relatively to
+    the chuck zero position. If the wafer position is found the command sets it as
+    the wafer map home position and sets the current chuck position as the chuck
+    home position. If there is no corresponding wafer position the command returns
+    error 701. Command is used by AutoAlign for the BuildMap feature.
+    API Status: published
+    Args:
+        X:Decimal = 0
+        Y:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SyncMapHome",X,Y)
+
+
+def SetWaferProfileOptions(ProfileSensor:str="", SearchSpeed:Decimal="", Gap:Decimal="", SuccessRatio:Decimal="", ProfDistX:Decimal="", ProfDistY:Decimal=""):
+    """
+    Sets some WaferMap profiling options remotely.
+    API Status: published
+    Args:
+        ProfileSensor:str = "e"
+        SearchSpeed:Decimal = 50
+        Gap:Decimal = 10
+        SuccessRatio:Decimal = 75
+        ProfDistX:Decimal = 0
+        ProfDistY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferProfileOptions",ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY)
+
+
+def GetWaferProfileOptions():
+    """
+    Returns predefined settings of the WaferMap profiling options.
+    API Status: published
+    Returns:
+        ProfileSensor:str
+        SearchSpeed:Decimal
+        Gap:Decimal
+        SuccessRatio:Decimal
+        ProfDistX:Decimal
+        ProfDistY:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferProfileOptions")
+    global GetWaferProfileOptions_Response
+    if not "GetWaferProfileOptions_Response" in globals(): GetWaferProfileOptions_Response = namedtuple("GetWaferProfileOptions_Response", "ProfileSensor,SearchSpeed,Gap,SuccessRatio,ProfDistX,ProfDistY")
+    return GetWaferProfileOptions_Response(str(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def StartWaferProfiling(DoContinue:int=""):
+    """
+    Starts the profiling process. To determine the current profiling state, use
+    GetWaferProfilingStatus command.
+    API Status: published
+    Args:
+        DoContinue:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("StartWaferProfiling",DoContinue)
+
+
+def GetWaferProfilingStatus():
+    """
+    Returns status of the profiling process. If this status is true, the process is
+    started.
+    API Status: published
+    Returns:
+        Started:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferProfilingStatus")
+    return int(rsp[0])
+
+def StopWaferProfiling():
+    """
+    Stops the profiling process.
+    API Status: published
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("StopWaferProfiling")
+
+
+def DoWaferProfiling():
+    """
+    Profiles the wafer and returns a status of the profiling as an error code.
+    API Status: published
+    Command Timeout: 36000000
+    """
+    MessageServerInterface.sendSciCommand("DoWaferProfiling")
+
+
+def DoWaferProfilingOffAxis():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Profiles the wafer and returns a status of the profiling as an error code.
+    Executes profiling using the off axis camera
+    API Status: internal
+    Command Timeout: 36000000
+    """
+    MessageServerInterface.sendSciCommand("DoWaferProfilingOffAxis")
+
+
+def GetSubDieLabel(DieX:int="", DieY:int="", Site:int=""):
+    """
+    Returns a label from the wafer map at the current die and current subdie, unless
+    a row, column, and subdie are specified. The SubDie collection is 0-based, the
+    first value is 0, not 1.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieLabel",DieX,DieY,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabel(Label:str="", DieX:int="", DieY:int="", Site:int=""):
+    """
+    Assigns a label to the wafer map at the current die and the current subdie,
+    unless a subdie, row, and column are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Label:str = ""
+        DieX:int = 0
+        DieY:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieLabel",Label,DieX,DieY,Site)
+
+
+def GetSubDieLabelAsNum(CDieIndex:int="", Site:int=""):
+    """
+    Returns a label from the wafer map the current die and the current subdie,
+    unless a subdie, and die number are specified. The SubDie collection is 0-based,
+    the first value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSubDieLabelAsNum",CDieIndex,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSubDieLabelAsNum(Label:str="", CDieIndex:int="", Site:int=""):
+    """
+    Assigns a label to the wafer map at the current die and the current subdie,
+    unless a subdie, and die number are specified. The SubDie collection is 0-based,
+    the first value is 0, not 1.
+    API Status: published
+    Args:
+        Label:str = ""
+        CDieIndex:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetSubDieLabelAsNum",Label,CDieIndex,Site)
+
+
+def GetDieLabelAsNum(CDieIndex:int=""):
+    """
+    Returns a label from the wafer map at the current die, unless a die number is
+    specified.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        Label:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieLabelAsNum",CDieIndex)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieLabelAsNum(Label:str="", CDieIndex:int=""):
+    """
+    Assigns a label to the wafer map at the current die, unless a die number is
+    specified.
+    API Status: published
+    Args:
+        Label:str = ""
+        CDieIndex:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieLabelAsNum",Label,CDieIndex)
+
+
+def GetHomeDieOffset():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the XY offset from the reference position of the Home Die to wafer
+    center in chuck coordinates.
+    API Status: internal
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHomeDieOffset")
+    global GetHomeDieOffset_Response
+    if not "GetHomeDieOffset_Response" in globals(): GetHomeDieOffset_Response = namedtuple("GetHomeDieOffset_Response", "X,Y")
+    return GetHomeDieOffset_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetWaferMapParams2(Diameter:Decimal="", DieWidth:Decimal="", DieHeight:Decimal="", FlatLength:Decimal="", FlatAngle:int="", XOffset:Decimal="", YOffset:Decimal="", EdgeArea:Decimal=""):
+    """
+    Creates the circle wafer with specified parameters. If parameter is omitted,
+    then zero is used. For this version of the command, units for XOffset and
+    YOffset are microns.
+    API Status: published
+    Args:
+        Diameter:Decimal = 200
+        DieWidth:Decimal = 10000
+        DieHeight:Decimal = 10000
+        FlatLength:Decimal = 20
+        FlatAngle:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+        EdgeArea:Decimal = 0
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferMapParams2",Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea)
+
+
+def GetWaferMapParams2():
+    """
+    Returns the circle wafer parameters. For this version of the command, units for
+    XOffset and YOffset are microns.
+    API Status: published
+    Returns:
+        Diameter:Decimal
+        DieWidth:Decimal
+        DieHeight:Decimal
+        FlatLength:Decimal
+        FlatAngle:int
+        XOffset:Decimal
+        YOffset:Decimal
+        EdgeArea:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferMapParams2")
+    global GetWaferMapParams2_Response
+    if not "GetWaferMapParams2_Response" in globals(): GetWaferMapParams2_Response = namedtuple("GetWaferMapParams2_Response", "Diameter,DieWidth,DieHeight,FlatLength,FlatAngle,XOffset,YOffset,EdgeArea")
+    return GetWaferMapParams2_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),Decimal(rsp[5]),Decimal(rsp[6]),Decimal(rsp[7]))
+
+def SetWaferTestAngle(Angle:int=""):
+    """
+    This command sets the Wafer Test Angle. This is different from the notch angle
+    and allows rotating the WaferMap.
+    API Status: published
+    Args:
+        Angle:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetWaferTestAngle",Angle)
+
+
+def GetWaferTestAngle():
+    """
+    This returns the Wafer Test Angle. This is different from the notch angle and
+    allows rotating the WaferMap.
+    API Status: published
+    Returns:
+        Angle:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferTestAngle")
+    return int(rsp[0])
+
+def LoadPreMappedDiesTable(FileName:str="", ClearMap:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Loads the Pre-Mapped Dies Table file with specified name.
+    API Status: internal
+    Args:
+        FileName:str = ""
+        ClearMap:int = 1
+    Command Timeout: 240000
+    """
+    MessageServerInterface.sendSciCommand("LoadPreMappedDiesTable",FileName,ClearMap)
+
+
+def GetPreMappedDieInfo(DieX:int="", DieY:int=""):
+    """
+    This command is valid when a PreMapped Dies Table has been loaded. Returns
+    values at the current die, unless a column (M_pnDieX) and row (M_pnDieY) are
+    specified.  Returns actual (as measured during the Pre-Mapping) x, y, z, and
+    theta die positions. Also returns whether or not Z and Theta are being used.
+    This command is only valid when a Pre-Mapped Dies Table has been loaded. If a
+    PreMapped Dies Table has NOT been loaded, ERR_IllegalParameters (715) is
+    returned.
+    API Status: published
+    Args:
+        DieX:int = 0
+        DieY:int = 0
+    Returns:
+        UseZ:int
+        UseTheta:int
+        ActualX:Decimal
+        ActualY:Decimal
+        ActualZ:Decimal
+        Theta:Decimal
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPreMappedDieInfo",DieX,DieY)
+    global GetPreMappedDieInfo_Response
+    if not "GetPreMappedDieInfo_Response" in globals(): GetPreMappedDieInfo_Response = namedtuple("GetPreMappedDieInfo_Response", "UseZ,UseTheta,ActualX,ActualY,ActualZ,Theta")
+    return GetPreMappedDieInfo_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def GetDieResultAsNum(CDieIndex:int=""):
+    """
+    Returns a measurement result from the wafer map at the current die, unless a die
+    number is specified.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieResultAsNum",CDieIndex)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieResultAsNum(Result:str="", CDieIndex:int=""):
+    """
+    Assigns a measurement result to the wafer map at the current die, unless a die
+    number is specified.
+    API Status: published
+    Args:
+        Result:str = ""
+        CDieIndex:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieResultAsNum",Result,CDieIndex)
+
+
+def GetDieMapResultAsNum(CDieIndex:int="", Site:int=""):
+    """
+    Returns a measurement result from the wafer map the current die and the current
+    subdie, unless a subdie, and die number are specified. The SubDie collection is
+    0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        CDieIndex:int = 0
+        Site:int = 0
+    Returns:
+        Result:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDieMapResultAsNum",CDieIndex,Site)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetDieMapResultAsNum(Result:str="", CDieIndex:int="", Site:int=""):
+    """
+    Assigns a measurement result to the wafer die map at the current die at the
+    current subdie, unless a subdie, and die number are specified. The SubDie
+    collection is 0-based, the first value is 0, not 1.
+    API Status: published
+    Args:
+        Result:str = ""
+        CDieIndex:int = 0
+        Site:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetDieMapResultAsNum",Result,CDieIndex,Site)
+
+
+def MapEdgeDies(Enable:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Enables or disables edge dies for test
+    API Status: internal
+    Args:
+        Enable:int = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("MapEdgeDies",Enable)
+
+
+def GetSpectrumData(DataPath:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows access to read any data item in Spectrum explorer.     GetSpectrumData
+    AlignWafer/ProjectData/Mark1/ChuckPosition/X     GetSpectrumData Chuck
+    Camera/Camera Settings/Shutter
+    API Status: internal
+    Args:
+        DataPath:str = ""
+    Returns:
+        Value:str
+    Command Timeout: 6000
+    Example:GetSpectrumData Chuck Camera/Camera Settings/Shutter
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSpectrumData",DataPath)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumData(PathAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Allows changing any data item in Spectrum explorer. Works independent of access
+    level. SetSpectrumData AlignWafer/ProjectData/Mark1/ChuckPosition/X=1000
+    SetSpectrumData Chuck Camera/Camera Settings/Shutter=17
+    API Status: internal
+    Args:
+        PathAndValue:str = ""
+    Command Timeout: 6000
+    Example:SetSpectrumData Scope Camera/Camera Settings/Shutter=17
+    """
+    MessageServerInterface.sendSciCommand("SetSpectrumData",PathAndValue)
+
+
+def ReadVMPosition(ToolName:str="", XY:int="", Z:int="", Model:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command reads the current chuck and microscope position and sets them as
+    new controller or chuck and microscope positions.     The command was originally used
+    by ReAlignWizard but may be removed in the future because of direct access to
+    tooldata     within Spectrum.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        XY:int = 1
+        Z:int = 0
+        Model:int = -1
+    Command Timeout: 60000
+    Example:ReadVMPosition AlignWafer 1 0 0
+    """
+    MessageServerInterface.sendSciCommand("ReadVMPosition",ToolName,XY,Z,Model)
+
+
+def MoveToVMPosition(ToolName:str="", XYChuck:int="", ZChuck:int="", XYScope:int="", ZScope:int="", Model:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command moves to trained stages positions of a requested tool. Command is
+    used by ReAlignWizard to move to     the trained positions for AutoAlign and
+    DetectWaferHeight.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        XYChuck:int = 1
+        ZChuck:int = 1
+        XYScope:int = 0
+        ZScope:int = 0
+        Model:int = -1
+    Command Timeout: 120000
+    Example:MoveToVMPosition AlignWafer 1 0 0 0 0
+    """
+    MessageServerInterface.sendSciCommand("MoveToVMPosition",ToolName,XYChuck,ZChuck,XYScope,ZScope,Model)
+
+
+def ShapeTracker(SetHome:int="", AutoEdgeFind:int="", FileName:str=""):
+    """
+    ShapeTracker automatically tracks the shape of a substrate (e.g. a broken wafer)
+    to determine the contour of it. The data will be memorized as xy coordinates of
+    contour points referenced to the home position. These Points are written to a
+    file after tracking the shape.
+    API Status: published
+    Args:
+        SetHome:int = 1
+        AutoEdgeFind:int = 0
+        FileName:str = ""
+    Command Timeout: 600000
+    Example:ShapeTracker 1
+    """
+    MessageServerInterface.sendSciCommand("ShapeTracker",SetHome,AutoEdgeFind,FileName)
+
+
+def DetectWaferHeight(SetStartPosition:int="", Synchronize:int="", ChuckX:Decimal="", ChuckY:Decimal=""):
+    """
+    Synchronizes chuck and top camera in X, Y and Z. Then the wafer surface is
+    focused on the trained chuck position or the manual adjusted reference position.
+    This tool uses the FindFocus tool with its own Range.
+    API Status: published
+    Args:
+        SetStartPosition:int = 0
+        Synchronize:int = 0
+        ChuckX:Decimal = -1
+        ChuckY:Decimal = -1
+    Returns:
+        PositionX:Decimal
+        PositionY:Decimal
+        WaferHeight:Decimal
+        SynchGap:Decimal
+        ZOffset:Decimal
+        Stage:str
+    Command Timeout: 300000
+    Example:DetectWaferHeight 0 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("DetectWaferHeight",SetStartPosition,Synchronize,ChuckX,ChuckY)
+    global DetectWaferHeight_Response
+    if not "DetectWaferHeight_Response" in globals(): DetectWaferHeight_Response = namedtuple("DetectWaferHeight_Response", "PositionX,PositionY,WaferHeight,SynchGap,ZOffset,Stage")
+    return DetectWaferHeight_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),str("" if len(rsp) < 6 else ' '.join(rsp[5:])))
+
+def CheckSpectrumPlugin(Plugin:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command checks if a plugin is trained and returns a string of error/warning
+    messages including information about what is not trained, setup for the tool to
+    run.
+    API Status: internal
+    Args:
+        Plugin:str = ""
+    Returns:
+        PluginAvailable:int
+        Message:str
+    Command Timeout: 1000
+    Example:CheckSpectrumPlugin AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("CheckSpectrumPlugin",Plugin)
+    global CheckSpectrumPlugin_Response
+    if not "CheckSpectrumPlugin_Response" in globals(): CheckSpectrumPlugin_Response = namedtuple("CheckSpectrumPlugin_Response", "PluginAvailable,Message")
+    return CheckSpectrumPlugin_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AutoAlign(SetValue:int="", SkipSettingHome:int=""):
+    """
+    Executes the AutoAlign tool to do a theta alignment of the wafer with optional
+    index calculation or thermal expansion measurement. The command will update home
+    if home was trained. It will only move to its trained chuck/scope position
+    before starting the alignment if the option "MoveToTrainedXYPosition" and/or
+    "MoveToTrainedZPosition" is true.
+    API Status: published
+    Args:
+        SetValue:int = 0
+        SkipSettingHome:int = 0
+    Command Timeout: 300000
+    Example:AutoAlign 1
+    """
+    MessageServerInterface.sendSciCommand("AutoAlign",SetValue,SkipSettingHome)
+
+
+def SetCameraQuiet(Active:int=""):
+    """
+    Activates/deactivates the camera quiet mode. (Applies only to ATM300A and
+    SPS300/SUMMIT200 stations.)     The camera quiet mode deactivates the chuck,
+    platen and contact view camera and triggers a digital output     which
+    connects/disconnects these cameras firewire connection to the PC.
+    API Status: published
+    Args:
+        Active:int = 0
+    Command Timeout: 30000
+    Example:SetCameraQuiet 1
+    """
+    MessageServerInterface.sendSciCommand("SetCameraQuiet",Active)
+
+
+def SetRefDieOffset(RefDieCol:int="", RefDieRow:int="", RefDieDistToCentreX:Decimal="", RefDieDistToCentreY:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is based on the SetMapOrientation command. It allows shifting the
+    center of the reference die to the center of the wafer.
+    API Status: internal
+    Args:
+        RefDieCol:int = 0
+        RefDieRow:int = 0
+        RefDieDistToCentreX:Decimal = 0
+        RefDieDistToCentreY:Decimal = 0
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetRefDieOffset",RefDieCol,RefDieRow,RefDieDistToCentreX,RefDieDistToCentreY)
+
+
+def AlignWafer(TrackPosition:int=""):
+    """
+    Performs a two-point alignment and moves chuck to the trained align position. XY
+    correction is made afterwards to calculate the new home position.
+    API Status: published
+    Args:
+        TrackPosition:int = 0
+    Returns:
+        ThetaOffset:Decimal
+    Command Timeout: 120000
+    Example:AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignWafer",TrackPosition)
+    return Decimal(rsp[0])
+
+def AlignChip():
+    """
+    Performs a single or two point alignment and moves the current chip to the
+    trained aligned position in Theta (in degrees) and X, Y (in microns). The
+    current chip is assumed to be in the region of interest when the command is
+    called.
+    API Status: published
+    Returns:
+        ThetaOffset:Decimal
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 180000
+    Example:AlignChip
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignChip")
+    global AlignChip_Response
+    if not "AlignChip_Response" in globals(): AlignChip_Response = namedtuple("AlignChip_Response", "ThetaOffset,XOffset,YOffset")
+    return AlignChip_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def FindFocus(StepCount:int="", Range:Decimal=""):
+    """
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search.
+    API Status: published
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocus 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocus",StepCount,Range)
+    global FindFocus_Response
+    if not "FindFocus_Response" in globals(): FindFocus_Response = namedtuple("FindFocus_Response", "ZPosition,Stage")
+    return FindFocus_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAux(AuxSiteID:int=""):
+    """
+    Performs an automated aux site alignment in XYZ. Tool can correct reference
+    position and contact height for the given aux site.
+    API Status: published
+    Args:
+        AuxSiteID:int = 0
+    Command Timeout: 300000
+    Example:AlignAux 1
+    """
+    MessageServerInterface.sendSciCommand("AlignAux",AuxSiteID)
+
+
+def FindFeature(Model:int="", ReturnDistanceFromModelOrigin:int="", UseSingleImageAcquisition:int=""):
+    """
+    Search user-defined models. Up to 40 different models can be trained. After
+    training, these models can be searched on screen either by direct user
+    interaction or from external applications with a remote command. The remote
+    command returns the X/Y-Positions, angle (degree) and score value (0 - 1.0) for
+    each instance of the controller found in the region of interest.
+    API Status: published
+    Args:
+        Model:int = 1
+        ReturnDistanceFromModelOrigin:int = 0
+        UseSingleImageAcquisition:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 10000
+    Example:FindFeature 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFeature",Model,ReturnDistanceFromModelOrigin,UseSingleImageAcquisition)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CloseSpectrum():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    CloseSpectrum closes the Spectrum application. Used internally by CommonCommands
+    during Project loading. Does save configuration data but does not save project
+    data.
+    API Status: internal
+    Command Timeout: 6000
+    Example:CloseSpectrum
+    """
+    MessageServerInterface.sendSciCommand("CloseSpectrum")
+
+
+def SnapImage(MountPos:str="", FullPath:str="", SnapShotMode:int=""):
+    """
+    Saves the currently displayed image to the specified file. The image is stored
+    in the requested file format (bmp, jpg or png). By default. it will save the raw
+    camera image and an image with the overlays that are currently visible on the
+    camera view. Using a parameter, one can decide to only save either raw image,
+    overlay image or both. By Specifying 'ALL' as the mount position, the captured
+    screenshot will consist of the currently selected camera layout without
+    providing the raw image. If MountPos and FullPath are empty then the current
+    camera view with overlays is copied to the clipboard.
+    API Status: published
+    Args:
+        MountPos:str = "Scope"
+        FullPath:str = "Image.bmp"
+        SnapShotMode:int = 2
+    Command Timeout: 60000
+    Example:SnapImage Scope C:/Temp/Image.bmp
+    """
+    MessageServerInterface.sendSciCommand("SnapImage",MountPos,FullPath,SnapShotMode)
+
+
+def SetCameraView(Name:str="", Zoom:int="", LiveVideo:int="", WindowState:int=""):
+    """
+    Switches the desired video window of Spectrum as foreground and active view. The
+    camera view can be determined over a tool name or the camera mount position. The
+    second parameter defines the displays zoom factor to be used. Third parameter is
+    used to toogle the live video. Last parameter can be used to maximize a window.
+    API Status: published
+    Args:
+        Name:str = ""
+        Zoom:int = 0
+        LiveVideo:int = 2
+        WindowState:int = 1
+    Command Timeout: 6000
+    Example:SetCameraView AlignWafer 0 2 2
+    """
+    MessageServerInterface.sendSciCommand("SetCameraView",Name,Zoom,LiveVideo,WindowState)
+
+
+def SetCameraLight(Name:str="", State:int="", Shutter:Decimal="", Gain:Decimal="", Brightness:int="", Contrast:int="", Sharpness:int="", Illumination:int=""):
+    """
+    Switches the light of the choosen camera on or off. Light values of -1 will
+    cause that the parameter is not affected.
+    API Status: published
+    Args:
+        Name:str = ""
+        State:int = 0
+        Shutter:Decimal = -1
+        Gain:Decimal = -1
+        Brightness:int = -1
+        Contrast:int = -1
+        Sharpness:int = -1
+        Illumination:int = -1
+    Command Timeout: 6000
+    Example:SetCameraLight AlignWafer 1 20 5
+    """
+    MessageServerInterface.sendSciCommand("SetCameraLight",Name,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination)
+
+
+def ShowWizard(ToolName:str="", MountPosition:str="", AskExecute:int=""):
+    """
+    Starts the wizard of a given tool on the display defined in the tool settings.
+    Additionally it can start a wizard for training single models with the syntax
+    e.g. ShowWizard FindFeature/ProjectData/Features/Feature1/Model For the tools
+    MeasureOnScreen, Calibrate and CameraOrigin you can specify a mount position
+    e.g. ShowWizard Calibrate Platen
+    API Status: published
+    Args:
+        ToolName:str = ""
+        MountPosition:str = ""
+        AskExecute:int = 0
+    Returns:
+        Cancelled:int
+    Command Timeout: 10000000
+    Example:ShowWizard AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("ShowWizard",ToolName,MountPosition,AskExecute)
+    return int(rsp[0])
+
+def ProbeToPadAlign(Position:str=""):
+    """
+    Sets a new Home position. The command is used during ReAlign to search the
+    trained home reference controller and to calculate the new xy home position.
+    API Status: published
+    Args:
+        Position:str = "H"
+    Returns:
+        XOffsetWafer:Decimal
+        YOffsetWafer:Decimal
+    Command Timeout: 120000
+    Example:ProbeToPadAlign H
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProbeToPadAlign",Position)
+    global ProbeToPadAlign_Response
+    if not "ProbeToPadAlign_Response" in globals(): ProbeToPadAlign_Response = namedtuple("ProbeToPadAlign_Response", "XOffsetWafer,YOffsetWafer")
+    return ProbeToPadAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def ReadOcrString():
+    """
+    Reads the wafer ID string from the wafer's surface. Returns the read ID as
+    string. Requires IDTools license.
+    API Status: published
+    Returns:
+        OcrString:str
+    Command Timeout: 60000
+    Example:ReadOcrString
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadOcrString")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadBarCode():
+    """
+    Reads the wafers barcode and decodes it to a string. Requires IDTools license.
+    API Status: published
+    Returns:
+        BarCodeString:str
+    Command Timeout: 60000
+    Example:ReadBarCode
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadBarCode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def Read2DMatrixCode():
+    """
+    Reads the wafers matrix code and decodes it to a string. Requires IDTools
+    license.
+    API Status: published
+    Returns:
+        MatrixCodeString:str
+    Command Timeout: 60000
+    Example:Read2DMatrixCode
+    """
+    rsp = MessageServerInterface.sendSciCommand("Read2DMatrixCode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetSpectrumRemote(Activate:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Activates the Spectrum remote mode. In this mode all user interface elements are
+    hidden and disabled. This is used when Spectrum is hosted inside VeloxPro.
+    API Status: internal
+    Args:
+        Activate:int = 1
+    Command Timeout: 10000
+    Example:SetSpectrumRemote 1
+    """
+    MessageServerInterface.sendSciCommand("SetSpectrumRemote",Activate)
+
+
+def GetCameraLight(Name:str=""):
+    """
+    Returns light properties of choosen camera.
+    API Status: published
+    Args:
+        Name:str = ""
+    Returns:
+        MountPosition:str
+        State:int
+        Shutter:Decimal
+        Gain:Decimal
+        Brightness:int
+        Contrast:int
+        Sharpness:int
+        Illumination:int
+    Command Timeout: 6000
+    Example:GetCameraLight Scope
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraLight",Name)
+    global GetCameraLight_Response
+    if not "GetCameraLight_Response" in globals(): GetCameraLight_Response = namedtuple("GetCameraLight_Response", "MountPosition,State,Shutter,Gain,Brightness,Contrast,Sharpness,Illumination")
+    return GetCameraLight_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def GetCameraView(Name:str=""):
+    """
+    Returns the present camera view state of a desired tool or active view.
+    API Status: published
+    Args:
+        Name:str = ""
+    Returns:
+        MountPosition:str
+        Zoom:int
+        LiveVideo:int
+        WindowState:int
+    Command Timeout: 6000
+    Example:GetCameraView AlignWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraView",Name)
+    global GetCameraView_Response
+    if not "GetCameraView_Response" in globals(): GetCameraView_Response = namedtuple("GetCameraView_Response", "MountPosition,Zoom,LiveVideo,WindowState")
+    return GetCameraView_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetPattern(ToolName:str="", ModelName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Transforms the specific controller of a demanded tool into a bitmap. This bitmap will
+    be stored in the same folder as the project file.     The command was originally
+    required by ReAlignWizard and is currently no longer in use.
+    API Status: internal
+    Args:
+        ToolName:str = ""
+        ModelName:str = ""
+    Returns:
+        BitmapPath:str
+    Command Timeout: 30000
+    Example:GetPattern AlignWafer Model1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPattern",ToolName,ModelName)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ShowPosition(MountPosition:str="", DistPositionX:Decimal="", DistPositionY:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the ChuckCenter under a given camera. When no camera mount position is
+    given, Spectrum uses active view. If there is an Offset different from zero,
+    this position will be moved under the camera.
+    API Status: internal
+    Args:
+        MountPosition:str = ""
+        DistPositionX:Decimal = 0
+        DistPositionY:Decimal = 0
+    Command Timeout: 60000
+    Example:ShowPosition Scope
+    """
+    MessageServerInterface.sendSciCommand("ShowPosition",MountPosition,DistPositionX,DistPositionY)
+
+
+def GetCameraHomePosition():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the home die coordinates when the home die is under the alignment camera
+    (for instance, the top camera).     Command was used during TrainReAlign to get
+    the start position for Z-Profiling. Command is no longer used.
+    API Status: internal
+    Returns:
+        XPosition:Decimal
+        YPosition:Decimal
+        ZPosition:Decimal
+    Command Timeout: 6000
+    Example:GetCameraHomePosition
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCameraHomePosition")
+    global GetCameraHomePosition_Response
+    if not "GetCameraHomePosition_Response" in globals(): GetCameraHomePosition_Response = namedtuple("GetCameraHomePosition_Response", "XPosition,YPosition,ZPosition")
+    return GetCameraHomePosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SynchronizeCamera(MountPos:str="", SynchronizeXY:int="", SynchronizeZ:int=""):
+    """
+    Synchronizes the Platen camera with the calibration mark. The mark is mounted on
+    the chuck camera. The chuck must be moved to get the mark in view of the
+    specified camera.
+    API Status: published
+    Args:
+        MountPos:str = "Scope"
+        SynchronizeXY:int = 0
+        SynchronizeZ:int = 0
+    Returns:
+        XPosition:Decimal
+        YPosition:Decimal
+        ZPosition:Decimal
+    Command Timeout: 120000
+    Example:SynchronizeCamera S 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SynchronizeCamera",MountPos,SynchronizeXY,SynchronizeZ)
+    global SynchronizeCamera_Response
+    if not "SynchronizeCamera_Response" in globals(): SynchronizeCamera_Response = namedtuple("SynchronizeCamera_Response", "XPosition,YPosition,ZPosition")
+    return SynchronizeCamera_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def ProbeCardOCS(UpdateZ:int="", MeasureBothGroups:int=""):
+    """
+    Determines the chuck XYZ axis position where the needles of the probe card are
+    in focus. The output parameter is the Z axis value in microns from zero of the
+    new focus height.
+    API Status: published
+    Args:
+        UpdateZ:int = 1
+        MeasureBothGroups:int = 1
+    Returns:
+        ZPosition:Decimal
+    Command Timeout: 360000
+    Example:ProbeCardOCS 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProbeCardOCS",UpdateZ,MeasureBothGroups)
+    return Decimal(rsp[0])
+
+def MoveChuckAutoXY(XPosition:Decimal="", YPosition:Decimal="", XSubsiteOffset:Decimal="", YSubsiteOffset:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is sent by WaferMap to trigger AutoXY, AutoZ or VueTrack for each die
+    move. Automation must be activated/trained before command can be used. Response
+    is X, Y relative distance of adjustment from requested position.
+    API Status: internal
+    Args:
+        XPosition:Decimal = 0
+        YPosition:Decimal = 0
+        XSubsiteOffset:Decimal = 0
+        YSubsiteOffset:Decimal = 0
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 6000000
+    Example:MoveChuckAutoXY 5000 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveChuckAutoXY",XPosition,YPosition,XSubsiteOffset,YSubsiteOffset)
+    global MoveChuckAutoXY_Response
+    if not "MoveChuckAutoXY_Response" in globals(): MoveChuckAutoXY_Response = namedtuple("MoveChuckAutoXY_Response", "XOffset,YOffset")
+    return MoveChuckAutoXY_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def VueTrackAlign(FullVueTrackAlign:int=""):
+    """
+    Alignment for the next wafer when using VueTrack.
+    API Status: published
+    Args:
+        FullVueTrackAlign:int = 1
+    Command Timeout: 6000000
+    Example:VueTrackAlign
+    """
+    MessageServerInterface.sendSciCommand("VueTrackAlign",FullVueTrackAlign)
+
+
+def AutoFocusEVue(DistBelow:Decimal="", DistAbove:Decimal="", XOffsetCenter:int="", YOffsetCenter:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command is only used internally for software testing and for providing backwards
+    compatibility with SCPI legacy commands. It executes a focus search using the
+    eVue focus drive.
+    API Status: internal
+    Args:
+        DistBelow:Decimal = 0
+        DistAbove:Decimal = 0
+        XOffsetCenter:int = 0
+        YOffsetCenter:int = 0
+    Returns:
+        FocusScore:Decimal
+        ZPosition:Decimal
+    Command Timeout: 30000
+    Example:AutoFocusEVue 200 200 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutoFocusEVue",DistBelow,DistAbove,XOffsetCenter,YOffsetCenter)
+    global AutoFocusEVue_Response
+    if not "AutoFocusEVue_Response" in globals(): AutoFocusEVue_Response = namedtuple("AutoFocusEVue_Response", "FocusScore,ZPosition")
+    return AutoFocusEVue_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def AutoAlignOffAxis(SetValue:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes the ReAlign Wafer Alignment tool to do a theta alignment of the wafer
+    with optional index calculation or thermal expansion measurement. AutoAlign is
+    performed using the Platen camera. Only supported for systems with off-axis
+    camera.
+    API Status: internal
+    Args:
+        SetValue:int = 0
+    Command Timeout: 300000
+    Example:AutoAlignOffAxis 1
+    """
+    MessageServerInterface.sendSciCommand("AutoAlignOffAxis",SetValue)
+
+
+def FindFocusOffAxis(StepCount:int="", Range:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search. Focus search is performed using the Platen camera. Only supported for
+    systems with off-axis camera.
+    API Status: internal
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocusOffAxis 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocusOffAxis",StepCount,Range)
+    global FindFocusOffAxis_Response
+    if not "FindFocusOffAxis_Response" in globals(): FindFocusOffAxis_Response = namedtuple("FindFocusOffAxis_Response", "ZPosition,Stage")
+    return FindFocusOffAxis_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignAuxOffAxis(AuxSiteID:int=""):
+    """
+    Performs an automated aux site alignment in XYZ using the Off Axis camera. Tool
+    can correct reference position and contact height for the given aux site.
+    API Status: published
+    Args:
+        AuxSiteID:int = 0
+    Command Timeout: 300000
+    Example:AlignAuxOffAxis 1
+    """
+    MessageServerInterface.sendSciCommand("AlignAuxOffAxis",AuxSiteID)
+
+
+def FindFocusPlaten(StepCount:int="", Range:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Determines the Z axis position where an object in the region of interest is in
+    focus. First output parameter is the Z axis value in microns from zero of the
+    new focus height. Second output parameter is the used stage to perform focus
+    search. Uses the FindFocus tool settings but always the Platen camera -
+    independent of the FindFocus mount. This command is used on e.g. BlueRay systems
+    that have a platen camera but can't use ReAlign/DetectWaferHeight as they don't
+    have an upward looking camera.
+    API Status: internal
+    Args:
+        StepCount:int = -1
+        Range:Decimal = -1
+    Returns:
+        ZPosition:Decimal
+        Stage:str
+    Command Timeout: 120000
+    Example:FindFocusPlaten 50 500
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindFocusPlaten",StepCount,Range)
+    global FindFocusPlaten_Response
+    if not "FindFocusPlaten_Response" in globals(): FindFocusPlaten_Response = namedtuple("FindFocusPlaten_Response", "ZPosition,Stage")
+    return FindFocusPlaten_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AlignChipOffAxis():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a single or two point alignment and moves the current chip to the
+    trained aligned position in Theta (in degrees) and X, Y (in microns). This
+    command is using the off axis platen camera with functionality of ReAlign.
+    API Status: internal
+    Returns:
+        ThetaOffset:Decimal
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 180000
+    Example:AlignChipOffAxis
+    """
+    rsp = MessageServerInterface.sendSciCommand("AlignChipOffAxis")
+    global AlignChipOffAxis_Response
+    if not "AlignChipOffAxis_Response" in globals(): AlignChipOffAxis_Response = namedtuple("AlignChipOffAxis_Response", "ThetaOffset,XOffset,YOffset")
+    return AlignChipOffAxis_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SelectAZoomLens(Lens:int=""):
+    """
+    Selects 1 of 4 symbolic lenses (4 classified coarse ranges).
+    API Status: published
+    Args:
+        Lens:int = 1
+    Command Timeout: 10000
+    Example:SelectAZoomLens 1
+    """
+    MessageServerInterface.sendSciCommand("SelectAZoomLens",Lens)
+
+
+def GetAZoomLens():
+    """
+    Returns 1 of 4 symbolic lenses, coarse ranges.
+    API Status: published
+    Returns:
+        Lens:int
+    Command Timeout: 5000
+    Example:GetAZoomLens
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAZoomLens")
+    return int(rsp[0])
+
+def AZoomSetupDialog():
+    """
+    Opens the operator panel. In this window you can change the settings for all
+    defined lenses.
+    API Status: published
+    Command Timeout: 5000
+    Example:AZoomSetupDialog
+    """
+    MessageServerInterface.sendSciCommand("AZoomSetupDialog")
+
+
+def MoveAZoomFocus(Focus:int="", Ref:str=""):
+    """
+    Changes the focus magnitude.
+    API Status: published
+    Args:
+        Focus:int = 100
+        Ref:str = "R"
+    Returns:
+        RetFocus:int
+    Command Timeout: 10000
+    Example:MoveAZoomFocus 100
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAZoomFocus",Focus,Ref)
+    return int(rsp[0])
+
+def ReadAZoomFocus():
+    """
+    Returns the focus magnitude.
+    API Status: published
+    Returns:
+        Focus:int
+    Command Timeout: 5000
+    Example:ReadAZoomFocus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAZoomFocus")
+    return int(rsp[0])
+
+def MoveAZoomVelocity(Direction:str="", Velocity:int=""):
+    """
+    Moves the A-Zoom using the set focus speed.
+    API Status: published
+    Args:
+        Direction:str = ""
+        Velocity:int = 100
+    Returns:
+        RetVelocity:Decimal
+    Command Timeout: 240000
+    Example:MoveAZoomVelocity + 67
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAZoomVelocity",Direction,Velocity)
+    return Decimal(rsp[0])
+
+def StopAZoom():
+    """
+    Stops the A-Zoom movements.
+    API Status: published
+    Command Timeout: 5000
+    Example:StopAZoom
+    """
+    MessageServerInterface.sendSciCommand("StopAZoom")
+
+
+def SetAZoomLight(Light:int=""):
+    """
+    Switches all lights ON or OFF. ON means the values defined by the current lens.
+    1 switches the light on, 0 switches the light off. Without parameter toggles
+    between on an off.
+    API Status: published
+    Args:
+        Light:int = 0
+    Command Timeout: 5000
+    Example:SetAZoomLight 1
+    """
+    MessageServerInterface.sendSciCommand("SetAZoomLight",Light)
+
+
+def CloseAZoom():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the OpticalControl application. Used during Project File handling.
+    API Status: internal
+    Command Timeout: 5000
+    Example:CloseAZoom
+    """
+    MessageServerInterface.sendSciCommand("CloseAZoom")
+
+
+def OCLightVal(Value:int="", Channel:int="", Segment:int=""):
+    """
+    Set the brightness of given channel and segment to the given value.
+    API Status: published
+    Args:
+        Value:int = 0
+        Channel:int = 1
+        Segment:int = 1
+    Command Timeout: 5000
+    Example:OCLightVal 128 1 4
+    """
+    MessageServerInterface.sendSciCommand("OCLightVal",Value,Channel,Segment)
+
+
+def OCLightOn(On:int="", Channel:int=""):
+    """
+    Switch the light (if it has segments then all) in a given channel ON or OFF.
+    Switch ON - that means: light to the before adjusted brightness.
+    API Status: published
+    Args:
+        On:int = 0
+        Channel:int = 1
+    Command Timeout: 5000
+    Example:OCLightOn 1 1
+    """
+    MessageServerInterface.sendSciCommand("OCLightOn",On,Channel)
+
+
+def OCSetZoomLevel(Zoom:int="", Motor:int=""):
+    """
+    Set logical zoom factor for given motor (if has more then one, else to the one)
+    API Status: published
+    Args:
+        Zoom:int = 0
+        Motor:int = 1
+    Command Timeout: 5000
+    Example:OCSetZoomLevel 50 1
+    """
+    MessageServerInterface.sendSciCommand("OCSetZoomLevel",Zoom,Motor)
+
+
+def OCGetZoomLevel(Motor:int=""):
+    """
+    Get logical zoom factor for given motor (if has more then one, else to the one)
+    API Status: published
+    Args:
+        Motor:int = 1
+    Returns:
+        Zoom:int
+    Command Timeout: 5000
+    Example:OCGetZoomLevel 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("OCGetZoomLevel",Motor)
+    return int(rsp[0])
+
+def StartReAlignTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int=""):
+    """
+    Starts temperature ramping using ReAlign. ReAlign will re-adjust the probes and
+    wafer during ramping to the new target temperature. Command returns immediately.
+    The status of temperature ramping must be checked using the
+    GetReAlignTemperatureStatus command.
+    API Status: published
+    Args:
+        TargetTemperature:Decimal = 0
+        ThetaAlignOnFinish:int = 0
+        ContactOnFinish:int = 0
+    Command Timeout: 5000
+    Example:StartReAlignTemperature 150
+    """
+    MessageServerInterface.sendSciCommand("StartReAlignTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish)
+
+
+def StopReAlignTemperature():
+    """
+    Stops temperature ramping using ReAlign.
+    API Status: published
+    Command Timeout: 10000
+    Example:StopReAlignTemperature
+    """
+    MessageServerInterface.sendSciCommand("StopReAlignTemperature")
+
+
+def GetReAlignTemperatureStatus():
+    """
+    Returns the status of the current temperature ramping using ReAlign process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 300000
+    Example:GetReAlignTemperatureStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetReAlignTemperatureStatus")
+    global GetReAlignTemperatureStatus_Response
+    if not "GetReAlignTemperatureStatus_Response" in globals(): GetReAlignTemperatureStatus_Response = namedtuple("GetReAlignTemperatureStatus_Response", "StatusId,StatusStr")
+    return GetReAlignTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+    """
+    Performs an automatic realignment of the wafer. This includes measuring the
+    needle drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck
+    drift XYZ and optionally a Z-Profile. Alternatively the tool performs a
+    ProbeToDie Alignment to correct the needle position for the current die. Command
+    returns once ReAlign is finished or aborted because of an error.
+    API Status: published
+    Args:
+        Repeats:int = 1
+        Mode:str = "H"
+        AlignProbeCard:int = 2
+        CorrectZ:int = 2
+    Returns:
+        XOffsetWafer:Decimal
+        YOffsetWafer:Decimal
+        ZOffsetWafer:Decimal
+        XOffsetCard:Decimal
+        YOffsetCard:Decimal
+        ZOffsetCard:Decimal
+    Command Timeout: 1000000
+    Example:ReAlign 2 H 0 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+    global ReAlign_Response
+    if not "ReAlign_Response" in globals(): ReAlign_Response = namedtuple("ReAlign_Response", "XOffsetWafer,YOffsetWafer,ZOffsetWafer,XOffsetCard,YOffsetCard,ZOffsetCard")
+    return ReAlign_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def NextWafer():
+    """
+    Starts the NextWafer routine.
+    API Status: published
+    Returns:
+        Canceled:int
+    Command Timeout: 60000000
+    Example:NextWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("NextWafer")
+    return int(rsp[0])
+
+def StartReAlign(Repeats:int="", Mode:str="", AlignProbeCard:int="", CorrectZ:int=""):
+    """
+    Starts an automatic realignment of the wafer. This includes measuring the needle
+    drift XYZ, aligning the wafer, measuring chuck expansion, measuring chuck drift
+    XYZ and optionally a Z-Profile. Alternatively the tool performs a ProbeToPad
+    Alignment to correct the needle position for the current die. Command returns
+    immediately. The status of the asynchronous ReAlign execution must be checked
+    using the GetReAlignStatus command.
+    API Status: published
+    Args:
+        Repeats:int = 1
+        Mode:str = "H"
+        AlignProbeCard:int = 2
+        CorrectZ:int = 2
+    Command Timeout: 60000
+    Example:StartReAlign 2 H 0 0
+    """
+    MessageServerInterface.sendSciCommand("StartReAlign",Repeats,Mode,AlignProbeCard,CorrectZ)
+
+
+def StopReAlign():
+    """
+    Stops the ReAlign procedure.
+    API Status: published
+    Command Timeout: 120000
+    Example:StopReAlign
+    """
+    MessageServerInterface.sendSciCommand("StopReAlign")
+
+
+def GetReAlignStatus():
+    """
+    Returns a status of the ReAlign procedure. If the return value is true, ReAlign
+    is running.
+    API Status: published
+    Returns:
+        Running:int
+    Command Timeout: 60000
+    Example:GetReAlignStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetReAlignStatus")
+    return int(rsp[0])
+
+def EnableOverlay(Overlay:int=""):
+    """
+    Allows activating the overlay of the needles for the top camera.
+    API Status: published
+    Args:
+        Overlay:int = 0
+    Command Timeout: 6000
+    Example:EnableOverlay 0
+    """
+    MessageServerInterface.sendSciCommand("EnableOverlay",Overlay)
+
+
+def SwitchOffset(Offset:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Switches the offset compensation. Applicable for MicroAlign stations only.
+    API Status: internal
+    Args:
+        Offset:int = 0
+    Command Timeout: 60000
+    Example:SwitchOffset 1
+    """
+    MessageServerInterface.sendSciCommand("SwitchOffset",Offset)
+
+
+def TrainFeature(Model:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command was only implemented for supporting a SCPI legacy command. Does not make
+    sense in Velox, as there is no default training rectangle on the screen as in
+    Nucleus.
+    API Status: internal
+    Args:
+        Model:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 30000
+    Example:TrainFeature 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("TrainFeature",Model)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetEvueExposureLevel():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the exposure value of the eVue. Implemented for supporting SCPI legacy
+    command.
+    API Status: internal
+    Returns:
+        Exposure:Decimal
+    Command Timeout: 10000
+    Example:GetEvueExposureLevel
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueExposureLevel")
+    return Decimal(rsp[0])
+
+def SetEvueExposureLevel(Exposure:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the exposure value of the eVue. Implemented for supporting SCPI legacy
+    command.
+    API Status: internal
+    Args:
+        Exposure:Decimal = 0
+    Command Timeout: 10000
+    Example:SetEvueExposureLevel
+    """
+    MessageServerInterface.sendSciCommand("SetEvueExposureLevel",Exposure)
+
+
+def MoveEvueFocusStage(EvueZ:Decimal="", EvueVelocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the eVue focus stage to a specified position. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Args:
+        EvueZ:Decimal = 0
+        EvueVelocity:Decimal = 100
+    Command Timeout: 30000
+    Example:MoveEvueFocusStage 1000
+    """
+    MessageServerInterface.sendSciCommand("MoveEvueFocusStage",EvueZ,EvueVelocity)
+
+
+def GetEvueFocusStagePos():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the eVue focus stage. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Returns:
+        EvueZ:Decimal
+    Command Timeout: 5000
+    Example:GetEvueFocusStagePos
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueFocusStagePos")
+    return Decimal(rsp[0])
+
+def RunEvueAutoExpose(UseCB:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command runs the AutoExpose function for the eVue. Implemented for supporting
+    SCPI legacy command.
+    API Status: internal
+    Args:
+        UseCB:int = 1
+    Command Timeout: 20000
+    Example:RunEvueAutoExpose 1
+    """
+    MessageServerInterface.sendSciCommand("RunEvueAutoExpose",UseCB)
+
+
+def GetEvueZoomLevel():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Valid only with the eVue microscope that is connected to Velox.     On eVue
+    systems, this command, returns values ranging from 0.5 to 5.0 for a 10x system
+    and 0.5 to 20.0 for a 40x system.
+    API Status: internal
+    Returns:
+        Zoom:Decimal
+    Command Timeout: 5000
+    Example:GetEvueZoomLevel
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetEvueZoomLevel")
+    return Decimal(rsp[0])
+
+def SetEvueZoomLevel(Zoom:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Valid only with the eVue microscope or an A-Zoom microscope that is connected to
+    Velox. On eVue systems, this command sets the proper CCD zoom level to the
+    appropriate optical path.
+    API Status: internal
+    Args:
+        Zoom:Decimal = 0
+    Command Timeout: 5000
+    Example:SetEvueZoomLevel 2.0
+    """
+    MessageServerInterface.sendSciCommand("SetEvueZoomLevel",Zoom)
+
+
+def StartAutomationTemperature(TargetTemperature:Decimal="", ThetaAlignOnFinish:int="", ContactOnFinish:int="", AlignOnFinish:int=""):
+    """
+    Starts temperature ramping using Automation. The Automation (mostly VueTrack)
+    will re-adjust the probes and wafer during ramping to the new target
+    temperature.
+    API Status: published
+    Args:
+        TargetTemperature:Decimal = 0
+        ThetaAlignOnFinish:int = 0
+        ContactOnFinish:int = 0
+        AlignOnFinish:int = 1
+    Command Timeout: 5000
+    Example:StartAutomationTemperature 150
+    """
+    MessageServerInterface.sendSciCommand("StartAutomationTemperature",TargetTemperature,ThetaAlignOnFinish,ContactOnFinish,AlignOnFinish)
+
+
+def StopAutomationTemperature():
+    """
+    Stops temperature ramping using Automation.
+    API Status: published
+    Command Timeout: 10000
+    Example:StopAutomationTemperature
+    """
+    MessageServerInterface.sendSciCommand("StopAutomationTemperature")
+
+
+def GetAutomationTemperatureStatus():
+    """
+    Returns the status of the current temperature ramping using automation process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 300000
+    Example:GetAutomationTemperatureStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationTemperatureStatus")
+    global GetAutomationTemperatureStatus_Response
+    if not "GetAutomationTemperatureStatus_Response" in globals(): GetAutomationTemperatureStatus_Response = namedtuple("GetAutomationTemperatureStatus_Response", "StatusId,StatusStr")
+    return GetAutomationTemperatureStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationActive():
+    """
+    Command to read from Spectrum if Automation (AutoXY, AutoZ or VueTrack) is
+    active. Command is used     by WaferMap to read if it must send MoveChuckAutoXY
+    instead of MoveChuck
+    API Status: published
+    Returns:
+        Active:int
+    Command Timeout: 1000
+    Example:GetAutomationActive
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationActive")
+    return int(rsp[0])
+
+def AutomationNeedleSearch(NeedleIndex:int="", MoveScope:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    VueTrack vision search of the given needle index.
+    API Status: internal
+    Args:
+        NeedleIndex:int = 1
+        MoveScope:int = 1
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+        ZOffset:Decimal
+        XYMatchScore:Decimal
+        ZMatchScore:Decimal
+    Command Timeout: 60000
+    Example:AutomationNeedleSearch 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationNeedleSearch",NeedleIndex,MoveScope)
+    global AutomationNeedleSearch_Response
+    if not "AutomationNeedleSearch_Response" in globals(): AutomationNeedleSearch_Response = namedtuple("AutomationNeedleSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore,ZMatchScore")
+    return AutomationNeedleSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def AutomationReferenceSearch():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    AutomationReferenceSearch exposes the functionality of searching the Automation
+    reference target via remote command
+    API Status: internal
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+        ZOffset:Decimal
+        XYMatchScore:Decimal
+    Command Timeout: 60000
+    Example:AutomationReferenceSearch
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationReferenceSearch")
+    global AutomationReferenceSearch_Response
+    if not "AutomationReferenceSearch_Response" in globals(): AutomationReferenceSearch_Response = namedtuple("AutomationReferenceSearch_Response", "XOffset,YOffset,ZOffset,XYMatchScore")
+    return AutomationReferenceSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def MovePositionersSafe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the configured motorized positioners to a safe position
+    API Status: internal
+    Command Timeout: 60000
+    Example:MovePositionersSafe
+    """
+    MessageServerInterface.sendSciCommand("MovePositionersSafe")
+
+
+def SetConstantContactMode(IsOn:int="", ForceLastCorrection:int=""):
+    """
+    Starts Constant Contact mode using Automation. The Automation will re-adjust the
+    wafer during ramping to the new target temperature.
+    API Status: published
+    Args:
+        IsOn:int = 0
+        ForceLastCorrection:int = 0
+    Command Timeout: 5000
+    Example:SetConstantContactMode 1
+    """
+    MessageServerInterface.sendSciCommand("SetConstantContactMode",IsOn,ForceLastCorrection)
+
+
+def GetConstantContactModeStatus():
+    """
+    Returns the status of the current ConstantContact automation process.
+    API Status: published
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 5000
+    Example:GetConstantContactModeStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetConstantContactModeStatus")
+    global GetConstantContactModeStatus_Response
+    if not "GetConstantContactModeStatus_Response" in globals(): GetConstantContactModeStatus_Response = namedtuple("GetConstantContactModeStatus_Response", "StatusId,StatusStr")
+    return GetConstantContactModeStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetAutomationActive(Activate:int=""):
+    """
+    Command to set if Automation (AutoXY, AutoZ or VueTrack) is active. Command can
+    be used to e.g. deactivate automation     programmatically in case it is no
+    longer used.     When activating automation, the command will return an error in
+    case it is not possible (e.g. not trained)
+    API Status: published
+    Args:
+        Activate:int = 0
+    Command Timeout: 1000
+    Example:SetAutomationActive 1
+    """
+    MessageServerInterface.sendSciCommand("SetAutomationActive",Activate)
+
+
+def AutomationSearchCurrentDie():
+    """
+    Performs an Automation search and position correction using the current chuck
+    position. Response is X, Y relative distance of adjustment.
+    API Status: published
+    Returns:
+        XOffset:Decimal
+        YOffset:Decimal
+    Command Timeout: 6000000
+    Example:AutomationSearchCurrentDie
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationSearchCurrentDie")
+    global AutomationSearchCurrentDie_Response
+    if not "AutomationSearchCurrentDie_Response" in globals(): AutomationSearchCurrentDie_Response = namedtuple("AutomationSearchCurrentDie_Response", "XOffset,YOffset")
+    return AutomationSearchCurrentDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def PreMapWafer():
+    """
+    PreMapWafer finds actual singulated die locations and updates positions used by
+    WaferMap.
+    API Status: published
+    Returns:
+        NumberOfDies:int
+    Command Timeout: 14400000
+    Example:PreMapWafer
+    """
+    rsp = MessageServerInterface.sendSciCommand("PreMapWafer")
+    return int(rsp[0])
+
+def ISSProbeAlign():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs an probe to pad operation on the ISS with two RF positioners.
+    API Status: internal
+    Command Timeout: 6000000
+    Example:ISSProbeAlign
+    """
+    MessageServerInterface.sendSciCommand("ISSProbeAlign")
+
+
+def FindWaferCenter(NoManualRecovery:int=""):
+    """
+    FindWaferCenter finds the center of the wafer using edge detection.
+    API Status: published
+    Args:
+        NoManualRecovery:int = 0
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 300000
+    Example:FindWaferCenter
+    """
+    rsp = MessageServerInterface.sendSciCommand("FindWaferCenter",NoManualRecovery)
+    global FindWaferCenter_Response
+    if not "FindWaferCenter_Response" in globals(): FindWaferCenter_Response = namedtuple("FindWaferCenter_Response", "ChuckX,ChuckY")
+    return FindWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def LocateHomeDie(NoManualRecovery:int=""):
+    """
+    LocateHomeDie finds the center of the wafer using edge detection and sets the
+    home position.
+    API Status: published
+    Args:
+        NoManualRecovery:int = 0
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 300000
+    Example:LocateHomeDie
+    """
+    rsp = MessageServerInterface.sendSciCommand("LocateHomeDie",NoManualRecovery)
+    global LocateHomeDie_Response
+    if not "LocateHomeDie_Response" in globals(): LocateHomeDie_Response = namedtuple("LocateHomeDie_Response", "ChuckX,ChuckY")
+    return LocateHomeDie_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def SetAutomationProbeLayout(LayoutName:str="", ProbeID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stores the provided X or Y offset for the given probe for the specified layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+    Command Timeout: 10000
+    Example:SetAutomationProbeLayout "layout1" 1 100.0 0
+    """
+    MessageServerInterface.sendSciCommand("SetAutomationProbeLayout",LayoutName,ProbeID,XOffset,YOffset)
+
+
+def DeleteAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Delete the specfied layout. If LayoutName is empty then all layouts are deleted.
+    If optional ProbeID parmameter is set, it removes just that probe from the
+    layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+    Command Timeout: 10000
+    Example:DeleteAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("DeleteAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def CaptureAutomationProbeLayout(LayoutName:str="", ProbeID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Capture the specfied layout. If optional ProbeID parmameter is set, it captures
+    just that probe from the layout.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+        ProbeID:int = 0
+    Command Timeout: 30000
+    Example:CaptureAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("CaptureAutomationProbeLayout",LayoutName,ProbeID)
+
+
+def MoveToAutomationProbeLayout(LayoutName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move to the probes to specfied layout which are offsets from the trained
+    positions.
+    API Status: internal
+    Args:
+        LayoutName:str = ""
+    Command Timeout: 300000
+    Example:MoveToAutomationProbeLayout "layout1"
+    """
+    MessageServerInterface.sendSciCommand("MoveToAutomationProbeLayout",LayoutName)
+
+
+def ResetAutomation():
+    """
+    Reset automation data back to trained values.
+    API Status: published
+    Command Timeout: 10000
+    Example:ResetAutomation
+    """
+    MessageServerInterface.sendSciCommand("ResetAutomation")
+
+
+def GetWaferCenter():
+    """
+    GetWaferCenter returns the chuck location (zero based) of the wafer center. It
+    returns 0 0 if FindWaferCenter has not been executed for the current wafer.
+    API Status: published
+    Returns:
+        ChuckX:Decimal
+        ChuckY:Decimal
+    Command Timeout: 10000
+    Example:GetWaferCenter
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWaferCenter")
+    global GetWaferCenter_Response
+    if not "GetWaferCenter_Response" in globals(): GetWaferCenter_Response = namedtuple("GetWaferCenter_Response", "ChuckX,ChuckY")
+    return GetWaferCenter_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def InitEvueFocusStage():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initializes the eVue focus stage by finding the limit switches
+    API Status: internal
+    Command Timeout: 30000
+    Example:InitEvueFocusStage
+    """
+    MessageServerInterface.sendSciCommand("InitEvueFocusStage")
+
+
+def EvueSetNumTraceEntriesPreTrigger(NumTraceEntriesPreTrigger:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the number of trace log items to preserve prior to the trigger event. With
+    the continuous event capture log in Bluestone, up to {X} events are captured and
+    kept after the trigger event is sensed. Then, events are captured after the
+    trigger event until the trace log is full and then trace capture is halted.
+    API Status: internal
+    Args:
+        NumTraceEntriesPreTrigger:int = 0
+    Command Timeout: 30000
+    Example:EvueSetNumTraceEntriesPreTrigger 14
+    """
+    MessageServerInterface.sendSciCommand("EvueSetNumTraceEntriesPreTrigger",NumTraceEntriesPreTrigger)
+
+
+def EvueGetNumTraceEntriesPreTrigger():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the number of trace log items to preserve prior to the trigger event. With
+    the continuous event capture log in Bluestone, up to {X} events are captured and
+    kept after the trigger event is sensed. Then, events are captured after the
+    trigger event until the trace log is full and then trace capture is halted.
+    API Status: internal
+    Returns:
+        NumTraceEntriesPreTrigger:int
+    Command Timeout: 30000
+    Example:EvueGetNumTraceEntriesPreTrigger
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntriesPreTrigger")
+    return int(rsp[0])
+
+def EvueStartCaptureServoTrace():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts capturing events in the eVue motion capture log. Capture continues until
+    the log is full. However, log entries will overwrite the oldest entry until the
+    trigger event is encountered. Then, {X} events are preserved prior to the
+    trigger event and the oldest events are only overwritten if they are not part of
+    that preserved set.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EvueStartCaptureServoTrace
+    """
+    MessageServerInterface.sendSciCommand("EvueStartCaptureServoTrace")
+
+
+def EvueGetTraceMachineStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the current status of the trace machine. Bit fields - bit0 is 1 and bit4 is
+    16, etc. bit0 - active and in pre-trigger state bit1 - active and in post-
+    trigger state bit2 - stopped by servo error, lens crash or lens removal bit3 -
+    stopped on requested server state entry bit4 - stopped by immediate command
+    bit5..31 - reserved
+    API Status: internal
+    Returns:
+        TraceMachineStatus:int
+    Command Timeout: 30000
+    Example:EvueGetTraceMachineStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetTraceMachineStatus")
+    return int(rsp[0])
+
+def EvueSetTraceCaptureStopBits(TraceCaptureStopBits:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets condition bits to trigger servo trace capture. Bit fields - bit0 is 1 and
+    bit4 is 16, etc. bit0 - immediate stop bit1 - stop on servo error, lens crash or
+    lens removal bit2 - stop on requested server state (defined by bits 4..7) bit3 -
+    stop on motor move finish bit4..7 - servo state that triggers a trace stop (not
+    an index but the 4-bit state that, if seen, is the trigger for trace capture)
+    bit8..31 - reserved
+    API Status: internal
+    Args:
+        TraceCaptureStopBits:int = 0
+    Command Timeout: 30000
+    Example:EvueSetTraceCaptureStopBits
+    """
+    MessageServerInterface.sendSciCommand("EvueSetTraceCaptureStopBits",TraceCaptureStopBits)
+
+
+def EvueGetNumTraceEntries():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the current status of the trace machine.
+    API Status: internal
+    Returns:
+        TraceEntries:int
+    Command Timeout: 30000
+    Example:EvueGetNumTraceEntries
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetNumTraceEntries")
+    return int(rsp[0])
+
+def EvueGetTraceEntry(EntryIdx:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the N'th trace entry in the log.
+    API Status: internal
+    Args:
+        EntryIdx:int = 0
+    Returns:
+        CommandedPositionMotorCounts:int
+        CommandedPositionMicrons:Decimal
+        MeasuredPositionMotorCounts:int
+        MeasuredPositionMicrons:Decimal
+        TimestampMicroseconds:int
+        ServoStatus:int
+        PwmVal:int
+    Command Timeout: 30000
+    Example:EvueGetTraceEntry 32
+    """
+    rsp = MessageServerInterface.sendSciCommand("EvueGetTraceEntry",EntryIdx)
+    global EvueGetTraceEntry_Response
+    if not "EvueGetTraceEntry_Response" in globals(): EvueGetTraceEntry_Response = namedtuple("EvueGetTraceEntry_Response", "CommandedPositionMotorCounts,CommandedPositionMicrons,MeasuredPositionMotorCounts,MeasuredPositionMicrons,TimestampMicroseconds,ServoStatus,PwmVal")
+    return EvueGetTraceEntry_Response(int(rsp[0]),Decimal(rsp[1]),int(rsp[2]),Decimal(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]))
+
+def AutomationRFProbeSearch(ImageFilename:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the distance in X,Y between the center tips of the RF probes.
+    API Status: internal
+    Args:
+        ImageFilename:str = ""
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 5000
+    Example:AutomationRFProbeSearch
+    """
+    rsp = MessageServerInterface.sendSciCommand("AutomationRFProbeSearch",ImageFilename)
+    global AutomationRFProbeSearch_Response
+    if not "AutomationRFProbeSearch_Response" in globals(): AutomationRFProbeSearch_Response = namedtuple("AutomationRFProbeSearch_Response", "X,Y")
+    return AutomationRFProbeSearch_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def StartAutoRFCalibration():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts the AutoRF calibration sequence.
+    API Status: internal
+    Command Timeout: 3000
+    Example:StartAutoRFCalibration
+    """
+    MessageServerInterface.sendSciCommand("StartAutoRFCalibration")
+
+
+def StopAutoRFCalibration():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the currently running AutoRF calibraiton.
+    API Status: internal
+    Command Timeout: 10000
+    Example:StopAutoRFCalibration
+    """
+    MessageServerInterface.sendSciCommand("StopAutoRFCalibration")
+
+
+def GetAutoRFCalibrationStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the status of the AutoRF calibration sequence.
+    API Status: internal
+    Returns:
+        StatusId:int
+        StatusStr:str
+    Command Timeout: 1000
+    Example:GetAutoRFCalibrationStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutoRFCalibrationStatus")
+    global GetAutoRFCalibrationStatus_Response
+    if not "GetAutoRFCalibrationStatus_Response" in globals(): GetAutoRFCalibrationStatus_Response = namedtuple("GetAutoRFCalibrationStatus_Response", "StatusId,StatusStr")
+    return GetAutoRFCalibrationStatus_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetAutomationLastStepDiagnostics(Index:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the diagnostic state information for the provided index.
+    API Status: internal
+    Args:
+        Index:int = 0
+    Returns:
+        DiagnosticInfo:str
+    Command Timeout: 5000
+    Example:GetAutomationLastStepDiagnostics
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAutomationLastStepDiagnostics",Index)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMNanoChamberState(State:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the WLEM Nano Chamber State.
+    API Status: internal
+    Args:
+        State:str = "Free"
+    Command Timeout: 5000
+    Example:SetWLEMNanoChamberState Free
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMNanoChamberState",State)
+
+
+def GetWLEMNanoChamberState():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the WLEM Nano Chamber State.
+    API Status: internal
+    Returns:
+        State:str
+    Command Timeout: 5000
+    Example:GetWLEMNanoChamberState
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMNanoChamberState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetWLEMState(State:str="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the state of a WLEM pneumatic control (valve).
+    API Status: internal
+    Args:
+        State:str = "NCSeal"
+        Value:int = 0
+    Command Timeout: 5000
+    Example:SetWLEMState NCSeal 1
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMState",State,Value)
+
+
+def GetWLEMState(State:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the state of a WLEM pneumatic control (valve).
+    API Status: internal
+    Args:
+        State:str = "NCSeal"
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:GetWLEMState NCSeal
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMState",State)
+    return int(rsp[0])
+
+def GetWLEMSensorValue(Sensor:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets the value of a WLEM Sensor.
+    API Status: internal
+    Args:
+        Sensor:str = "O2Concentration"
+    Returns:
+        Value:Decimal
+    Command Timeout: 5000
+    Example:GetWLEMSensorValue O2Concentration
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMSensorValue",Sensor)
+    return Decimal(rsp[0])
+
+def SetWLEMOption(Option:str="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets a WLEM Control program option.
+    API Status: internal
+    Args:
+        Option:str = "MinimizeToTray"
+        Value:int = 0
+    Command Timeout: 5000
+    Example:SetWLEMOption MinimizeToTray 1
+    """
+    MessageServerInterface.sendSciCommand("SetWLEMOption",Option,Value)
+
+
+def GetWLEMOption(Option:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets a WLEM Control program option.
+    API Status: internal
+    Args:
+        Option:str = "MinimizeToTray"
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:GetWLEMOption MinimizeToTray
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetWLEMOption",Option)
+    return int(rsp[0])
+
+def NewTesterProject(LotID:str="", TileID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that a new Lot/Tile is to be tested. The tester
+    responds with the correct project name for the test. This is needed because the
+    prober needs to verify that the correct project is loaded. In case no valid
+    project is available, the command is returned with an error.
+    API Status: internal
+    Args:
+        LotID:str = ""
+        TileID:str = ""
+    Returns:
+        ProjectName:str
+    Command Timeout: 30000
+    Example:NewTesterProject Lot01 Tile01
+    """
+    rsp = MessageServerInterface.sendSciCommand("NewTesterProject",LotID,TileID)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def StartMeasurement(DieColumn:int="", DieRow:int="", ActiveDies:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester to begin measuring (Needles are in correct
+    position and in contact). The command is responded when the measurement has
+    finished. The response string holds the binning information separated by comma.
+    For deactivated dies, a bin value of '0' should be responded.
+    API Status: internal
+    Args:
+        DieColumn:int = 0
+        DieRow:int = 0
+        ActiveDies:str = ""
+    Returns:
+        BinNumbers:str
+    Command Timeout: 100000
+    Example:StartMeasurement 1 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StartMeasurement",DieColumn,DieRow,ActiveDies)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def EndOfWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester, that the test of the current substrate has
+    finished. It enables the tester application to save measurement data and/or
+    prepare for the next substrate.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EndOfWafer
+    """
+    MessageServerInterface.sendSciCommand("EndOfWafer")
+
+
+def EndOfLot():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command tells the tester, that the test of the current lot has finished. It
+    enables the tester application to save measurement data and/or prepare for the
+    next lot.
+    API Status: internal
+    Command Timeout: 30000
+    Example:EndOfLot
+    """
+    MessageServerInterface.sendSciCommand("EndOfLot")
+
+
+def VerifyProductID(ProductID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the ProductID that is to be tested. The
+    tester can respond with an error in case the ProductID is not allowed for
+    testing.
+    API Status: internal
+    Args:
+        ProductID:str = ""
+    Command Timeout: 30000
+    Example:VerifyProductID Product123
+    """
+    MessageServerInterface.sendSciCommand("VerifyProductID",ProductID)
+
+
+def VerifyLotID(LotID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the LotID that is to be tested. The tester
+    can respond with an error in case the LotID is not allowed for testing.
+    API Status: internal
+    Args:
+        LotID:str = ""
+    Command Timeout: 30000
+    Example:VerifyLotID Lot123
+    """
+    MessageServerInterface.sendSciCommand("VerifyLotID",LotID)
+
+
+def VerifySubstrateID(SubstrateID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the SubstrateID that is to be tested. The
+    tester can respond with an error in case the SubstrateID is not allowed for
+    testing.
+    API Status: internal
+    Args:
+        SubstrateID:str = ""
+    Command Timeout: 30000
+    Example:VerifySubstrateID Substrate123
+    """
+    MessageServerInterface.sendSciCommand("VerifySubstrateID",SubstrateID)
+
+
+def VerifyProbecard(ProbeCard:str="", Touchdowns:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the ProbecardID and touchdowns that is
+    used for testing. The tester can respond with an error in case the Probecard is
+    not allowed for testing.
+    API Status: internal
+    Args:
+        ProbeCard:str = ""
+        Touchdowns:int = 0
+    Command Timeout: 30000
+    Example:VerifyProbecard Probecard123 10596
+    """
+    MessageServerInterface.sendSciCommand("VerifyProbecard",ProbeCard,Touchdowns)
+
+
+def VerifyUserID(User:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester about the User ID. The tester can respond with
+    an error in case the User ID is not allowed for testing.
+    API Status: internal
+    Args:
+        User:str = ""
+    Command Timeout: 30000
+    Example:VerifyUserID User123
+    """
+    MessageServerInterface.sendSciCommand("VerifyUserID",User)
+
+
+def TesterAbort():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that the job was aborted and no more test will
+    happen.
+    API Status: internal
+    Command Timeout: 30000
+    Example:TesterAbort
+    """
+    MessageServerInterface.sendSciCommand("TesterAbort")
+
+
+def VerifySOTReady():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that a wafer is ready for testing which will
+    immediately start. This command is sent in the recipe sequence "Verify
+    SOTReady".
+    API Status: internal
+    Command Timeout: 30000
+    Example:VerifySOTReady
+    """
+    MessageServerInterface.sendSciCommand("VerifySOTReady")
+
+
+def VerifyWaferStart(SubstrateID:str="", CassettePlace:str="", LotID:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is sent in the VeloxPro recipe sequence "Verify Wafer Start" and
+    informs the tester about the current wafer on the chuck.
+    API Status: internal
+    Args:
+        SubstrateID:str = ""
+        CassettePlace:str = ""
+        LotID:str = ""
+    Command Timeout: 30000
+    Example:VerifyWaferStart Wafer01 1 Lot01
+    """
+    MessageServerInterface.sendSciCommand("VerifyWaferStart",SubstrateID,CassettePlace,LotID)
+
+
+def TesterCassetteInfo(CassetteCmd:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command will be sent after the user selected which wafers are to be tested.
+    It contains a string which represents the state of each wafer: 0 = empty, 1 =
+    full (and selected), 2 = error (e.g. double slotted), 3 = unknown, 4 =
+    deselected
+    API Status: internal
+    Args:
+        CassetteCmd:str = ""
+    Returns:
+        CassetteRsp:str
+    Command Timeout: 30000
+    Example:TesterCassetteInfo 0000001110000000010010111
+    """
+    rsp = MessageServerInterface.sendSciCommand("TesterCassetteInfo",CassetteCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def VerifyProject(ProjectName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is sent after selecting a project file in the VeloxPro product
+    setup page. The command sends the name of the project to tester for
+    verification.
+    API Status: internal
+    Args:
+        ProjectName:str = ""
+    Command Timeout: 30000
+    Example:VerifyProject C:/Users/Public/Documents/Velox/Projects/Test.spp
+    """
+    MessageServerInterface.sendSciCommand("VerifyProject",ProjectName)
+
+
+def TesterAbortWafer():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command informs the tester that the test for the current wafer was aborted
+    and no more tests will happen with the current wafer. The job will continue
+    though.
+    API Status: internal
+    Command Timeout: 30000
+    Example:TesterAbortWafer
+    """
+    MessageServerInterface.sendSciCommand("TesterAbortWafer")
+
+
+def DoTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts execution of one test. It returns a bin number or multple bin numbers
+    when clusters are enabled in the WaferMap (one number for each die in a
+    cluster).  The command starts execution of one test. It returns a bin number or
+    multple bin numbers when clusters are enabled in the WaferMap (one number for
+    each die in a cluster).
+    API Status: internal
+    Returns:
+        BitNumber:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("DoTTLTest")
+    return int(rsp[0])
+
+def StartTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Starts the test of a wafer. Depending on the cluster definitions queried from
+    the WaferMap, all clusters or all dies will be tested.  The command starts the
+    test of a wafer. Depending on the cluster definitions queried from the WaferMap
+    all clusters or all dies will be tested.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("StartTTLTest")
+
+
+def CancelTTLTest():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops the wafer test.
+    API Status: internal
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("CancelTTLTest")
+
+
+def SetTTLLine(Line:int="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the selected line of PA port.
+    API Status: internal
+    Args:
+        Line:int = 0
+        Value:int = 0
+    Command Timeout: 10000
+    Example:SetTTLLine 2 0
+    """
+    MessageServerInterface.sendSciCommand("SetTTLLine",Line,Value)
+
+
+def GetTTLLines():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the I/O lines as bit array.
+    API Status: internal
+    Returns:
+        LineA:int
+        LineB:int
+        LineC:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTTLLines")
+    global GetTTLLines_Response
+    if not "GetTTLLines_Response" in globals(): GetTTLLines_Response = namedtuple("GetTTLLines_Response", "LineA,LineB,LineC")
+    return GetTTLLines_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def GetTTLStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns returns the error 914 if the test is in progress.
+    API Status: internal
+    Returns:
+        ErrCode:int
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTTLStatus")
+    return int(rsp[0])
+
+def StartScript(ScriptName:str=""):
+    """
+    Starts the script and returns the response immediately.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Command Timeout: 10000
+    Example:StartScript myscript
+    """
+    MessageServerInterface.sendSciCommand("StartScript",ScriptName)
+
+
+def GetRunStatus(ScriptName:str=""):
+    """
+    Command returns information about Communicator status.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Returns:
+        Running:int
+        LastError:int
+        Title:str
+    Command Timeout: 5000
+    Example:GetRunStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetRunStatus",ScriptName)
+    global GetRunStatus_Response
+    if not "GetRunStatus_Response" in globals(): GetRunStatus_Response = namedtuple("GetRunStatus_Response", "Running,LastError,Title")
+    return GetRunStatus_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def CloseCommunicator():
+    """
+    Command closes the program. Used during ProjectFile handling.
+    API Status: published
+    Command Timeout: 10000
+    Example:CloseCommunicator
+    """
+    MessageServerInterface.sendSciCommand("CloseCommunicator")
+
+
+def DoScript(ScriptName:str=""):
+    """
+    Executes the script and returns the response afterwards.
+    API Status: published
+    Args:
+        ScriptName:str = ""
+    Command Timeout: 10000000
+    Example:DoScript myscript
+    """
+    MessageServerInterface.sendSciCommand("DoScript",ScriptName)
+
+
+def ReadKernelData(SilentMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Reads Kernel Data to KernelSetup (Left Program pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReadKernelData 0
+    """
+    MessageServerInterface.sendSciCommand("ReadKernelData",SilentMode)
+
+
+def SaveKernelDataAs(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves Kernel Data (Left Program pane) to File. An existing File will be
+    overwritten. If the Folder does not exist, it will be created
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:SaveKernelDataAs C:/Temp/RCConfigSample1.xml
+    """
+    MessageServerInterface.sendSciCommand("SaveKernelDataAs",FileName)
+
+
+def LoadConfigFile(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Loads File Data to KernelSetup (Right Program pane).
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:LoadConfigFile C:/Temp/RCConfigSample1.xml
+    """
+    MessageServerInterface.sendSciCommand("LoadConfigFile",FileName)
+
+
+def ReplaceKernelDataByFileData(SilentMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Replaces Kernel Data (Left pane) by File Data (Right pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReplaceKernelDataByFileData 0
+    """
+    MessageServerInterface.sendSciCommand("ReplaceKernelDataByFileData",SilentMode)
+
+
+def ReplaceFileTreeByKernelData(SilentMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Replaces File Tree (Right pane) by Kernel Data (Left pane).
+    API Status: internal
+    Args:
+        SilentMode:int = 0
+    Command Timeout: 300000
+    Example:ReplaceFileTreeByKernelData 0
+    """
+    MessageServerInterface.sendSciCommand("ReplaceFileTreeByKernelData",SilentMode)
+
+
+def SaveFileTreeAs(FileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Saves File Tree (Right pane) to File. An existing File will be overwritten. If
+    the Folder does not exist, it will be created.
+    API Status: internal
+    Args:
+        FileName:str = ""
+    Command Timeout: 10000
+    Example:SaveFileTreeAs C:/Temp/RCConfigSample2.xml
+    """
+    MessageServerInterface.sendSciCommand("SaveFileTreeAs",FileName)
+
+
+def HeatChuck(Temperature:Decimal="", Unit:str="", ReduceContact:int=""):
+    """
+    Sets a new target temperature and starts the heating or cooling of the chuck. An
+    answer to the command will be returned after reaching the given temperature and
+    waiting the soak time or an unexpected interrupt of the process. Given back is
+    the already reached temperature.
+    API Status: published
+    Args:
+        Temperature:Decimal = 25
+        Unit:str = "Celsius"
+        ReduceContact:int = 1
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 36000000
+    Example:HeatChuck 61.3 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("HeatChuck",Temperature,Unit,ReduceContact)
+    global HeatChuck_Response
+    if not "HeatChuck_Response" in globals(): HeatChuck_Response = namedtuple("HeatChuck_Response", "RespTemperature,RespUnit")
+    return HeatChuck_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetHeaterTemp(Temperature:Decimal="", Unit:str="", UseContactSafety:int=""):
+    """
+    Sets a new target temperature and starts the heating or cooling of the
+    temperature chuck. The new target temperature is returned immediately as the
+    command does not wait until heating is complete.
+    API Status: published
+    Args:
+        Temperature:Decimal = 25
+        Unit:str = "Celsius"
+        UseContactSafety:int = 1
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:SetHeaterTemp 55.5 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetHeaterTemp",Temperature,Unit,UseContactSafety)
+    global SetHeaterTemp_Response
+    if not "SetHeaterTemp_Response" in globals(): SetHeaterTemp_Response = namedtuple("SetHeaterTemp_Response", "RespTemperature,RespUnit")
+    return SetHeaterTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetHeaterTemp(Unit:str="", ExternalHeaterID:int=""):
+    """
+    Reads the current temperature of the chuck and determines the status of the
+    thermal system.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+        ExternalHeaterID:int = 0
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+        Status:str
+    Command Timeout: 60000
+    Example:GetHeaterTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHeaterTemp",Unit,ExternalHeaterID)
+    global GetHeaterTemp_Response
+    if not "GetHeaterTemp_Response" in globals(): GetHeaterTemp_Response = namedtuple("GetHeaterTemp_Response", "RespTemperature,RespUnit,Status")
+    return GetHeaterTemp_Response(Decimal(rsp[0]),str(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def EnableHeaterHoldMode(HoldMode:int=""):
+    """
+    Switches the Temperature Chuck devices hold mode on or off. In hold mode the
+    chuck is heated with a constant current to avoid noise from the temperature
+    control. The hold mode can be enabled only in HoldReady state.
+    API Status: published
+    Args:
+        HoldMode:int = 1
+    Returns:
+        RespHoldMode:int
+    Command Timeout: 60000
+    Example:EnableHeaterHoldMode 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("EnableHeaterHoldMode",HoldMode)
+    return int(rsp[0])
+
+def StopHeatChuck():
+    """
+    Stops a pending heating or cooling process. If the device is not at temperature,
+    the actual temperature is set as target temperature.
+    API Status: published
+    Command Timeout: 60000
+    Example:StopHeatChuck
+    """
+    MessageServerInterface.sendSciCommand("StopHeatChuck")
+
+
+def GetDewPointTemp(Unit:str=""):
+    """
+    Returns the current dew point temperature, if a dew point sensor is connected.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:GetDewPointTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetDewPointTemp",Unit)
+    global GetDewPointTemp_Response
+    if not "GetDewPointTemp_Response" in globals(): GetDewPointTemp_Response = namedtuple("GetDewPointTemp_Response", "RespTemperature,RespUnit")
+    return GetDewPointTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def GetTemperatureChuckOptions():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the currently set temperature chuck options.
+    API Status: internal
+    Returns:
+        UseSoakTime:int
+        SyncTemp:int
+        CurrConnection:int
+        MinTemperature:Decimal
+        MaxTemperature:Decimal
+        UsePurge:int
+        UseDynamicSoakTime:int
+        UseFixedDieSoakTime:int
+        UseDynamicDieSoakTime:int
+        UseEcoMode:int
+        PurgeOnChamberDoor:int
+        ForceBypassPurge:int
+        DoorClosedTime:int
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTemperatureChuckOptions")
+    global GetTemperatureChuckOptions_Response
+    if not "GetTemperatureChuckOptions_Response" in globals(): GetTemperatureChuckOptions_Response = namedtuple("GetTemperatureChuckOptions_Response", "UseSoakTime,SyncTemp,CurrConnection,MinTemperature,MaxTemperature,UsePurge,UseDynamicSoakTime,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime")
+    return GetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]))
+
+def SetTemperatureChuckOptions(UseFixedWaferSoak:int="", SyncTemp:int="", CurrConnection:int="", UsePurge:int="", UseDynamicWaferSoak:int="", UseFixedDieSoakTime:int="", UseDynamicDieSoakTime:int="", UseEcoMode:int="", PurgeOnChamberDoor:int="", ForceBypassPurge:int="", DoorClosedTime:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command is used to change the currently set temperature chuck options.
+    API Status: internal
+    Args:
+        UseFixedWaferSoak:int = -1
+        SyncTemp:int = -1
+        CurrConnection:int = -1
+        UsePurge:int = -1
+        UseDynamicWaferSoak:int = -1
+        UseFixedDieSoakTime:int = -1
+        UseDynamicDieSoakTime:int = -1
+        UseEcoMode:int = -1
+        PurgeOnChamberDoor:int = -1
+        ForceBypassPurge:int = -1
+        DoorClosedTime:int = -1
+    Returns:
+        UseFixedWaferSoakRsp:int
+        SyncTempRsp:int
+        CurrConnectionRsp:int
+        UsePurgeRsp:int
+        UseDynamicWaferSoakRsp:int
+        UseFixedDieSoakTimeRsp:int
+        UseDynamicDieSoakTimeRsp:int
+        UseEcoModeRsp:int
+        PurgeOnChamberDoorRsp:int
+        ForceBypassPurgeRsp:int
+        DoorClosedTimeRsp:int
+    Command Timeout: 300000
+    Example:SetTemperatureChuckOptions 1 0 1 1 1 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetTemperatureChuckOptions",UseFixedWaferSoak,SyncTemp,CurrConnection,UsePurge,UseDynamicWaferSoak,UseFixedDieSoakTime,UseDynamicDieSoakTime,UseEcoMode,PurgeOnChamberDoor,ForceBypassPurge,DoorClosedTime)
+    global SetTemperatureChuckOptions_Response
+    if not "SetTemperatureChuckOptions_Response" in globals(): SetTemperatureChuckOptions_Response = namedtuple("SetTemperatureChuckOptions_Response", "UseFixedWaferSoakRsp,SyncTempRsp,CurrConnectionRsp,UsePurgeRsp,UseDynamicWaferSoakRsp,UseFixedDieSoakTimeRsp,UseDynamicDieSoakTimeRsp,UseEcoModeRsp,PurgeOnChamberDoorRsp,ForceBypassPurgeRsp,DoorClosedTimeRsp")
+    return SetTemperatureChuckOptions_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]))
+
+def GetHeaterSoak():
+    """
+    Returns the current soak time values in seconds and the soaking status.
+    API Status: published
+    Returns:
+        FixedWaferSoakTime:int
+        FixedWaferSoakStatus:int
+        DynamicWaferSoakTime:Decimal
+        DynamicWaferSoakStatus:int
+        FixedDieSoakTime:Decimal
+        DynamicDieSoakTime:Decimal
+        FixedDieSoakStatus:int
+        DynamicDieSoakStatus:int
+    Command Timeout: 60000
+    Example:GetHeaterSoak
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetHeaterSoak")
+    global GetHeaterSoak_Response
+    if not "GetHeaterSoak_Response" in globals(): GetHeaterSoak_Response = namedtuple("GetHeaterSoak_Response", "FixedWaferSoakTime,FixedWaferSoakStatus,DynamicWaferSoakTime,DynamicWaferSoakStatus,FixedDieSoakTime,DynamicDieSoakTime,FixedDieSoakStatus,DynamicDieSoakStatus")
+    return GetHeaterSoak_Response(int(rsp[0]),int(rsp[1]),Decimal(rsp[2]),int(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),int(rsp[6]),int(rsp[7]))
+
+def SetHeaterSoak(FixedWaferSoakTime:int="", DynamicWaferSoakTime:Decimal="", FixedDieSoakTime:Decimal="", DynamicDieSoakTime:Decimal=""):
+    """
+    Sets the new soak time values. The unit of the values is seconds. If soak time
+    is actually running, it may be affected by the change.
+    API Status: published
+    Args:
+        FixedWaferSoakTime:int = 60
+        DynamicWaferSoakTime:Decimal = -1
+        FixedDieSoakTime:Decimal = -1
+        DynamicDieSoakTime:Decimal = -1
+    Command Timeout: 60000
+    Example:SetHeaterSoak 60
+    """
+    MessageServerInterface.sendSciCommand("SetHeaterSoak",FixedWaferSoakTime,DynamicWaferSoakTime,FixedDieSoakTime,DynamicDieSoakTime)
+
+
+def EnableHeaterStandby(Standby:int=""):
+    """
+    Switches the power save (standby) mode of the device on or off. If the device is
+    in power save mode, setting and reading temperatures switches off the power save
+    mode automatically.
+    API Status: published
+    Args:
+        Standby:int = 1
+    Returns:
+        RespStandby:int
+    Command Timeout: 60000
+    Example:EnableHeaterStandby 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("EnableHeaterStandby",Standby)
+    return int(rsp[0])
+
+def ReadTemperatureChuckStatus():
+    """
+    Returns values of the temperature chuck status. The status byte gives
+    information about the current controller's action. The dew point sensor status
+    encapsulates information, if such a sensor is connected, and if the actual dew
+    point difference temperature is readable (active). It can be used for purge
+    control. Soak time left (in seconds) is used when soak time is actually running.
+    API Status: published
+    Returns:
+        Status:str
+        DPSensor:int
+        SoakTimeLeft:int
+        HasEcoMode:int
+    Command Timeout: 60000
+    Example:ReadTemperatureChuckStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadTemperatureChuckStatus")
+    global ReadTemperatureChuckStatus_Response
+    if not "ReadTemperatureChuckStatus_Response" in globals(): ReadTemperatureChuckStatus_Response = namedtuple("ReadTemperatureChuckStatus_Response", "Status,DPSensor,SoakTimeLeft,HasEcoMode")
+    return ReadTemperatureChuckStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def GetTargetTemp(Unit:str=""):
+    """
+    Reads the target temperature of the chuck.
+    API Status: published
+    Args:
+        Unit:str = "Celsius"
+    Returns:
+        RespTemperature:Decimal
+        RespUnit:str
+    Command Timeout: 60000
+    Example:GetTargetTemp C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetTargetTemp",Unit)
+    global GetTargetTemp_Response
+    if not "GetTargetTemp_Response" in globals(): GetTargetTemp_Response = namedtuple("GetTargetTemp_Response", "RespTemperature,RespUnit")
+    return GetTargetTemp_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def SetThermoWindow(Window:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command sets the window for the target temperture which is the window in which a
+    station is assumed to be at temp. Only supported on Nucleus stations.
+    API Status: internal
+    Args:
+        Window:Decimal = 1
+    Returns:
+        RespWindow:Decimal
+    Command Timeout: 60000
+    Example:SetThermoWindow 2.0
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetThermoWindow",Window)
+    return Decimal(rsp[0])
+
+def GetThermoWindow():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command returns the current thermo window which is the window in which a station
+    is assumed to be at temp. Only supported on Nucleus stations.
+    API Status: internal
+    Returns:
+        RespWindow:Decimal
+    Command Timeout: 60000
+    Example:GetThermoWindow
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetThermoWindow")
+    return Decimal(rsp[0])
+
+def SendThermoCommand(Command:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sends a command string to the thermal chuck using the thermal chuck protocol and
+    returns the thermal chucks response as command response. This command can be
+    used to access thermal chuck features that are not exposed as standalone SCI
+    commands. Command is currently implemented for ERS and ATT chucks.
+    API Status: internal
+    Args:
+        Command:str = ""
+    Returns:
+        Response:str
+    Command Timeout: 5000
+    Example:SendThermoCommand RH
+    """
+    rsp = MessageServerInterface.sendSciCommand("SendThermoCommand",Command)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ReadAuxStatus(AuxID:int=""):
+    """
+    Returns the status of a single AUX site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        FlagsMode:int
+        Comp:str
+        PresetHeight:str
+        AuxSiteType:str
+    Command Timeout: 10000
+    Example:ReadAuxStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxStatus",AuxID)
+    global ReadAuxStatus_Response
+    if not "ReadAuxStatus_Response" in globals(): ReadAuxStatus_Response = namedtuple("ReadAuxStatus_Response", "AuxIDEcho,FlagsMode,Comp,PresetHeight,AuxSiteType")
+    return ReadAuxStatus_Response(int(rsp[0]),int(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ReadAuxPosition(AuxID:int="", Unit:str="", PosRef:str="", Comp:str=""):
+    """
+    Returns the actual AUX sites position in X, Y and Z. With AUX ID set to 0, the
+    position is read for the chuck stage. If no AUX ID is given, it tries to read
+    the position from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+        PosRef:str = "Home"
+        Comp:str = "Default"
+    Returns:
+        AuxIDEcho:int
+        X:Decimal
+        Y:Decimal
+        Z:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxPosition 1 Y Z
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxPosition",AuxID,Unit,PosRef,Comp)
+    global ReadAuxPosition_Response
+    if not "ReadAuxPosition_Response" in globals(): ReadAuxPosition_Response = namedtuple("ReadAuxPosition_Response", "AuxIDEcho,X,Y,Z")
+    return ReadAuxPosition_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def ReadAuxHeights(AuxID:int="", Unit:str=""):
+    """
+    Returns the actual technology heights from an AUX site. If AUX ID is set to 0,
+    all response values are read from chuck stage. If no AUX ID is given, it tries
+    to read the heights from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+        Contact:Decimal
+        Overtravel:Decimal
+        AlignDist:Decimal
+        SepDist:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxHeights 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxHeights",AuxID,Unit)
+    global ReadAuxHeights_Response
+    if not "ReadAuxHeights_Response" in globals(): ReadAuxHeights_Response = namedtuple("ReadAuxHeights_Response", "AuxIDEcho,Contact,Overtravel,AlignDist,SepDist")
+    return ReadAuxHeights_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]))
+
+def SetAuxMode(AuxID:int="", Overtravel:int=""):
+    """
+    Modes manage the way a stage behaves when it is in contact height. AUX site mode
+    holds only a single flag. Flags can be turned on by using the value 1 or turned
+    off by using the value 0. If you do not want to change the flag - use the value
+    of 2. If AUX ID is set to 0, all flags are set for chuck stage. AUX site will
+    move an additional overtravel on every contact move.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Overtravel:int = 2
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxMode 1 2
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxMode",AuxID,Overtravel)
+    return int(rsp[0])
+
+def SetAuxHome(AuxID:int="", Mode:str="", Unit:str="", XValue:Decimal="", YValue:Decimal=""):
+    """
+    Sets the AUX sites Home position in X and Y. It defines the origin of the AUX
+    sites coordinate system for later movements. Usually this position is identical
+    to the die home position.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxHome 1 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxHome",AuxID,Mode,Unit,XValue,YValue)
+    return int(rsp[0])
+
+def SetAuxIndex(AuxID:int="", XValue:Decimal="", YValue:Decimal="", Unit:str=""):
+    """
+    Sets the AUX sites index size. If AUX ID is set to 0, index size is set for
+    chuck stage.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxIndex 1 1000. 1000. Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxIndex",AuxID,XValue,YValue,Unit)
+    return int(rsp[0])
+
+def SetAuxHeight(AuxID:int="", PresetHeight:str="", Mode:str="", Unit:str="", Value:Decimal=""):
+    """
+    Sets the AUX sites contact height and corresponding gaps for overtravel,
+    alignment and separation height. A contact height search gap for contact search
+    with edge sensor can also be set. This search gap is always identical for all
+    AUX sites. Without any optional parameters the command sets contact height to
+    the current position.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        PresetHeight:str = "Contact"
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Value:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxHeight 1 C 0 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxHeight",AuxID,PresetHeight,Mode,Unit,Value)
+    return int(rsp[0])
+
+def ReadAuxIndex(AuxID:int="", Unit:str=""):
+    """
+    Returns the actual AUX sites index values. If AUX ID is set to 0, the index size
+    is read from chuck stage. If no AUX ID is given, it tries to read the index from
+    the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Unit:str = "Microns"
+    Returns:
+        AuxIDEcho:int
+        IndexX:Decimal
+        IndexY:Decimal
+    Command Timeout: 10000
+    Example:ReadAuxIndex 1 Y
+    """
+    rsp = MessageServerInterface.sendSciCommand("ReadAuxIndex",AuxID,Unit)
+    global ReadAuxIndex_Response
+    if not "ReadAuxIndex_Response" in globals(): ReadAuxIndex_Response = namedtuple("ReadAuxIndex_Response", "AuxIDEcho,IndexX,IndexY")
+    return ReadAuxIndex_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetAuxThetaHome(AuxID:int="", Mode:str="", Unit:str="", Position:Decimal=""):
+    """
+    Sets the AUX sites theta home position. It defines the origin of the AUX sites
+    theta coordinate system for later movements. If AUX ID is set to 0, theta home
+    position is set for chuck stage.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Mode:str = "0"
+        Unit:str = "Microns"
+        Position:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxThetaHome 1 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxThetaHome",AuxID,Mode,Unit,Position)
+    return int(rsp[0])
+
+def EnableOffset(Stage:str="", Enable:int="", Move:int=""):
+    """
+    Enables or disables the Offset XY compensation for the selected stage. If the
+    compensation holds an offset different from zero, the chuck is automatically
+    moved the distance of the offset. The chuck also moves automatically to a safe
+    height. The move can be disabled by the third parameter. This may put the stage
+    outside the software fence.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        Enable:int = 1
+        Move:int = 1
+    Command Timeout: 60000
+    Example:EnableOffset C 1
+    """
+    MessageServerInterface.sendSciCommand("EnableOffset",Stage,Enable,Move)
+
+
+def SetOffset(Stage:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+    """
+    Sets the offset values for the Offset XY compensation for the selected stage.
+    The changes take effect immediately. Note that the Offset XY compensation must
+    be enabled for the values to take effect. The compensation is enabled or
+    disabled using EnableOffset command.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+        OffsetX:Decimal = 0
+        OffsetY:Decimal = 0
+    Command Timeout: 5000
+    Example:SetOffset C 100000.0 0.0
+    """
+    MessageServerInterface.sendSciCommand("SetOffset",Stage,OffsetX,OffsetY)
+
+
+def GetOffsetInfo(Stage:str=""):
+    """
+    Gets information about the Offset XY compensation of the selected stage,
+    including the stored offset values and whether the compensation is enabled or
+    disabled.
+    API Status: published
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        Enable:int
+        OffsetX:Decimal
+        OffsetY:Decimal
+    Command Timeout: 5000
+    Example:GetOffsetInfo C
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetOffsetInfo",Stage)
+    global GetOffsetInfo_Response
+    if not "GetOffsetInfo_Response" in globals(): GetOffsetInfo_Response = namedtuple("GetOffsetInfo_Response", "Enable,OffsetX,OffsetY")
+    return GetOffsetInfo_Response(int(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]))
+
+def SetSwitchPosition(Stage:str="", AuxSite:int="", X:Decimal="", Y:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the switch position of a stage. This is the position to move to if an aux
+    site gets active. This is only supported for the chuck and it's aux sites. Aux
+    index 0 means wafer site, 1 means aux site 1 and so on.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        AuxSite:int = 0
+        X:Decimal = 0
+        Y:Decimal = 0
+    Command Timeout: 5000
+    Example:SetSwitchPosition C 0 5000 5000
+    """
+    MessageServerInterface.sendSciCommand("SetSwitchPosition",Stage,AuxSite,X,Y)
+
+
+def MoveAuxSite(AuxID:int=""):
+    """
+    Moves the chuck to the position of a given AUX site. A safe height is used for
+    the move. If AUX ID is set to 0, the target of the move is the wafer site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 60000
+    Example:MoveAuxSite 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveAuxSite",AuxID)
+    return int(rsp[0])
+
+def SetAuxSiteCount(AuxSiteCount:int=""):
+    """
+    Sets the number of available AUX sites. For preparing for example two cal
+    chucks, the count must be set to 2. For the changes to take effect the system
+    needs to be restarted.
+    API Status: published
+    Args:
+        AuxSiteCount:int = 0
+    Command Timeout: 10000
+    Example:SetAuxSiteCount 2
+    """
+    MessageServerInterface.sendSciCommand("SetAuxSiteCount",AuxSiteCount)
+
+
+def GetAuxSiteCount():
+    """
+    Reads the number of available AUX sites and the ID of the actual active AUX
+    site. If this is 0, the chuck stage is currently active.
+    API Status: published
+    Returns:
+        AuxSiteCount:int
+        ActualAuxSite:int
+    Command Timeout: 10000
+    Example:GetAuxSiteCount
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAuxSiteCount")
+    global GetAuxSiteCount_Response
+    if not "GetAuxSiteCount_Response" in globals(): GetAuxSiteCount_Response = namedtuple("GetAuxSiteCount_Response", "AuxSiteCount,ActualAuxSite")
+    return GetAuxSiteCount_Response(int(rsp[0]),int(rsp[1]))
+
+def SetAuxSiteName(AuxID:int="", AuxSiteName:str=""):
+    """
+    Sets the description of an AUX site. With AUX ID zero, the description of the
+    wafer site can be set.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        AuxSiteName:str = ""
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxSiteName 1 Aux site 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxSiteName",AuxID,AuxSiteName)
+    return int(rsp[0])
+
+def GetAuxSiteName(AuxID:int=""):
+    """
+    This command reads the description of an AUX site. If AUX ID is set to 0, the
+    description of the chuck stage is given back. If no AUX ID is given, it tries to
+    read from the active site.
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        AuxSiteName:str
+    Command Timeout: 10000
+    Example:GetAuxSiteName 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetAuxSiteName",AuxID)
+    global GetAuxSiteName_Response
+    if not "GetAuxSiteName_Response" in globals(): GetAuxSiteName_Response = namedtuple("GetAuxSiteName_Response", "AuxIDEcho,AuxSiteName")
+    return GetAuxSiteName_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def CleanProbeTip(AuxID:str=""):
+    """
+    Starts a probe tip cleaning on the given AUX site. The cleaning algorithm is
+    dependent from the type of the AUX site and from the duration and the cleaning
+    count that is set in configuration. The cleaning algorithm includes both a move
+    to the pad site and a move back to the source site.
+    API Status: published
+    Args:
+        AuxID:str = "-1"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 300000
+    Example:CleanProbeTip 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("CleanProbeTip",AuxID)
+    return int(rsp[0])
+
+def SetAuxSiteType(AuxID:int="", AuxSiteType:str=""):
+    """
+    Sets the type for a given AUX site. It depends on the type of the AUX site, if
+    there is a cleaning algorithm available. It is not possible to set the type of
+    the wafer site (AUX site 0).
+    API Status: published
+    Args:
+        AuxID:int = -1
+        AuxSiteType:str = "AuxUnknown"
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetAuxSiteType 1 G
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetAuxSiteType",AuxID,AuxSiteType)
+    return int(rsp[0])
+
+def SetCleaningParams(AuxID:int="", Count:int="", Time:int=""):
+    """
+    Sets the cleaning parameters for a given AUX site. It is not possible to set the
+    cleaning parameters of the wafer site (AUX site 0). If no AUX ID is given, it
+    tries to set the parameters of the active site.     The cleaning count defines,
+    how much times the cleaning is performed repeatedly. The cleaning time defines,
+    how much     milliseconds the needles wait in cleaning position during each
+    cleaning cycle.
+    API Status: published
+    Args:
+        AuxID:int = -1
+        Count:int = 1
+        Time:int = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:SetCleaningParams 1 5 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("SetCleaningParams",AuxID,Count,Time)
+    return int(rsp[0])
+
+def GetCleaningParams(AuxID:int=""):
+    """
+    Reads the cleaning parameters of a given AUX site. It is not possible to read
+    cleaning parameters of the wafer site (AUX site 0).
+    API Status: published
+    Args:
+        AuxID:int = -1
+    Returns:
+        AuxIDEcho:int
+        Count:int
+        Time:int
+        Remaining:int
+    Command Timeout: 30000
+    Example:GetCleaningParams
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCleaningParams",AuxID)
+    global GetCleaningParams_Response
+    if not "GetCleaningParams_Response" in globals(): GetCleaningParams_Response = namedtuple("GetCleaningParams_Response", "AuxIDEcho,Count,Time,Remaining")
+    return GetCleaningParams_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]))
+
+def UpdateAuxSitePositions(AuxID:int="", XOffset:Decimal="", YOffset:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Rotate the switch, home, and fence positions to match the current chuck theta
+    angle and adjust Home/Switch by XY offset. Should only be used for Aux sites
+    that don't move theta.
+    API Status: internal
+    Args:
+        AuxID:int = -1
+        XOffset:Decimal = 0
+        YOffset:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 5000
+    Example:UpdateAuxSitePositions 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("UpdateAuxSitePositions",AuxID,XOffset,YOffset)
+    return int(rsp[0])
+
+def ResetCleaningPosition(AuxID:str="", OffsetX:Decimal="", OffsetY:Decimal=""):
+    """
+    Resets the cleaning position to the beginning of the cleaning aux site (home).
+    API Status: published
+    Args:
+        AuxID:str = "-1"
+        OffsetX:Decimal = 0
+        OffsetY:Decimal = 0
+    Returns:
+        AuxIDEcho:int
+    Command Timeout: 10000
+    Example:ResetCleaningPosition 5
+    """
+    rsp = MessageServerInterface.sendSciCommand("ResetCleaningPosition",AuxID,OffsetX,OffsetY)
+    return int(rsp[0])
+
+def BnR_EchoData(ControllerID:int="", TestCmd:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Test Command for the Kernel Communication. It is like a ping command. The given
+    text string is returned unchanged.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        TestCmd:str = "Test"
+    Returns:
+        TestRsp:str
+    Command Timeout: 5000
+    Example:BnR_EchoData 1 Hello World
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_EchoData",ControllerID,TestCmd)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_ReportKernelVersion(ControllerID:int="", Module:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the actual version information of the controller software.
+    The 'Version' value contains version number and revision level of the actual
+    implementation.                                    The text string contains a
+    code description, version number and the revision date.
+    The 'Module' byte is optional (default is K).
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Module:str = "K"
+    Returns:
+        Version:Decimal
+        Description:str
+    Command Timeout: 5000
+    Example:BnR_ReportKernelVersion 1 K
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReportKernelVersion",ControllerID,Module)
+    global BnR_ReportKernelVersion_Response
+    if not "BnR_ReportKernelVersion_Response" in globals(): BnR_ReportKernelVersion_Response = namedtuple("BnR_ReportKernelVersion_Response", "Version,Description")
+    return BnR_ReportKernelVersion_Response(Decimal(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetStationType(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns information about the connected station.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        StationType:str
+        Type:str
+    Command Timeout: 5000
+    Example:BnR_GetStationType 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetStationType",ControllerID)
+    global BnR_GetStationType_Response
+    if not "BnR_GetStationType_Response" in globals(): BnR_GetStationType_Response = namedtuple("BnR_GetStationType_Response", "StationType,Type")
+    return BnR_GetStationType_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_ResetController(ControllerID:int="", Mode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Restarts the BnR controller.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Mode:str = "X"
+    Command Timeout: 10000
+    Example:BnR_ResetController 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_ResetController",ControllerID,Mode)
+
+
+def BnR_SetOutput(ControllerID:int="", Channel:str="", State:int="", CycleTime:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Controls the Velox output channel signals. It can be used to activate/deactivate
+    outputs.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DO_WaferVacuum"
+        State:int = 0
+        CycleTime:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetOutput 1 1000 1 2000
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetOutput",ControllerID,Channel,State,CycleTime)
+
+
+def BnR_GetOutput(ControllerID:int="", Channel:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the state of an output channel. By using the string identifier DO_ALL, a
+    string list of all outputs is returned in addition
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DO_WaferVacuum"
+    Returns:
+        State:int
+        AllOutputs:str
+    Command Timeout: 5000
+    Example:BnR_GetOutput 1 DO_WaferVacuum
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetOutput",ControllerID,Channel)
+    global BnR_GetOutput_Response
+    if not "BnR_GetOutput_Response" in globals(): BnR_GetOutput_Response = namedtuple("BnR_GetOutput_Response", "State,AllOutputs")
+    return BnR_GetOutput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetInput(ControllerID:int="", Channel:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the state of an input channel. By using the string identifier DI_ALL, a
+    string list of all outputs is returned in addition
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "DI_MotorPower"
+    Returns:
+        State:int
+        AllInputs:str
+    Command Timeout: 5000
+    Example:BnR_GetInput 1 DI_MotorPower
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetInput",ControllerID,Channel)
+    global BnR_GetInput_Response
+    if not "BnR_GetInput_Response" in globals(): BnR_GetInput_Response = namedtuple("BnR_GetInput_Response", "State,AllInputs")
+    return BnR_GetInput_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_SetAnalogOutput(ControllerID:int="", Channel:str="", OutputPercent:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets an analog output channel to a given value.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "AO_PurgeDewPoint"
+        OutputPercent:Decimal = 50
+    Command Timeout: 5000
+    Example:BnR_SetAnalogOutput 1 AO_PurgeDewPoint 50
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetAnalogOutput",ControllerID,Channel,OutputPercent)
+
+
+def BnR_GetAnalogIO(ControllerID:int="", Channel:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current value of an analog output or input.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Channel:str = "AO_PurgeDewPoint"
+    Returns:
+        Value:Decimal
+        UnderOverflow:int
+    Command Timeout: 5000
+    Example:BnR_GetAnalogIO 1 AO_PurgeDewPoint
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAnalogIO",ControllerID,Channel)
+    global BnR_GetAnalogIO_Response
+    if not "BnR_GetAnalogIO_Response" in globals(): BnR_GetAnalogIO_Response = namedtuple("BnR_GetAnalogIO_Response", "Value,UnderOverflow")
+    return BnR_GetAnalogIO_Response(Decimal(rsp[0]),int(rsp[1]))
+
+def BnR_GetStartupStatus(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the startup status of the BnR controller to determine if the controller
+    is properly booted or still starting.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        StartupStatus:str
+        AdditionalStatusInfo:str
+    Command Timeout: 5000
+    Example:BnR_GetStartupStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetStartupStatus",ControllerID)
+    global BnR_GetStartupStatus_Response
+    if not "BnR_GetStartupStatus_Response" in globals(): BnR_GetStartupStatus_Response = namedtuple("BnR_GetStartupStatus_Response", "StartupStatus,AdditionalStatusInfo")
+    return BnR_GetStartupStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_CreateSdmSystemDump(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Creates a Sdm System Dump file on the B&R flash
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Command Timeout: 60000
+    Example:BnR_CreateSdmSystemDump
+    """
+    MessageServerInterface.sendSciCommand("BnR_CreateSdmSystemDump",ControllerID)
+
+
+def BnR_GetControllerData(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Gets controller data from the B&R controller. Currently used for init
+    information.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Command Timeout: 10000
+    Example:BnR_GetControllerData 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_GetControllerData",ControllerID)
+
+
+def BnR_WriteMessage(ControllerID:int="", MessageType:str="", Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to write a (native) message to Controller
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        MessageType:str = "mtCryoLoader"
+        Message:str = ""
+    Command Timeout: 5000
+    Example:BnR_WriteMessage 1 mtCryoLoader SampleMessage
+    """
+    MessageServerInterface.sendSciCommand("BnR_WriteMessage",ControllerID,MessageType,Message)
+
+
+def BnR_ReadMessage(ControllerID:int="", MessageType:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to read a (native) message from Controller
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        MessageType:str = "mtCryoLoader"
+    Returns:
+        Message:str
+    Command Timeout: 5000
+    Example:BnR_ReadMessage 1 mtCryoLoader
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReadMessage",ControllerID,MessageType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetDataIterator(ControllerID:int="", ShowAll:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a data stream handle which represents a data stream of setup parameters
+    and requires the BnR_GetNextDatum command.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        ShowAll:int = 0
+    Returns:
+        IdentityToken:int
+        SizeNoAll:int
+    Command Timeout: 5000
+    Example:BnR_GetDataIterator 1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetDataIterator",ControllerID,ShowAll)
+    global BnR_GetDataIterator_Response
+    if not "BnR_GetDataIterator_Response" in globals(): BnR_GetDataIterator_Response = namedtuple("BnR_GetDataIterator_Response", "IdentityToken,SizeNoAll")
+    return BnR_GetDataIterator_Response(int(rsp[0]),int(rsp[1]))
+
+def BnR_GetNextDatum(ControllerID:int="", IdentityToken:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the next parameter from the data stream. Fields are separated by a
+    colon. Structure of the response parameter Value:
+    Path_Path:Name:Description:Value
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        IdentityToken:int = 0
+    Returns:
+        IsLastDatum:int
+        DatumCode:int
+        PathNameDescrValue:str
+    Command Timeout: 10000
+    Example:BnR_GetNextDatum 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetNextDatum",ControllerID,IdentityToken)
+    global BnR_GetNextDatum_Response
+    if not "BnR_GetNextDatum_Response" in globals(): BnR_GetNextDatum_Response = namedtuple("BnR_GetNextDatum_Response", "IsLastDatum,DatumCode,PathNameDescrValue")
+    return BnR_GetNextDatum_Response(int(rsp[0]),int(rsp[1]),str("" if len(rsp) < 3 else ' '.join(rsp[2:])))
+
+def BnR_SetDatum(ControllerID:int="", PathNameAndValue:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the value of a parameter. An empty parameter string saves the whole
+    configuration to non-volatile memory. Fields are separated by a colon.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        PathNameAndValue:str = ""
+    Command Timeout: 20000
+    Example:BnR_SetDatum 1 Chuck_XAxisData:CurrentMaximal:70
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetDatum",ControllerID,PathNameAndValue)
+
+
+def BnR_GetDatum(ControllerID:int="", PathName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a value string. The Value string consists of the value and the
+    description. The Locator only consists of the path and the name. All fields are
+    separated by a colon.  Structure of the command parameter Locator:
+    Path_Path:Name Structure of the response parameter Value: Value:Description
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        PathName:str = ""
+    Returns:
+        DatumCode:int
+        ValueDesc:str
+    Command Timeout: 5000
+    Example:BnR_GetDatum 1 Chuck_XAxisData:CurrentMaximal
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetDatum",ControllerID,PathName)
+    global BnR_GetDatum_Response
+    if not "BnR_GetDatum_Response" in globals(): BnR_GetDatum_Response = namedtuple("BnR_GetDatum_Response", "DatumCode,ValueDesc")
+    return BnR_GetDatum_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_DoInternalTask(ControllerID:int="", Task:str="", PCmdInt1:int="", PCmdInt2:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes an internal BnR Task
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Task:str = ""
+        PCmdInt1:int = 0
+        PCmdInt2:int = 0
+    Returns:
+        RspInt:int
+        RspString:str
+    Command Timeout: 10000
+    Example:BnR_DoInternalTask 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_DoInternalTask",ControllerID,Task,PCmdInt1,PCmdInt2)
+    global BnR_DoInternalTask_Response
+    if not "BnR_DoInternalTask_Response" in globals(): BnR_DoInternalTask_Response = namedtuple("BnR_DoInternalTask_Response", "RspInt,RspString")
+    return BnR_DoInternalTask_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetPosition(Stage:str="", Unit:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current positions for the X,Y,Z (or T) axis for the specified stage
+    as well as the commanded positions.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Unit:str = "Microns"
+    Returns:
+        XorT:Decimal
+        Y:Decimal
+        Z:Decimal
+        CommandedXorT:Decimal
+        CommandedY:Decimal
+        CommandedZ:Decimal
+    Command Timeout: 5000
+    Example:BnR_GetPosition 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetPosition",Stage,Unit)
+    global BnR_GetPosition_Response
+    if not "BnR_GetPosition_Response" in globals(): BnR_GetPosition_Response = namedtuple("BnR_GetPosition_Response", "XorT,Y,Z,CommandedXorT,CommandedY,CommandedZ")
+    return BnR_GetPosition_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]))
+
+def BnR_Move(Stage:str="", XValue:Decimal="", YValue:Decimal="", VelX:Decimal="", VelY:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command executes a XY movement for a specified stage. This can be either a
+    blocking or non blocking move.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        VelX:Decimal = 0
+        VelY:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        X:Decimal
+        Y:Decimal
+    Command Timeout: 60000
+    Example:BnR_Move 1 C 5000 5000 Z 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_Move",Stage,XValue,YValue,VelX,VelY,WaitFinished)
+    global BnR_Move_Response
+    if not "BnR_Move_Response" in globals(): BnR_Move_Response = namedtuple("BnR_Move_Response", "X,Y")
+    return BnR_Move_Response(Decimal(rsp[0]),Decimal(rsp[1]))
+
+def BnR_MoveZ(Stage:str="", ZValue:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the stage Z axis to a new position.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZValue:Decimal = 0
+        Vel:Decimal = 0
+        Dec:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        Z:Decimal
+    Command Timeout: 600000
+    Example:BnR_MoveZ 1 C 12000 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveZ",Stage,ZValue,Vel,Dec,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_ScanMoveZ(ControllerID:int="", Stage:str="", ZDistance:Decimal="", TriggerEveryNthCycle:int="", Vel:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command executes a scan movement of the Z axis that sets a digital output
+    every couple microns to trigger e.g. a camera. After the move is finished, the
+    command returns a list of Z heights at which the digital output was set.
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Stage:str = "Chuck"
+        ZDistance:Decimal = 1000
+        TriggerEveryNthCycle:int = 2
+        Vel:Decimal = 10
+    Command Timeout: 300000
+    Example:BnR_ScanMoveZ 1 C 1000 6 10
+    """
+    MessageServerInterface.sendSciCommand("BnR_ScanMoveZ",ControllerID,Stage,ZDistance,TriggerEveryNthCycle,Vel)
+
+
+def BnR_MoveT(TValue:Decimal="", Vel:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Executes a movement of the theta axis, either blocking or non blocking
+    API Status: internal
+    Args:
+        TValue:Decimal = 0
+        Vel:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        T:Decimal
+    Command Timeout: 60000
+    Example:BnR_MoveT 1 1.003 10 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveT",TValue,Vel,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_StopAxis(Stage:str="", FlagsStop:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Stops 1... all axes of a stage
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        FlagsStop:int = 15
+    Command Timeout: 5000
+    Example:BnR_StopAxis 1 C 7
+    """
+    MessageServerInterface.sendSciCommand("BnR_StopAxis",Stage,FlagsStop)
+
+
+def BnR_InitAxis(Stage:str="", FlagsInit:int="", FlagsDirection:int="", FlagsInitInPlace:int="", LowLimitX:Decimal="", LowLimitY:Decimal="", LowLimitZ:Decimal="", LowLimitTh:Decimal="", InitInPlaceMoveRangeX:Decimal="", InitInPlaceMoveRangeY:Decimal="", InitInPlaceMoveRangeZ:Decimal="", InitInPlaceMoveRangeTh:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Machine Coordinate System: X Y Z Theta  - _FlagsInit_: X, Y, Z, Theta -
+    _FlagsDirection_: X, Y, Z, Theta (true means plus direction) -
+    _FlagsInitInPlace_: X, Y, Z, Theta   All flags can be accessed by indirect
+    members. Initializes the stage and resets current coordinate system. Should be
+    used only in cases when the reported coordinates do not correspond to real
+    position of mechanics. Init in Place performs the initialization without any
+    movements.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        FlagsInit:int = 0
+        FlagsDirection:int = 0
+        FlagsInitInPlace:int = 0
+        LowLimitX:Decimal = 0
+        LowLimitY:Decimal = 0
+        LowLimitZ:Decimal = 0
+        LowLimitTh:Decimal = 0
+        InitInPlaceMoveRangeX:Decimal = 0
+        InitInPlaceMoveRangeY:Decimal = 0
+        InitInPlaceMoveRangeZ:Decimal = 0
+        InitInPlaceMoveRangeTh:Decimal = 0
+    Command Timeout: 300000
+    Example:BnR_InitAxis 1 C 7
+    """
+    MessageServerInterface.sendSciCommand("BnR_InitAxis",Stage,FlagsInit,FlagsDirection,FlagsInitInPlace,LowLimitX,LowLimitY,LowLimitZ,LowLimitTh,InitInPlaceMoveRangeX,InitInPlaceMoveRangeY,InitInPlaceMoveRangeZ,InitInPlaceMoveRangeTh)
+
+
+def BnR_GetAxisState(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns the state of an axis (disabled/standstill/errorstop/stoppin
+    g/homing/continuousmotion/discretemotion/synchronizedmotion)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        State:str
+        AdditionalStateInfo:str
+    Command Timeout: 5000
+    Example:BnR_GetAxisState 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisState",Stage,Axis)
+    global BnR_GetAxisState_Response
+    if not "BnR_GetAxisState_Response" in globals(): BnR_GetAxisState_Response = namedtuple("BnR_GetAxisState_Response", "State,AdditionalStateInfo")
+    return BnR_GetAxisState_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def BnR_GetAxisStatus(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns some axis status information
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        Initialized:int
+        PositiveEndlimit:int
+        NegativeEndlimit:int
+    Command Timeout: 5000
+    Example:BnR_GetAxisStatus 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetAxisStatus",Stage,Axis)
+    global BnR_GetAxisStatus_Response
+    if not "BnR_GetAxisStatus_Response" in globals(): BnR_GetAxisStatus_Response = namedtuple("BnR_GetAxisStatus_Response", "Initialized,PositiveEndlimit,NegativeEndlimit")
+    return BnR_GetAxisStatus_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]))
+
+def BnR_SetQuietMode(Stage:str="", QuietMode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to enable the quiet mode for a stage (quiet turns motors powerless)
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        QuietMode:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetQuietMode 1 C 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetQuietMode",Stage,QuietMode)
+
+
+def BnR_GetQuietMode(Stage:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to query the quiet mode for a stage
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+    Returns:
+        QuietMode:int
+    Command Timeout: 5000
+    Example:BnR_GetQuietMode 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetQuietMode",Stage)
+    return int(rsp[0])
+
+def BnR_GetInternalAxisInfo(Stage:str="", Axis:str="", InfoType:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command returns various axis information, dependent on the InfoType
+    parameter
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        InfoType:str = "StallInfo"
+    Returns:
+        RspString:str
+    Command Timeout: 5000
+    Example:BnR_GetInternalAxisInfo 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetInternalAxisInfo",Stage,Axis,InfoType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_GetWiringTesterData(Stage:str="", Axis:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command to get various information required for the BnR wiring tester tool.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+    Returns:
+        STIn_ModuleOK:int
+        STIn_LifeCnt:int
+        STIn_DrvOK:int
+        STIn_OvertemperatureError:int
+        STIn_CurrentError:int
+        STIn_OvercurrentError:int
+        STIn_RefPulsePos:int
+        STIn_RefPulseCnt:int
+        STIn_ModulePowerSupplyError:int
+        STOut_SetTime:int
+        STOut_MotorStep0:int
+        STOut_DriveEnable:int
+        STOut_BoostCurrent:int
+        STOut_StandStillCurrent:int
+        STOut_ClearError:int
+        CMIn_ModuleOK:int
+        CMIn_SDCLifeCount:int
+        CMIn_Encoder:int
+        CMIn_EncoderTimeValid:int
+        CMIn_DigitalInput1:int
+        CMIn_DigitalInput2:int
+        CMIn_BWChannelA:int
+        CMIn_BWChannelB:int
+        CMIn_PowerSupply2:int
+        CMOut_QuitChannelA:int
+        CMOut_QuitChannelB:int
+        SWAxisErrorID:int
+        SWAxisErrorDesc:str
+    Command Timeout: 5000
+    Example:BnR_GetWiringTesterData 1 C X
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetWiringTesterData",Stage,Axis)
+    global BnR_GetWiringTesterData_Response
+    if not "BnR_GetWiringTesterData_Response" in globals(): BnR_GetWiringTesterData_Response = namedtuple("BnR_GetWiringTesterData_Response", "STIn_ModuleOK,STIn_LifeCnt,STIn_DrvOK,STIn_OvertemperatureError,STIn_CurrentError,STIn_OvercurrentError,STIn_RefPulsePos,STIn_RefPulseCnt,STIn_ModulePowerSupplyError,STOut_SetTime,STOut_MotorStep0,STOut_DriveEnable,STOut_BoostCurrent,STOut_StandStillCurrent,STOut_ClearError,CMIn_ModuleOK,CMIn_SDCLifeCount,CMIn_Encoder,CMIn_EncoderTimeValid,CMIn_DigitalInput1,CMIn_DigitalInput2,CMIn_BWChannelA,CMIn_BWChannelB,CMIn_PowerSupply2,CMOut_QuitChannelA,CMOut_QuitChannelB,SWAxisErrorID,SWAxisErrorDesc")
+    return BnR_GetWiringTesterData_Response(int(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),int(rsp[4]),int(rsp[5]),int(rsp[6]),int(rsp[7]),int(rsp[8]),int(rsp[9]),int(rsp[10]),int(rsp[11]),int(rsp[12]),int(rsp[13]),int(rsp[14]),int(rsp[15]),int(rsp[16]),int(rsp[17]),int(rsp[18]),int(rsp[19]),int(rsp[20]),int(rsp[21]),int(rsp[22]),int(rsp[23]),int(rsp[24]),int(rsp[25]),int(rsp[26]),str("" if len(rsp) < 28 else ' '.join(rsp[27:])))
+
+def BnR_MoveAxis(Stage:str="", Axis:str="", Value:Decimal="", Vel:Decimal="", Dec:Decimal="", WaitFinished:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command allows moving a single axis to and e.g. in case of X does not
+    trigger a Y movement
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        Value:Decimal = 0
+        Vel:Decimal = 0
+        Dec:Decimal = 0
+        WaitFinished:int = 1
+    Returns:
+        PositionAfterMove:Decimal
+    Command Timeout: 60000
+    Example:BnR_MoveAxis 1 C X 20000 100 100 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveAxis",Stage,Axis,Value,Vel,Dec,WaitFinished)
+    return Decimal(rsp[0])
+
+def BnR_MoveZCombined(ChuckTargetZ:Decimal="", WaitFinished:int="", ForcedAbsVelocity:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move Chuck-Z and (by fixed factor) Scope X, Y and Z
+    API Status: internal
+    Args:
+        ChuckTargetZ:Decimal = 0
+        WaitFinished:int = 1
+        ForcedAbsVelocity:int = 0
+    Returns:
+        ChuckZ:Decimal
+        ScopeX:Decimal
+        ScopeY:Decimal
+        ScopeZ:Decimal
+    Command Timeout: 600000
+    Example:BnR_MoveZCombined 1 17592.5 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_MoveZCombined",ChuckTargetZ,WaitFinished,ForcedAbsVelocity)
+    global BnR_MoveZCombined_Response
+    if not "BnR_MoveZCombined_Response" in globals(): BnR_MoveZCombined_Response = namedtuple("BnR_MoveZCombined_Response", "ChuckZ,ScopeX,ScopeY,ScopeZ")
+    return BnR_MoveZCombined_Response(Decimal(rsp[0]),Decimal(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]))
+
+def BnR_StepMove(Stage:str="", ZDown:Decimal="", XValue:Decimal="", YValue:Decimal="", ZUp:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    This command does a combined Z-XY-Z- move completely on the BnR-controller
+    without WinKernel interaction. This is a part of an ongoing optimization.
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        ZDown:Decimal = 0
+        XValue:Decimal = 0
+        YValue:Decimal = 0
+        ZUp:Decimal = 0
+    Command Timeout: 60000
+    Example:BnR_StepMove 1 C 250 1000 1000 250
+    """
+    MessageServerInterface.sendSciCommand("BnR_StepMove",Stage,ZDown,XValue,YValue,ZUp)
+
+
+def BnR_SearchEdgeSensor(SearchEndPos:Decimal="", Velocity:Decimal=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Performs a search move until the search end position is reached or the edge
+    sensor triggers. If the edge sensor triggers during the move, the trigger
+    position is returned.Otherwise, an edge sensor not found error is returned.
+    API Status: internal
+    Args:
+        SearchEndPos:Decimal = 0
+        Velocity:Decimal = 0
+    Returns:
+        EdgeSensorTriggerPos:Decimal
+    Command Timeout: 300000
+    Example:BnR_SearchEdgeSensor 3000 10
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_SearchEdgeSensor",SearchEndPos,Velocity)
+    return Decimal(rsp[0])
+
+def BnR_GetTraceData(ControllerID:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns a collection of trace data
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+    Returns:
+        Data:str
+    Command Timeout: 5000
+    Example:BnR_GetTraceData 1 C
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_GetTraceData",ControllerID)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def BnR_SetTraceMode(ControllerID:int="", Mode:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Commands sets the trace mode
+    API Status: internal
+    Args:
+        ControllerID:int = 1
+        Mode:int = 0
+    Command Timeout: 5000
+    Example:BnR_SetTraceMode 1 1
+    """
+    MessageServerInterface.sendSciCommand("BnR_SetTraceMode",ControllerID,Mode)
+
+
+def BnR_WriteAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str="", Value:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Development command to change a module register value without controller restart
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        MotorModule:int = 0
+        RegisterName:str = ""
+        Value:int = 0
+    Command Timeout: 5000
+    Example:BnR_WriteAxisModuleRegister 1 C X 1 ConfigOutput03 70
+    """
+    MessageServerInterface.sendSciCommand("BnR_WriteAxisModuleRegister",Stage,Axis,MotorModule,RegisterName,Value)
+
+
+def BnR_ReadAxisModuleRegister(Stage:str="", Axis:str="", MotorModule:int="", RegisterName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Development command to get any desired module register value
+    API Status: internal
+    Args:
+        Stage:str = "Chuck"
+        Axis:str = "XAxis"
+        MotorModule:int = 0
+        RegisterName:str = ""
+    Returns:
+        Value:int
+    Command Timeout: 5000
+    Example:BnR_ReadAxisModuleRegister 1 C X 1 ConfigOutput03
+    """
+    rsp = MessageServerInterface.sendSciCommand("BnR_ReadAxisModuleRegister",Stage,Axis,MotorModule,RegisterName)
+    return int(rsp[0])
+
+def ProcessStationGetStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns process station status (UNKNOWN, IDLE, BUSY, ERROR, PAUSED, Not
+    Initialized) and error code with error message when error.
+    API Status: internal
+    Returns:
+        Status:str
+        SubstratePresent:int
+        LastError:int
+        UseLoaderModule:int
+        WaferSizes:str
+        StatusMessage:str
+        IsLoaderJobRunning:int
+    Command Timeout: 25000
+    Example:ProcessStationGetStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationGetStatus")
+    global ProcessStationGetStatus_Response
+    if not "ProcessStationGetStatus_Response" in globals(): ProcessStationGetStatus_Response = namedtuple("ProcessStationGetStatus_Response", "Status,SubstratePresent,LastError,UseLoaderModule,WaferSizes,StatusMessage,IsLoaderJobRunning")
+    return ProcessStationGetStatus_Response(str(rsp[0]),int(rsp[1]),int(rsp[2]),int(rsp[3]),str(rsp[4]),str(rsp[5]),int(rsp[6]))
+
+def ProcessStationInit():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Initialize process station machine. This is not the prober init it is a fast
+    program initialization. Only applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 2400000
+    Example:ProcessStationInit
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationInit")
+
+
+def ProcessStationFinish():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Finishes a process station process. This resets some internal test information
+    for the probe station. Some data is only reset in case this command is sent
+    after the last wafer in the job was tested. Only applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 7500000
+    Example:ProcessStationFinish
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationFinish")
+
+
+def ProcessStationPrepareForLoad():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Command moves the chuck of the probe station to the secondary load position and
+    if available also checks the table level sensor. Only applies to fully auto
+    systems.
+    API Status: internal
+    Command Timeout: 120000
+    Example:ProcessStationPrepareForLoad
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPrepareForLoad")
+
+
+def ProcessStationLoadComplete():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Moves the chuck out of the load position and checks if a wafer is placed. Only
+    applies to fully auto systems.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationLoadComplete
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationLoadComplete")
+
+
+def ProcessStationPrepareForUnLoad():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The module should do whatever is necessary to prepare the current wafer for
+    unload. Typically this includes things such as moving lift pins and opening
+    doors.
+    API Status: internal
+    Command Timeout: 1000000
+    Example:ProcessStationPrepareForUnLoad
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPrepareForUnLoad")
+
+
+def ProcessStationUnLoadComplete():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The module should so whatever is necessary after a wafer is unloaded. This may
+    for example include closing doors.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationUnLoadComplete
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationUnLoadComplete")
+
+
+def ProcessStationLoadRecipe(ForceReOpenProject:int="", ProjectFileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    The recipe is a zipped archive that includes all project data. This command
+    tells the device to load the recipe.
+    API Status: internal
+    Args:
+        ForceReOpenProject:int = 0
+        ProjectFileName:str = ""
+    Command Timeout: 60000
+    Example:ProcessStationLoadRecipe 1 SampleProject.spp
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationLoadRecipe",ForceReOpenProject,ProjectFileName)
+
+
+def ProcessStationVerifyRecipe(ProjectFileName:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Requests that the device verify that the recipe given can be executed on the
+    device. It should check that the recipe is correctly formed and conforms to the
+    hardware of the device. It should not check for transient things such as whether
+    there is sufficient media or facilities available. those kinds of checks should
+    be done in PrepareForProcess
+    API Status: internal
+    Args:
+        ProjectFileName:str = ""
+    Returns:
+        Verified:int
+        ErrorDescription:str
+    Command Timeout: 60000
+    Example:ProcessStationVerifyRecipe SampleProject.spp
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationVerifyRecipe",ProjectFileName)
+    global ProcessStationVerifyRecipe_Response
+    if not "ProcessStationVerifyRecipe_Response" in globals(): ProcessStationVerifyRecipe_Response = namedtuple("ProcessStationVerifyRecipe_Response", "Verified,ErrorDescription")
+    return ProcessStationVerifyRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def ProcessStationStartRecipe(CurrentWaferInJob:int="", TotalWafersInJob:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells VeloxPro to start the current recipe. The station will switch to error if
+    an error occurs. If VeloxPro recipe execution is currently paused, this command
+    tells the system to continue execution.
+    API Status: internal
+    Args:
+        CurrentWaferInJob:int = -1
+        TotalWafersInJob:int = -1
+    Command Timeout: 25000
+    Example:ProcessStationStartRecipe 1
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationStartRecipe",CurrentWaferInJob,TotalWafersInJob)
+
+
+def ProcessStationStopRecipe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells the device to stop the current recipe. The station will switch to error if
+    an error occurs.
+    API Status: internal
+    Command Timeout: 25000
+    Example:ProcessStationStopRecipe
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationStopRecipe")
+
+
+def ProcessStationRecoverError():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Tells the module to do whatever is necessary to recover from an error condition.
+    API Status: internal
+    Command Timeout: 60000
+    Example:ProcessStationRecoverError
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationRecoverError")
+
+
+def ProcessStationGetWaferResult():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get substrate information from process station controller application.
+    API Status: internal
+    Returns:
+        Result:str
+        PercentDone:Decimal
+        AllowSkipWafer:int
+        TestInformation:str
+    Command Timeout: 25000
+    Example:ProcessStationGetWaferResult
+    """
+    rsp = MessageServerInterface.sendSciCommand("ProcessStationGetWaferResult")
+    global ProcessStationGetWaferResult_Response
+    if not "ProcessStationGetWaferResult_Response" in globals(): ProcessStationGetWaferResult_Response = namedtuple("ProcessStationGetWaferResult_Response", "Result,PercentDone,AllowSkipWafer,TestInformation")
+    return ProcessStationGetWaferResult_Response(str(rsp[0]),Decimal(rsp[1]),int(rsp[2]),str("" if len(rsp) < 4 else ' '.join(rsp[3:])))
+
+def QueryWaferInfo():
+    """
+    Returns information about the wafer that is currently on the probe station. It
+    will return an error when there is no wafer currently on the chuck.
+    API Status: published
+    Returns:
+        Size:int
+        Angle:Decimal
+        ID:str
+        LotID:str
+        ProductID:str
+    Command Timeout: 25000
+    Example:QueryWaferInfo
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryWaferInfo")
+    global QueryWaferInfo_Response
+    if not "QueryWaferInfo_Response" in globals(): QueryWaferInfo_Response = namedtuple("QueryWaferInfo_Response", "Size,Angle,ID,LotID,ProductID")
+    return QueryWaferInfo_Response(int(rsp[0]),Decimal(rsp[1]),str(rsp[2]),str(rsp[3]),str("" if len(rsp) < 5 else ' '.join(rsp[4:])))
+
+def ProcessStationPauseRecipe():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Sets the process station to PAUSE mode
+    API Status: internal
+    Command Timeout: 25000
+    Example:ProcessStationPauseRecipe
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationPauseRecipe")
+
+
+def GetProbingStatus():
+    """
+    Retrieves the current status of the prober. If probing status is AtFirstDie the
+    tester can take control.
+    API Status: published
+    Returns:
+        Status:str
+    Command Timeout: 25000
+    Example:GetProbingStatus
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetProbingStatus")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedProbing():
+    """
+    Tells the prober to proceed the recipe when current status is AtFirstDie.
+    API Status: published
+    Command Timeout: 25000
+    Example:ProceedProbing
+    """
+    MessageServerInterface.sendSciCommand("ProceedProbing")
+
+
+def GetCassetteStatus(Cassette:int=""):
+    """
+    Provides all available wafer information. It returns a set of data for each
+    wafer in either cassette. The data contains the cassette and the slot number
+    where the wafer is located, the status of the wafer, and identification
+    information.
+    API Status: published
+    Args:
+        Cassette:int = 0
+    Returns:
+        CassetteStatus:str
+    Command Timeout: 25000
+    Example:GetCassetteStatus 0
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetCassetteStatus",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def QueryWaferID(Module:str="", Slot:int=""):
+    """
+    Queries the wafer ID of a given module and slot.
+    API Status: published
+    Args:
+        Module:str = "Robot"
+        Slot:int = 0
+    Returns:
+        ID:str
+    Command Timeout: 25000
+    Example:QueryWaferID Cassette1 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryWaferID",Module,Slot)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def UpdateWaferID(Module:str="", Slot:int="", ID:str=""):
+    """
+    Overrides the wafer ID of the given module and slot. If the wafer id is empty
+    and the module is a Loadport, the id will be read by the idreader if possible.
+    This process behaves as follows:  - the current wafer id is reset - if the read-
+    wafer-process would be delayed (e.g. there is already a   wafer on the idreader)
+    the process will be aborted and an error         will be returned - if the id-
+    reading fails, the process behaves like a normal inventory  triggered by the UI:
+    skip (returns success), abort (returns error)      or "ask user". It is
+    recomended to use either skip or abort for         remote id reading.  If the
+    module is a Loadport and the slot is set to -1, a regular inventory will be
+    triggered. This behaves similar to an inventory triggered by the UI: The ID
+    won't be reset and already scanned wafers won't be reset. Setting an ID
+    explicitly with slot -1 is an error:  - Okay, read id of wafer in slot 3 even if
+    it is already set: UpdateWaferID Cassette1 3 - Okay, set id of wafer in slot 3
+    to XYZ123: UpdateWaferID Cassette1 3 XYZ123 - Okay, start full inventory:
+    UpdateWaferID Cassette1 -1  - Error: UpdateWaferID Cassette1 -1 XYZ123
+    API Status: published
+    Args:
+        Module:str = "Robot"
+        Slot:int = 0
+        ID:str = ""
+    Command Timeout: 1500000
+    Example:UpdateWaferID Cassette1 1 Wafer01
+    """
+    MessageServerInterface.sendSciCommand("UpdateWaferID",Module,Slot,ID)
+
+
+def ConfirmRecipe(ProjectFileName:str=""):
+    """
+    Queries whether the given project/flow name is a valid project/flow at the probe
+    station.  Using file and folder names without white spaces is recommended. For
+    folders and files whith white spaces use quotation marks for the path.  Example
+    for using white spaces:  ConfirmRecipe
+    "C:/Users/Public/Documents/Velox/Projects/White Spaces.spp"
+    API Status: published
+    Args:
+        ProjectFileName:str = ""
+    Returns:
+        Verified:int
+        ErrorDescription:str
+    Command Timeout: 25000
+    Example:ConfirmRecipe C:/Temp/Test.spp
+    """
+    rsp = MessageServerInterface.sendSciCommand("ConfirmRecipe",ProjectFileName)
+    global ConfirmRecipe_Response
+    if not "ConfirmRecipe_Response" in globals(): ConfirmRecipe_Response = namedtuple("ConfirmRecipe_Response", "Verified,ErrorDescription")
+    return ConfirmRecipe_Response(int(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def StartWaferJob(RecipeName:str="", WaferIDs:str=""):
+    """
+    Creates and starts a new job by specifying the flow/spp file and the wafers to
+    be included in the job.
+    API Status: published
+    Args:
+        RecipeName:str = ""
+        WaferIDs:str = ""
+    Returns:
+        JobID:str
+    Command Timeout: 25000
+    Example:StartWaferJob C:/Users/Public/Documents/Velox/Test.flow 1;1 2;1
+    """
+    rsp = MessageServerInterface.sendSciCommand("StartWaferJob",RecipeName,WaferIDs)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def GetJobParams(JobID:str=""):
+    """
+    Get job information for a specific job ID including the flow file and the list
+    of wafers.
+    API Status: published
+    Args:
+        JobID:str = ""
+    Returns:
+        RecipeName:str
+        WaferIDs:str
+    Command Timeout: 25000
+    Example:GetJobParams 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetJobParams",JobID)
+    global GetJobParams_Response
+    if not "GetJobParams_Response" in globals(): GetJobParams_Response = namedtuple("GetJobParams_Response", "RecipeName,WaferIDs")
+    return GetJobParams_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def JobStatus(JobID:str=""):
+    """
+    Retrieves the status of a specific job by its ID. If the status is ErrorWaiting,
+    an error string is returned.
+    API Status: published
+    Args:
+        JobID:str = ""
+    Returns:
+        Status:str
+        JobStatusInfo:str
+    Command Timeout: 25000
+    Example:JobStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("JobStatus",JobID)
+    global JobStatus_Response
+    if not "JobStatus_Response" in globals(): JobStatus_Response = namedtuple("JobStatus_Response", "Status,JobStatusInfo")
+    return JobStatus_Response(str(rsp[0]),str("" if len(rsp) < 2 else ' '.join(rsp[1:])))
+
+def AbortJob(JobID:str="", Unload:int=""):
+    """
+    Aborts the job given by the job ID. The status of the job will be set to
+    "Aborted". The "Unload" parameter defines whether the wafer remains on the chuck
+    or not.
+    API Status: published
+    Args:
+        JobID:str = ""
+        Unload:int = 0
+    Command Timeout: 25000
+    Example:AbortJob 2 1
+    """
+    MessageServerInterface.sendSciCommand("AbortJob",JobID,Unload)
+
+
+def ProcessStationCloseApplication(NoUserPrompt:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Closes the VeloxPro application.
+    API Status: internal
+    Args:
+        NoUserPrompt:int = 0
+    Command Timeout: 25000
+    Example:ProcessStationCloseApplication
+    """
+    MessageServerInterface.sendSciCommand("ProcessStationCloseApplication",NoUserPrompt)
+
+
+def UnloadWafer():
+    """
+    Unolads a Wafer from the chuck to its origin. If no origin is known, the first
+    free Slot of a loadport will be chosen. A Wafer should be on the chuck.
+    API Status: published
+    Command Timeout: 600000
+    Example:UnloadWafer
+    """
+    MessageServerInterface.sendSciCommand("UnloadWafer")
+
+
+def GetJobList(JobType:str=""):
+    """
+    Returns a string for the relevant JobIDs.
+    API Status: published
+    Args:
+        JobType:str = "Probing"
+    Returns:
+        GetJobList:str
+    Command Timeout: 25000
+    Example:GetJobList
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetJobList",JobType)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def ProceedJob(ProceedJob:str=""):
+    """
+    Continues a job that is waiting on an error (Job Status ErrorWaiting). The mode
+    determines how the job continues.
+    API Status: published
+    Args:
+        ProceedJob:str = "AbortJob"
+    Command Timeout: 25000
+    Example:ProceedJob AbortJob
+    """
+    MessageServerInterface.sendSciCommand("ProceedJob",ProceedJob)
+
+
+def QueryCassetteID(Cassette:int=""):
+    """
+    Returns the ID of a cassette that is placed on the load port. The loadport and
+    the cassette must support RFID reading (additional hardware needed).
+    API Status: published
+    Args:
+        Cassette:int = 1
+    Returns:
+        ID:str
+    Command Timeout: 25000
+    Example:QueryCassetteID 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("QueryCassetteID",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def DockCassette(LoadPortId:int="", DockUndock:int=""):
+    """
+    Docks or undocks a cassette which is placed on a LoadPort (CM300 only). It will
+    return an error if no cassette is placed: the LoadPort is not ready/available or
+    the docking failed. The command will do the docking/undocking and return when
+    this is done.
+    API Status: published
+    Args:
+        LoadPortId:int = 0
+        DockUndock:int = 0
+    Command Timeout: 60000
+    Example:DockCassette 1 1
+    """
+    MessageServerInterface.sendSciCommand("DockCassette",LoadPortId,DockUndock)
+
+
+def LoadWafer(LoadportID:int="", SlotID:int="", AlignmentAngle:Decimal=""):
+    """
+    Load a wafer from a given loadport onto the prober. If no slot id is defined,
+    the first available wafer with the lowest slot id will be loaded. If no loadport
+    is defined, it will try to use the first loadport. If there is no suitable
+    wafer, it will try the second.  Returns an error if the loading process fails or
+    no suitable wafer is found.  To define an alignment angle and still use the
+    "autoselect" behaviour, use -1 for loadport and slot.
+    API Status: published
+    Args:
+        LoadportID:int = -1
+        SlotID:int = -1
+        AlignmentAngle:Decimal = 0
+    Command Timeout: 600000
+    Example:LoadWafer 1 1
+    """
+    MessageServerInterface.sendSciCommand("LoadWafer",LoadportID,SlotID,AlignmentAngle)
+
+
+def UpdateCassetteStatus(Cassette:int=""):
+    """
+    Updates the cassette status with a simple scan.
+    API Status: published
+    Args:
+        Cassette:int = 0
+    Returns:
+        CassetteStatus:str
+    Command Timeout: 1200000
+    Example:UpdateCassetteStatus 1
+    """
+    rsp = MessageServerInterface.sendSciCommand("UpdateCassetteStatus",Cassette)
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def TransportWafer(SourceLocation:str="", SourceSlot:int="", DestinationLocation:str="", DestinationSlot:int=""):
+    """
+    Transport a wafer from one location to another. This command behaves like the
+    wafer-transport inside the LoaderModule. The Slot must always be set.
+    API Status: published
+    Args:
+        SourceLocation:str = "Cassette1"
+        SourceSlot:int = 1
+        DestinationLocation:str = "Cassette1"
+        DestinationSlot:int = 1
+    Command Timeout: 600000
+    Example:TransportWafer Cassette1 1 PreAligner 1
+    """
+    MessageServerInterface.sendSciCommand("TransportWafer",SourceLocation,SourceSlot,DestinationLocation,DestinationSlot)
+
+
+def ProcessWafer(Module:str="", ProcessParam:str=""):
+    """
+    "Process" a wafer on a given location. What is done depends on the current
+    station:  - IDReader: read ID - PreAligner: align wafer (alignment angle
+    mandatory) - Prober: Perform current recipe
+    API Status: published
+    Args:
+        Module:str = "Cassette1"
+        ProcessParam:str = ""
+    Command Timeout: 100000
+    Example:ProcessWafer PreAligner 90.0
+    """
+    MessageServerInterface.sendSciCommand("ProcessWafer",Module,ProcessParam)
+
+
+def GetIDReaderPos():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Returns the current position of the IDReader
+    API Status: internal
+    Returns:
+        IDReaderPos:str
+    Command Timeout: 2000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetIDReaderPos")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def SetIDReaderPos(IDReaderPos:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the current position of the IDReader
+    API Status: internal
+    Args:
+        IDReaderPos:str = "Bottom"
+    Command Timeout: 10000
+    """
+    MessageServerInterface.sendSciCommand("SetIDReaderPos",IDReaderPos)
+
+
+def CryoCommand(Process:str=""):
+    """
+    CryoCommand controls automatic cooling and warm up.
+    API Status: published
+    Args:
+        Process:str = "CD"
+    Command Timeout: 60000
+    Example:CryoCommand CD
+    """
+    MessageServerInterface.sendSciCommand("CryoCommand",Process)
+
+
+def CryoReadTemperature(Stage:str=""):
+    """
+    Reads the current temperature from sensor chuck or shield.
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Returns:
+        Temp:Decimal
+    Command Timeout: 10000
+    Example:CryoReadTemperature C
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadTemperature",Stage)
+    return Decimal(rsp[0])
+
+def CryoSetTemperature(Stage:str="", Temp:Decimal=""):
+    """
+    Sets temperature value for TIC chuck or shield. (Only available in process state
+    'Idle' or 'Cold'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+        Temp:Decimal = 320
+    Command Timeout: 10000
+    Example:CryoSetTemperature C 70.5
+    """
+    MessageServerInterface.sendSciCommand("CryoSetTemperature",Stage,Temp)
+
+
+def CryoStartRefill(Stage:str=""):
+    """
+    Enables refill. (Only available in process state 'Idle'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Command Timeout: 10000
+    Example:CryoStartRefill C
+    """
+    MessageServerInterface.sendSciCommand("CryoStartRefill",Stage)
+
+
+def CryoStopRefill(Stage:str=""):
+    """
+    Disables refill. (Only available in process state 'Idle'.)
+    API Status: published
+    Args:
+        Stage:str = "C"
+    Command Timeout: 10000
+    Example:CryoStopRefill C
+    """
+    MessageServerInterface.sendSciCommand("CryoStopRefill",Stage)
+
+
+def CryoReadState():
+    """
+    Reads current state.
+    API Status: published
+    Returns:
+        State:str
+    Command Timeout: 10000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadState")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def CryoMoveBBPark():
+    """
+    Moves the black body to parking position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveBBPark")
+
+
+def CryoMoveBBWork(NbrPosition:int=""):
+    """
+    Moves the black body to working position.
+    API Status: published
+    Args:
+        NbrPosition:int = 1
+    Command Timeout: 60000
+    Example:CryoMoveBBWork 1
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveBBWork",NbrPosition)
+
+
+def CryoMoveShutter(Position:str="", Shutter:int=""):
+    """
+    Moves one of the two shutters.
+    API Status: published
+    Args:
+        Position:str = "C"
+        Shutter:int = 1
+    Command Timeout: 60000
+    Example:CryoMoveShutter F 1
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveShutter",Position,Shutter)
+
+
+def CryoMoveScopeWork():
+    """
+    Moves the microscope to working position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveScopeWork")
+
+
+def CryoMoveScopePark():
+    """
+    Moves the microscope to parking position.
+    API Status: published
+    Command Timeout: 60000
+    """
+    MessageServerInterface.sendSciCommand("CryoMoveScopePark")
+
+
+def CryoReadPressure():
+    """
+    Reads the current pressure of the vacuum chamber.
+    API Status: published
+    Returns:
+        Pressure:Decimal
+    Command Timeout: 60000
+    """
+    rsp = MessageServerInterface.sendSciCommand("CryoReadPressure")
+    return Decimal(rsp[0])
+
+def MoveZCombined(Height:Decimal="", Percent:Decimal="", Async:int=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Move both Chuck and Scope to a new absolute z-Height. The position must be
+    within 0 and a predefined maximum height (e.g. 3000um). Moves are performed with
+    maximum velocity for now
+    API Status: internal
+    Args:
+        Height:Decimal = 0
+        Percent:Decimal = 0
+        Async:int = 0
+    Command Timeout: 15000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombined",Height,Percent,Async)
+
+
+def GetSoftwareStop():
+    """
+    Get the state of the software stop.
+    API Status: published
+    Returns:
+        StopState:int
+    Command Timeout: 1000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetSoftwareStop")
+    return int(rsp[0])
+
+def MoveZCombinedSetStatus(Status:str="", Message:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Used to set the system either in off, on, error or locked state.  For lock, a
+    key is required. To unlock this key, doe a 'SetStatus' with the same key. So,
+    SetStatus without message means enable/ recover from error, with message it
+    means unlock. If the system wasn't enabled or in error state before an unlock,
+    it will remain in this state after the unlock.
+    API Status: internal
+    Args:
+        Status:str = "Off"
+        Message:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("MoveZCombinedSetStatus",Status,Message)
+
+
+def GetScopeWorkingStage():
+    """
+    Get the currently active ScopeWorkingStage or -1 if unknown. Normally, this
+    should be the same as the currently active ScopeSilo
+    API Status: published
+    Returns:
+        ScopeWorkingStage:int
+    Command Timeout: 5000
+    Example:GetScopeWorkingStage
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetScopeWorkingStage")
+    return int(rsp[0])
+
+def SetPerformanceMode(Mode:str=""):
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Set the performance mode in use by remote command. If this feature is not
+    supported and the mode is anything but Standard, an error is returned.
+    API Status: internal
+    Args:
+        Mode:str = "Standard"
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("SetPerformanceMode",Mode)
+
+
+def SetScopeWorkingStage(ScopeWorkingStage:int=""):
+    """
+    Move to the target working stage
+    API Status: published
+    Args:
+        ScopeWorkingStage:int = -1
+    Command Timeout: 30000
+    Example:SetScopeWorkingStage 1
+    """
+    MessageServerInterface.sendSciCommand("SetScopeWorkingStage",ScopeWorkingStage)
+
+
+def GetPerformanceMode():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the currently configured performance mode. If this feature is not supported
+    on a station, Standard will be returned
+    API Status: internal
+    Returns:
+        Mode:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("GetPerformanceMode")
+    return str("" if len(rsp) < 1 else ' '.join(rsp))
+
+def MoveZCombinedGetStatus():
+    """
+    ***WARNING: internal command. Do not use without explicit instructions from FormFactor***
+    Get the current status of the combined-z-move-system
+    API Status: internal
+    Returns:
+        Status:str
+        PlatenSafe:int
+        Height:Decimal
+        HeightMax:Decimal
+        HeightRelative:Decimal
+        SafeHeight:Decimal
+        Message:str
+    Command Timeout: 5000
+    """
+    rsp = MessageServerInterface.sendSciCommand("MoveZCombinedGetStatus")
+    global MoveZCombinedGetStatus_Response
+    if not "MoveZCombinedGetStatus_Response" in globals(): MoveZCombinedGetStatus_Response = namedtuple("MoveZCombinedGetStatus_Response", "Status,PlatenSafe,Height,HeightMax,HeightRelative,SafeHeight,Message")
+    return MoveZCombinedGetStatus_Response(str(rsp[0]),int(rsp[1]),Decimal(rsp[2]),Decimal(rsp[3]),Decimal(rsp[4]),Decimal(rsp[5]),str("" if len(rsp) < 7 else ' '.join(rsp[6:])))
+
+def LoadScopeFenceConfiguration(Enable:int="", Path:str=""):
+    """
+    Load a previously saved Scope-Fence-configuration or remove the current
+    configuration
+    API Status: published
+    Args:
+        Enable:int = 0
+        Path:str = ""
+    Command Timeout: 5000
+    """
+    MessageServerInterface.sendSciCommand("LoadScopeFenceConfiguration",Enable,Path)
+
+
+def SetSoftwareStop(StopState:int=""):
+    """
+    Set the state of the software stop.
+    API Status: published
+    Args:
+        StopState:int = 0
+    Command Timeout: 1000
+    """
+    MessageServerInterface.sendSciCommand("SetSoftwareStop",StopState)
+
+
+#End of module
diff --git a/src/FlexSensor/Prober/velox_api/velox/vxmessageserver.py b/src/FlexSensor/Prober/velox_api/velox/vxmessageserver.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eb3e3f0872d5edf3bcbafc9b910822342739310
--- /dev/null
+++ b/src/FlexSensor/Prober/velox_api/velox/vxmessageserver.py
@@ -0,0 +1,186 @@
+"""
+Velox Message Server Interface
+To simplify calls from the SCI commands, many of the class methods are
+defined as static.  Some class variables are required to support a
+connection to the Message Server, but the individual SCI commands
+do not maintain a reference to the MessageServer object. Several
+class global variables are used to maintain state.
+Registration with the Message Server is handled in the __init__.
+"""
+import re
+import socket
+import sys
+from collections import namedtuple
+from os.path import basename
+
+REGISTRATION_MESSAGE_TEMPLATE = "FCN=1:RegisterProberApp:{0} {0} 0\n"
+GET_ALL_COMMANDS_MESSAGE = "FCN=1:GetCommands:\n"
+
+class SciException(Exception):
+    """ Contains fields for:
+        code : The Error Number as a string
+        description : The error description
+        __str__, __repr__ : A formatted description of the exception """
+    def __init__(self, cmd, code, description):
+        self.command = cmd
+        self.code = str(code)
+        self.description = description
+
+    def __repr__(self):
+        return 'Error # {0} "{1}"'.format(self.code, self.description)
+
+    def __str__(self):
+        return 'Error # {0} "{1}"'.format(self.code, self.description)
+
+
+class MessageServerInterface(object):
+
+    def __init__(self, ipaddr = 'localhost', targetSocket = 1412):
+        """ Initialize a socket and register with the velox message server.
+            Uses the python script name as the application name to register.
+        """
+        global mySocket, myBytesReceived, myResponse, myCurrentCommand
+
+        try:
+            appName = basename(sys.argv[0])     # get the script name being executed
+            appName = appName.replace(' ', '_') # make sure there are no spaces in the name
+            registrationMessage = REGISTRATION_MESSAGE_TEMPLATE.format(appName)
+
+            myCurrentCommand = 1
+            mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            mySocket.connect((ipaddr, targetSocket))
+
+            #register with message server
+            mySocket.send(registrationMessage.encode())
+            myBytesReceived = 0
+            myResponse = mySocket.recv(200)
+        except ConnectionRefusedError:
+            errormessage = ('Error: The connection to the Velox Message Server was refused.'
+                            ' It probably is not running on IP [' 
+                            + str(ipaddr) + '] on Socket [' + str(targetSocket) + '].'
+                            ' Start Velox or examine IP Address and Socket parameters.')
+
+            raise Exception(errormessage)
+        pass
+
+    def __enter__(self):
+        return self
+        pass
+
+    def __exit__(self, type, value, traceback):
+        """ Close the socket connected to the message server """
+        global mySocket
+        mySocket.close()
+        pass
+
+    def _getcommands(self):
+        ''' Return a list of all commands known to the Velox Message Server '''
+        global mySocket, myBytesReceived, myResponse
+        mySocket.send(GET_ALL_COMMANDS_MESSAGE.encode())
+        myBytesReceived = 0
+        myResponse = mySocket.recv(60000)
+        message = str(myResponse.decode('utf-8'))
+        # parse the list
+        commands = message.split(':')[2].split(';')
+
+        # split the list into parsed tuples
+        SimpleCommandTuple = namedtuple('SimpleCommandTuple', 'section, name, number, timeout')
+        scilist = []
+        for x in commands:
+            parts = x.split(' ')
+            scilist.append(SimpleCommandTuple(parts[0], parts[1], int(parts[2]),int(parts[3])))
+        return scilist
+        pass
+
+    @staticmethod
+    def __parseReturnValues(valueString):
+        """ The values come back from the SCI command as a string separated by spaces,
+            but with embedded strings as well.  Separate the values. """
+
+        results = []   # the values parsed to be returned
+        remainingValues = valueString   # holds all values still to be parsed
+        while remainingValues:
+            if remainingValues.startswith('"'):     # we have a string
+                parts = remainingValues.split('"', 2)
+                parts.pop(0)
+                results.append(parts.pop(0).strip())    # get the string
+                parts.pop(0)
+            else:   # get value separated by a space
+                parts = remainingValues.split(' ', 1)
+                results.append(parts.pop(0))
+
+            if len(parts) > 0:
+                remainingValues = parts[0].strip()  # get the rest of the values
+            else:
+                remainingValues = None
+
+        return results
+        pass
+
+    @staticmethod
+    def __convertReturnValues(responses):
+        """ The responses are all strings.  Use the hints from the SCI Command definition
+            to convert them to the proper types """
+        pass
+
+    @staticmethod
+    def __parseSciCommandResponse(response):
+        """ The response from Message Server has the form
+            Rsp=<ID>:<Return Code>:<Return Value>
+            Split the response on the : character, then split up the return values """
+
+        message = str(response.decode('utf-8')[:-2])
+
+        # we may have 0 or more values
+        partsCount = message.count(':')+1
+        if partsCount == 2:
+            command, code = re.split(":", message)
+            values = '';
+        else:
+            command, code, values = re.split(":", message)
+            values = values.strip()
+
+        if message.startswith('Rsp='):
+            values = MessageServerInterface.__parseReturnValues(values)
+
+        commandNumber = command.split('=')[1]
+        return int(commandNumber), int(code), values
+
+    @staticmethod
+    def __sendSynchronousCommand(commandName, message=''):
+        global mySocket, myBytesReceived, myResponse, myCurrentCommand
+        
+        try:
+            myCurrentCommand += 1       # increment the commend number
+            if myCurrentCommand == 0 or myCurrentCommand > 999:
+                myCurrentCommand = 1
+            messageToSend = 'Cmd={}:{}:{}\n'.format(myCurrentCommand,commandName,message)
+            mySocket.send(messageToSend.encode())
+            myBytesReceived = 0
+            myResponse = mySocket.recv(500)
+
+        except Exception as e:
+            raise Exception('Unable to communicate with Velox Message Server. Start Velox. %s', e)
+
+        cmd, code, values = MessageServerInterface.__parseSciCommandResponse(myResponse)
+
+        # if the response code is not 0, raise an exception
+        if code:
+            parameters = ' '.join(values)
+            raise SciException(cmd, code, parameters)
+
+        return values
+        pass
+
+    @staticmethod
+    def sendSciCommand(commandName, *args, **kwargs):
+        """ If the parameter rparams is passed, it is the full command parameter string and should be used.
+            Otherwise, join the other arguments into a string separated by spaces and send that.
+            The rparams is used for legacy scripts converted from Pascal or Basic or other cases 
+            where you want to send the command parameters as a single string.  """
+
+        if 'rparams' in kwargs: # use the raw parameter string if provided
+            commandParameters = kwargs['rparams']
+        else: # use the positional arguments and build the parameter string
+            commandParameters = ' '.join(str(x) for x in args)
+        return MessageServerInterface.__sendSynchronousCommand(commandName, commandParameters)
diff --git a/src/FlexSensor/Prober/view/ProberControlWindow.py b/src/FlexSensor/Prober/view/ProberControlWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..2bb990de5bd0b25cafff5f0994a6e6196b01218d
--- /dev/null
+++ b/src/FlexSensor/Prober/view/ProberControlWindow.py
@@ -0,0 +1,66 @@
+import logging
+import sys
+
+from PySide6.QtGui import QWindow
+from PySide6.QtWidgets import QGridLayout, QApplication, QMainWindow, QWidget, QGroupBox, QVBoxLayout
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from Prober.controller.MapFileParser import MapFileParser
+from Prober.controller.ProberController import ProberController
+from Prober.model.ProberModel import ProberModel
+from Prober.view.widgets.DieGridWidget import DieGridWidget
+from Prober.view.widgets.ProberPositionWidget import ProberPositionWidget
+from Prober.view.widgets.ProberStatusWidget import ProberStatusWidget
+from generics.logger import setup_logging
+
+
+class ProberControlWindow(QMainWindow):
+
+    def __init__(self, model: ProberModel, controller: ProberController):
+        super().__init__()
+        self.controller = controller
+        self.model = model
+
+        #self.parsed_map = MapFileParser(self.controller.wafer_map)
+
+        # Add a GridLayout to the main window
+        self._widget = QWidget()
+        self._grid_layout = QGridLayout()
+        # Add the DieGridWidget to the main window
+        # Add the prober status widget to the a group box
+        groupbox_status_widget = QGroupBox("Prober Status")
+        groupbox_status_widget_layout = QVBoxLayout()
+        groupbox_status_widget_layout.addWidget(ProberStatusWidget(self.model))
+        groupbox_status_widget.setLayout(groupbox_status_widget_layout)
+
+
+        groupbox_position_widget = QGroupBox("Prober Status")
+        groupbox_position_widget_layout = QVBoxLayout()
+        groupbox_position_widget_layout.addWidget(ProberPositionWidget(self.model))
+        groupbox_position_widget.setLayout(groupbox_position_widget_layout)
+
+        self._grid_layout.addWidget(groupbox_status_widget, 0, 0, 1, 1)
+        self._grid_layout.addWidget(groupbox_position_widget, 1, 0, 1, 1)
+        self._grid_layout.addWidget(DieGridWidget(self.model), 0, 1, 2, 1)
+        # set the layout of the main window
+        self._widget.setLayout(self._grid_layout)
+        self.setCentralWidget(self._widget)
+
+
+
+
+if __name__ == "__main__":
+    setup_logging()
+    logging.warning("ProberControlWindow.py is not meant to be run as a script.")
+
+    app = QApplication()
+
+    vaut_config = VAutomatorConfig.load_config("../configs/init_config.yaml")
+
+    prober_model = ProberModel()
+    prober_controller = ProberController(prober_model, vaut_config)
+    main_window = ProberControlWindow(prober_controller, prober_model)
+    # test_win = StructureSelector()
+
+    main_window.show()
+    sys.exit(app.exec())
diff --git a/src/FlexSensor/Prober/view/__init__.py b/src/FlexSensor/Prober/view/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/Prober/view/widgets/DieGridWidget.py b/src/FlexSensor/Prober/view/widgets/DieGridWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..b1e365e4dbebf20a048955440605885261ef55c4
--- /dev/null
+++ b/src/FlexSensor/Prober/view/widgets/DieGridWidget.py
@@ -0,0 +1,225 @@
+import pandas as pd
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QColor, QPainter, QPen
+from PySide6.QtWidgets import QWidget, QGridLayout, QPushButton, QApplication, QLabel
+
+from Prober.controller.MapFileParser import MapFileParser
+from Prober.model.ProberModel import ProberModel
+
+
+class FlatButton(QPushButton):
+    def __init__(self, text, top_left="", top_right="", bottom_left="", bottom_right="", parent=None):
+        super().__init__(parent, text)
+
+        # Set flat appearance
+
+        self.setFlat(True)
+
+        self.color_default = QColor(192, 192, 192)#QColor(0, 58, 98) #
+        self.color_die_selected = QColor(49, 61, 102)
+        self.color_probe_active = QColor(62, 120, 52)
+        self.color_disabled = QColor(0, 0, 0)
+        self.border_color = self.color_default
+
+        self.setStyleSheet(self.get_stylesheet(self.color_default))
+
+        # Set quadratic aspect ratio
+        self.setMaximumSize(50, 50)
+        self.setMinimumSize(50, 50)
+        self.setFixedSize(50, 50)
+
+        self.setContentsMargins(0, 0, 0, 0)  # Set margins to zero
+        # Create label widgets
+        #self.top_left_label = QLabel(top_left, parent=self)
+        self.top_right_label = QLabel(top_right, parent=self)
+        self.bottom_left_label = QLabel(bottom_left, parent=self)
+        self.bottom_right_label = QLabel(bottom_right, parent=self)
+
+        # Set label positions
+        #self.top_left_label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
+        self.top_right_label.setAlignment(Qt.AlignTop | Qt.AlignRight)
+        self.bottom_left_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft)
+        self.bottom_right_label.setAlignment(Qt.AlignBottom | Qt.AlignRight)
+
+        # Border colo
+
+
+        # Border flag
+        self.draw_border = False
+        # Border width
+        self.border_width = 3
+
+    def get_stylesheet(self, qcolor):
+        return f"background-color: rgb({qcolor.red()}, {qcolor.green()}, {qcolor.blue()});"
+    def setTopLeftLabel(self, text):
+        self.top_left_label.setText(text)
+
+    def setTopRightLabel(self, text):
+        self.top_right_label.setText(text)
+
+    def setBottomLeftLabel(self, text):
+        self.bottom_left_label.setText(text)
+
+    def setBottomRightLabel(self, text):
+        self.bottom_right_label.setText(text)
+
+    def setEnabled(self, arg__1: bool) -> None:
+        super().setEnabled(arg__1)
+        if not arg__1:
+            self.setStyleSheet(self.get_stylesheet(self.color_disabled))
+            self.border_color = self.color_disabled # Black
+            self.update()
+
+    def set_die_selected(self, checked: bool) -> None:
+        if not self.isEnabled():
+            return
+
+        if checked:
+            self.setStyleSheet(self.get_stylesheet(self.color_die_selected))
+            self.border_color = self.color_die_selected
+        else:
+            self.setStyleSheet(self.get_stylesheet(self.color_default))
+            self.border_color = self.color_default
+        self.update()
+
+    def set_probe_active(self, active: bool) -> None:
+        if not self.isEnabled():
+            return
+
+        if active:
+            #self.setStyleSheet(self.get_stylesheet(self.color_default))
+            self.border_color = self.color_probe_active
+        else:
+            #self.setStyleSheet(self.get_stylesheet(self.color_default))
+            self.border_color = self.color_default
+        self.update()
+
+    def paintEvent(self, event):
+        super().paintEvent(event)
+
+        #if self.draw_border:
+        painter = QPainter(self)
+        pen = QPen(self.border_color, self.border_width)
+        painter.setPen(pen)
+        painter.setBrush(Qt.NoBrush)
+        painter.drawRect(
+            self.border_width // 2,
+            self.border_width // 2,
+            self.width() - self.border_width,
+            self.height() - self.border_width
+        )
+
+    def resizeEvent(self, event):
+        super().resizeEvent(event)
+
+        # Calculate label sizes based on button size
+        button_size = self.size()
+        border_offset = self.border_width // 2
+        label_width = (button_size.width() - self.border_width)
+        label_height = (button_size.height()) // 2
+
+        # Set label sizes and positions
+
+
+        self.top_right_label.setGeometry(self.border_width, self.border_width,
+                                         label_width-self.border_width, label_height)
+
+        self.bottom_left_label.setGeometry(self.border_width, label_height - self.border_width,
+                                           label_width//2, label_height)
+
+        self.bottom_right_label.setGeometry(label_width//2,  label_height - self.border_width,
+                                            label_width//2+1, label_height)
+
+
+
+class DieGridWidget(QWidget):
+    def __init__(self, model: ProberModel):
+        super(DieGridWidget, self).__init__()
+        self._model = model
+
+        parsed_map = MapFileParser(str(self._model.wafer_map))
+        self.setWindowTitle("Die Grid Widget")
+        self._dies = {}
+
+        self.grid_layout = QGridLayout()
+        self.grid_layout.setSpacing(0)
+        self.grid_layout.setHorizontalSpacing(0)
+        self.grid_layout.setVerticalSpacing(0)
+        #self.grid_layout.setContentsMargins(0, 0, 0, 0)  # Set margins to zero
+
+        self.setLayout(self.grid_layout)
+
+        self._die = parsed_map.result['Die']
+
+        self._prof_dies = parsed_map.result['ProfDies']
+        self.create_die_grid()
+        self.setFixedSize(9*60, 9*60)
+
+
+        self._model.signals.die_changed.connect(self.update_die_grid)
+
+        self.update_die_grid(self._model.die)
+
+    def create_die_grid(self):
+        table = pd.DataFrame([[int(die), *self._die[die].split(",")] for die in self._die],
+                             columns=['die_number', 'col', 'row', 'status'])
+        table['col'] = table['col'].astype(int)
+        table['row'] = table['row'].astype(int)
+        table['status'] = table['status'].astype(str)
+
+        table['col_os'] = table.apply([lambda row: row['col'] - table['col'].min()], axis=1)
+        table['row_os'] = table.apply([lambda row: row['row'] - table['row'].min()], axis=1)
+        
+
+        #print(table)
+        # pd.DataFrame([die.split(",").strip for die in die_info], columns=['col', 'row', 'status'])
+        for entry in self._prof_dies:
+            col, row, value = self._prof_dies[entry].split(",")
+            df = table.loc[(table['col'] == int(col)) & (table['row'] == int(row))]
+            if df.empty:
+                continue
+            else:
+                table.loc[(table['col'] == int(col)) & (table['row'] == int(row)), 'prof_die_number'] = entry
+        
+
+        for index, die in table.iterrows():
+            button = FlatButton("1", "2", f"{die['col']}, {die['row']}",  str(die['die_number']), str(die['status']))#,
+            if die['status'] == "X":
+                button.setEnabled(False)
+            elif die['status'] == "V":
+                    button.set_die_selected(False)
+            elif die['status'] == "P":
+                button.set_die_selected(True)
+                #button.setText(f"{die['col']}, {die['row']} - {die['die_number']}")
+            self._dies[f"{die['row']}, {die['col']}"] = button
+
+            button.clicked.connect(self.on_button_clicked)
+
+            self.grid_layout.addWidget(button, die['col_os'], die['row_os'])
+
+        #print(table)
+
+    def on_button_clicked(self):
+        button: FlatButton = self.sender()
+        button.set_probe_active(True)
+
+    def update_die_grid(self, die):
+        for die in self._dies:
+            self._dies[die].set_probe_active(False)
+
+        die_x = self._model.die_row
+        die_y = self._model.die_col
+        print(f"Die {die}: {die_x}, {die_y} was probed")
+        #print(self._dies)
+        self._dies[f"{die_x}, {die_y}"].set_probe_active(True)
+        
+
+if __name__ == "__main__":
+    app = QApplication([])
+
+    parsed_map = MapFileParser("../Wafermapary1_48dies.map")
+
+    widget = DieGridWidget(parsed_map)
+    widget.show()
+
+    app.exec_()
\ No newline at end of file
diff --git a/src/FlexSensor/Prober/view/widgets/ProberPositionWidget.py b/src/FlexSensor/Prober/view/widgets/ProberPositionWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..9db1dfde64d455f62e7574d9407525a5099f26e9
--- /dev/null
+++ b/src/FlexSensor/Prober/view/widgets/ProberPositionWidget.py
@@ -0,0 +1,105 @@
+from PySide6.QtWidgets import QWidget, QGroupBox, QGridLayout, QLabel, QProgressBar
+
+from Prober.model.ProberModel import ProberModel
+
+
+class ProberPositionWidget(QWidget):
+
+    def __init__(self, model: ProberModel, chuck_position="Vertical"):
+        super().__init__()
+        self.model = model
+        self.layout = QGridLayout()
+        self.chuck_position = chuck_position
+
+        self.lbl_chuck_x = QLabel()
+        self.lbl_chuck_y = QLabel()
+        self.lbl_chuck_z = QLabel()
+
+        self.lbl_die_no = QLabel()
+        self.lbl_structure = QLabel()
+        self.lbl_die_col = QLabel()
+        self.lbl_die_row = QLabel()
+
+        self.lbl_die_no.setText(str(self.model.die))
+        self.lbl_structure.setText("<b>Stopped</b>")
+        self.lbl_die_col.setText(str(self.model.die_col))
+        self.lbl_die_row.setText(str(self.model.die_row))
+        self.lbl_chuck_x.setText(str(self.model.chuck_x))
+        self.lbl_chuck_y.setText(str(self.model.chuck_y))
+        self.lbl_chuck_z.setText(str(self.model.chuck_z))
+
+        # self.progress = QProgressBar(self)
+        # self.progress.setStyleSheet(
+        #     "#GreenProgressBar { min-height: 12px; max-height: 12px; border-radius: 6px;}")
+        # self.layout.addWidget(self.progress, 2, 0, 1, 4)
+        # self.progress.setFixedHeight(self.progress.sizeHint().height() / 2)
+
+        self._init_ui_wafer_position()
+        self._init_ui_chuck_position()
+        self.setLayout(self.layout)
+
+        self.model.signals.chuck_x_changed.connect(self._on_chuck_x_changed)
+        self.model.signals.chuck_y_changed.connect(self._on_chuck_y_changed)
+        self.model.signals.chuck_z_changed.connect(self._on_chuck_z_changed)
+        self.model.signals.die_changed.connect(self._on_die_no_changed)
+        #self.model.signals.st.connect(self._on_structure_changed)
+        self.model.signals.curr_die_col_changed.connect(self._on_die_col_changed)
+        self.model.signals.curr_die_row_changed.connect(self._on_die_row_changed)
+
+
+    def _init_ui_wafer_position(self):
+        self.layout.addWidget(QLabel("Die No:"), 0, 0)
+        self.layout.addWidget(self.lbl_die_no, 0, 1)
+
+        self.layout.addWidget(QLabel("Structure"), 0, 2)
+        self.layout.addWidget(self.lbl_structure, 0, 3)
+
+        self.layout.addWidget(QLabel("Die col:"), 1, 0)
+        self.layout.addWidget(self.lbl_die_col, 1, 1)
+
+        self.layout.addWidget(QLabel("Die row:"), 1, 2)
+        self.layout.addWidget(self.lbl_die_row, 1, 3)
+
+    def _init_ui_chuck_position(self):
+        if self.chuck_position == "Vertical":
+            self.layout.addWidget(QLabel("X"), 2, 0)
+            self.layout.addWidget(self.lbl_chuck_x, 2, 1)
+
+            self.layout.addWidget(QLabel("Y"), 3, 0)
+            self.layout.addWidget(self.lbl_chuck_y, 3, 1)
+
+            self.layout.addWidget(QLabel("Z"), 4, 0)
+            self.layout.addWidget(self.lbl_chuck_z, 4, 1)
+
+        elif self.chuck_position == "Horizontal":
+            self.layout.addWidget(QLabel("X"), 2, 0)
+            self.layout.addWidget(self.lbl_chuck_x, 2, 1)
+
+            self.layout.addWidget(QLabel("Y"), 2, 2)
+            self.layout.addWidget(self.lbl_chuck_y, 2, 3)
+
+            self.layout.addWidget(QLabel("Z"), 2, 4)
+            self.layout.addWidget(self.lbl_chuck_z, 2, 5)
+
+
+    def _on_chuck_x_changed(self, value: int):
+        self.lbl_chuck_x.setText(str(value))
+
+    def _on_chuck_y_changed(self, value: int):
+        self.lbl_chuck_y.setText(str(value))
+
+    def _on_chuck_z_changed(self, value: int):
+        self.lbl_chuck_z.setText(str(value))
+
+    def _on_die_no_changed(self, value: int):
+        self.lbl_die_no.setText(str(value))
+
+    def _on_structure_changed(self, value: int):
+        self.lbl_structure.setText(str(value))
+
+    def _on_die_col_changed(self, value: int):
+        self.lbl_die_col.setText(str(value))
+
+    def _on_die_row_changed(self, value: int):
+        self.lbl_die_row.setText(str(value))
+
diff --git a/src/FlexSensor/Prober/view/widgets/ProberStatusWidget.py b/src/FlexSensor/Prober/view/widgets/ProberStatusWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..00e2073375bd698281f6887da38514385df74376
--- /dev/null
+++ b/src/FlexSensor/Prober/view/widgets/ProberStatusWidget.py
@@ -0,0 +1,74 @@
+from PySide6.QtCore import Qt
+from PySide6.QtGui import QIcon
+from PySide6.QtWidgets import QWidget, QLabel, QGridLayout, QStyle, QFrame, QProgressBar, QGroupBox
+
+from Prober.model.ProberModel import ProberModel
+
+
+class ProberStatusWidget(QWidget):
+
+    def __init__(self, model: ProberModel):
+        super().__init__()
+        self.setFixedSize(300, 200)
+        self.model = model
+        self._grid_layout = QGridLayout()
+        self.prober_status = self._add_status(self._get_std_icon("SP_ComputerIcon"), "", 0)
+        self.version_status = self._add_status(self._get_std_icon("SP_MessageBoxInformation"), str(self.model.version), 1)
+        self._add_line(2)
+        self.errors = self._add_status(self._get_std_icon("SP_MessageBoxCritical"), "0", 3)
+        self.warnings = self._add_status(self._get_std_icon("SP_MessageBoxWarning"), "0", 4)
+
+        self._on_connected_changed(self.model.connected)
+
+        self.model.signals.connected_changed.connect(self._on_connected_changed)
+        self.model.signals.version_changed.connect(self._on_version_changed)
+        self.model.signals.errors_changed.connect(self._on_errors_changed)
+        self.model.signals.warnings_changed.connect(self._on_warnings_changed)
+
+
+        self.setLayout(self._grid_layout)
+
+
+    def _get_std_icon(self, icon_name) -> QIcon:
+        return self.style().standardIcon(getattr(QStyle, icon_name))
+
+    def _add_status(self, icon, text, pos=0):
+        icon_label = QLabel()
+        icon_label.setPixmap(icon.pixmap(50, 50))
+        icon_label.setAlignment(Qt.AlignCenter)
+        icon_label.setContentsMargins(0, 0, 0, 0)
+        # icon_label.setStyleSheet("background-color: rgb(192, 192, 192);")
+        icon_label.setFixedSize(24, 24)
+        icon_label.setScaledContents(True)
+
+        text_label = QLabel(text)
+        #text_label.setAlignment(Qt.AlignCenter)
+        #text_label.setContentsMargins(0, 0, 0, 0)
+        # text_label.setStyleSheet("background-color: rgb(192, 192, 192);")
+        # text_label.setFixedSize(32, 50)
+        #text_label.setScaledContents(True)
+
+        self._grid_layout.addWidget(icon_label, pos, 0)
+        self._grid_layout.addWidget(text_label, pos, 1)
+        return text_label
+
+    def _add_line(self, pos=0):
+        line = QFrame()
+        line.setFrameShape(QFrame.HLine)
+        line.setFrameShadow(QFrame.Sunken)
+        self._grid_layout.addWidget(line, pos, 0, 1, 2)
+
+    def _on_connected_changed(self, connected):
+        if connected:
+            self.prober_status.setText("Connected")
+        else:
+            self.prober_status.setText("Disconnected")
+
+    def _on_version_changed(self, version):
+        self.version_status.setText(version)
+
+    def _on_errors_changed(self, errors):
+        self.errors.setText(str(len(errors)))
+
+    def _on_warnings_changed(self, warnings):
+        self.warnings.setText(str(len(warnings)))
\ No newline at end of file
diff --git a/src/FlexSensor/__init__.py b/src/FlexSensor/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..81dab0e1c8728d9d20fda311be5ccfd69e7324e7
--- /dev/null
+++ b/src/FlexSensor/__init__.py
@@ -0,0 +1,7 @@
+import os
+import pathlib
+import sys
+
+from flexsensorpy.__version__ import __version__
+
+__all__ = []
diff --git a/src/FlexSensor/__version__.py b/src/FlexSensor/__version__.py
new file mode 100644
index 0000000000000000000000000000000000000000..36b6d4f16487f4a4b4b68a1913dedc60d22080d3
--- /dev/null
+++ b/src/FlexSensor/__version__.py
@@ -0,0 +1,2 @@
+__version__ = "6.0.0 beta"
+__changelog__ = "New UI Version and better measurement routine implemented."
\ No newline at end of file
diff --git a/src/FlexSensor/constants/Enumerate.py b/src/FlexSensor/constants/Enumerate.py
new file mode 100644
index 0000000000000000000000000000000000000000..08721dce289f2ba27e2647add2dd9e3294e5ba57
--- /dev/null
+++ b/src/FlexSensor/constants/Enumerate.py
@@ -0,0 +1,119 @@
+"""
+   DWF Python Example
+   Author:  Digilent, Inc.
+   Revision:  2019-07-24
+
+   Requires:                       
+       Python 2.7, 3
+   Description:
+   Device detection troubleshooting.
+"""
+
+from ctypes import *
+import sys
+import time
+
+if sys.platform.startswith("win"):
+    dwf = cdll.dwf
+    dmgr = cdll.dmgr
+    ftd = windll.ftd2xx
+elif sys.platform.startswith("darwin"):
+    dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
+    dmgr = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/Frameworks/libdmgr.dylib")
+    ftd = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/Frameworks/libftd2xx.dylib")
+    dftd = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/Frameworks/libdftd2xx.dylib")
+else:
+    dwf = cdll.LoadLibrary("libdwf.so")
+    dmgr = cdll.LoadLibrary("libdmgr.so")
+    ftd = cdll.LoadLibrary("libftd2xx.so")
+
+version = create_string_buffer(32)
+cDev = c_int();
+dvc = (c_char*1024)()
+pdid = c_int()
+flags = c_int()
+locid = c_int()
+type = c_int()
+
+name = create_string_buffer(64)
+sn = create_string_buffer(64)
+
+if sys.platform.startswith("darwin"):
+    print("")
+    if dftd.DFT_Init() == 0 :
+        print("DFT_INIT failed")
+        quit()
+
+    print("Digilent FTDI Enumeration library loaded")
+    
+    if dftd.DFT_CreateDeviceInfoList(byref(cDev)) != 0 :
+        print("DFT_CreateDeviceInfoList failed")
+        dftd.DFT_Term()
+        quit()
+
+    print("Devices: "+str(cDev.value))
+
+    for i in range(0, cDev.value):
+        if dftd.DFT_GetDeviceInfoDetail(c_int(i), byref(flags), byref(type), byref(pdid), byref(locid), sn, name, None) != 0 :
+            print("Failed DFT_GetDeviceInfoDetail")
+            dftd.DFT_Term()
+            quit()
+        print(" "+str(i+1)+". SN:"+str(sn.value)+" '"+str(name.value)+"'"+" flags: "+hex(flags.value)+" type: "+hex(type.value)+" id: "+hex(pdid.value)+" locid: "+hex(locid.value))
+
+
+print("")
+ftd.FT_GetLibraryVersion(byref(pdid))
+print("FTDI Version: "+hex(pdid.value))
+
+if ftd.FT_CreateDeviceInfoList(byref(cDev)) != 0 :
+    print("FT_CreateDeviceInfoList failed")
+    quit()
+
+print("Devices: "+str(cDev.value))
+
+for i in range(cDev.value):
+    if ftd.FT_GetDeviceInfoDetail(c_int(i), byref(flags), byref(type), byref(pdid), byref(locid), sn, name, None) != 0 :
+        print("Failed FT_GetDeviceInfoDetail")
+    print(" "+str(i+1)+". SN:"+str(sn.value)+" "+str(name.value)+""+" flags: "+hex(flags.value)+" type: "+hex(type.value)+" id: "+hex(pdid.value)+" locid: "+hex(locid.value))
+
+
+print("")
+dmgr.DmgrGetVersion(version)
+print("DMGR Version: "+str(version.value))
+
+if dmgr.DmgrEnumDevices(byref(cDev)) == 0 :
+    print("DmgrEnumDevices failed")
+    quit()
+
+print("Devices: "+str(cDev.value))
+
+for i in range(cDev.value):
+    dmgr.DmgrGetDvc(c_int(i), dvc);
+
+    if dmgr.DmgrGetInfo(dvc, 3, name) == 0 : #dinfoProdName
+        print("Failed DmgrGetInfo dinfoProdName")
+    if dmgr.DmgrGetInfo(dvc, 4, byref(pdid)) == 0 : #dinfoPDID
+        print("Failed DmgrGetInfo dinfoPDID")
+    if dmgr.DmgrGetInfo(dvc, 5, sn) == 0 : #dinfoSN
+        print("Failed DmgrGetInfo dinfoSN")
+    print(" "+str(i+1)+". "+str(sn.value)+" "+str(name.value)+""+" PDID: "+hex(pdid.value))
+
+
+print("")
+dwf.FDwfGetVersion(version)
+print("DWF Version: "+str(version.value))
+
+if dwf.FDwfEnum(c_int(0), byref(cDev)) == 0 :
+    print("DmgrEnumDevices failed")
+    quit()
+
+print("Devices: "+str(cDev.value))
+
+for i in range(cDev.value):
+    dwf.FDwfEnumDeviceName(c_int(i), name)
+    dwf.FDwfEnumSN(c_int(i), sn)
+    print(" "+str(i+1)+". "+str(sn.value)+" "+str(name.value)+"")
+
+dmgr.DmgrFreeDvcEnum()
+if sys.platform.startswith("darwin"):
+    dftd.DFT_Term()
\ No newline at end of file
diff --git a/src/FlexSensor/constants/FlexsensorConstants.py b/src/FlexSensor/constants/FlexsensorConstants.py
new file mode 100644
index 0000000000000000000000000000000000000000..37913cb0695cc5479cd7e98967eb5386e46743e0
--- /dev/null
+++ b/src/FlexSensor/constants/FlexsensorConstants.py
@@ -0,0 +1,3 @@
+class Probe:
+    INPUT = 0
+    OUTPUT = 1
diff --git a/src/FlexSensor/constants/__init__.py b/src/FlexSensor/constants/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/constants/css_stylesheet.py b/src/FlexSensor/constants/css_stylesheet.py
new file mode 100644
index 0000000000000000000000000000000000000000..75924a64c8211e5cfb5d822bb65471ca8092c0ae
--- /dev/null
+++ b/src/FlexSensor/constants/css_stylesheet.py
@@ -0,0 +1,44 @@
+styleData="""
+QWidget
+{
+    color: #b1b1b1;
+    background-color: #323232;
+}
+QWidget:disabled
+{
+    border-color: #404040;
+    background-color: #323232;
+}
+QProgressBar
+{
+    border: 2px solid grey;
+    border-radius: 5px;
+    text-align: center;
+}
+QProgressBar::chunk
+{
+    background-color: #d7801a;
+    width: 2.15px;
+    margin: 0.5px;
+}
+QPushButton:pressed
+{
+    background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
+}
+QComboBox:hover,QPushButton:hover
+{
+    border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+QPushButton
+{
+    color: #b1b1b1;
+    background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
+    border-width: 1px;
+    border-color: #1e1e1e;
+    border-style: solid;
+    border-radius: 6;
+    padding: 3px;
+    font-size: 12px;
+    padding-left: 5px;
+    padding-right: 5px;
+}"""
\ No newline at end of file
diff --git a/src/FlexSensor/constants/dwfconstants.py b/src/FlexSensor/constants/dwfconstants.py
new file mode 100644
index 0000000000000000000000000000000000000000..b7b445e1a4ae7056f6a09354164915c5def3572b
--- /dev/null
+++ b/src/FlexSensor/constants/dwfconstants.py
@@ -0,0 +1,252 @@
+"""
+   DWFConstants (definitions file for DWF library)
+   Author:  Digilent, Inc.
+   Revision:  2019-10-15
+
+   Must install:                       
+       Python 2.7 or 3
+"""
+
+
+from ctypes import *
+
+# device handle
+#HDWF
+hdwfNone = c_int(0)
+
+# device enumeration filters
+enumfilterAll        = c_int(0)
+
+enumfilterType     = c_int(0x8000000)
+enumfilterUSB      = c_int(0x0000001)
+enumfilterNetwork  = c_int(0x0000002)
+enumfilterAXI      = c_int(0x0000004)
+enumfilterRemote   = c_int(0x1000000)
+enumfilterAudio    = c_int(0x2000000)
+enumfilterDemo     = c_int(0x4000000)
+
+# device ID
+devidEExplorer   = c_int(1)
+devidDiscovery   = c_int(2)
+devidDiscovery2  = c_int(3)
+devidDDiscovery  = c_int(4)
+devidADP3X50     = c_int(6)
+
+# device version
+devverEExplorerC   = c_int(2)
+devverEExplorerE   = c_int(4)
+devverEExplorerF   = c_int(5)
+devverDiscoveryA   = c_int(1)
+devverDiscoveryB   = c_int(2)
+devverDiscoveryC   = c_int(3)
+
+# trigger source
+trigsrcNone                 = c_ubyte(0)
+trigsrcPC                   = c_ubyte(1)
+trigsrcDetectorAnalogIn     = c_ubyte(2)
+trigsrcDetectorDigitalIn    = c_ubyte(3)
+trigsrcAnalogIn             = c_ubyte(4)
+trigsrcDigitalIn            = c_ubyte(5)
+trigsrcDigitalOut           = c_ubyte(6)
+trigsrcAnalogOut1           = c_ubyte(7)
+trigsrcAnalogOut2           = c_ubyte(8)
+trigsrcAnalogOut3           = c_ubyte(9)
+trigsrcAnalogOut4           = c_ubyte(10)
+trigsrcExternal1            = c_ubyte(11)
+trigsrcExternal2            = c_ubyte(12)
+trigsrcExternal3            = c_ubyte(13)
+trigsrcExternal4            = c_ubyte(14)
+trigsrcHigh                 = c_ubyte(15)
+trigsrcLow                  = c_ubyte(16)
+trigsrcClock                = c_ubyte(17)
+
+# instrument states
+DwfStateReady        = c_ubyte(0)
+DwfStateConfig       = c_ubyte(4)
+DwfStatePrefill      = c_ubyte(5)
+DwfStateArmed        = c_ubyte(1)
+DwfStateWait         = c_ubyte(7)
+DwfStateTriggered    = c_ubyte(3)
+DwfStateRunning      = c_ubyte(3)
+DwfStateDone         = c_ubyte(2)
+
+# DwfEnumConfigInfo
+DECIAnalogInChannelCount = c_int(1)
+DECIAnalogOutChannelCount = c_int(2)
+DECIAnalogIOChannelCount = c_int(3)
+DECIDigitalInChannelCount = c_int(4)
+DECIDigitalOutChannelCount = c_int(5)
+DECIDigitalIOChannelCount = c_int(6)
+DECIAnalogInBufferSize = c_int(7)
+DECIAnalogOutBufferSize = c_int(8)
+DECIDigitalInBufferSize = c_int(9)
+DECIDigitalOutBufferSize = c_int(10)
+
+# acquisition modes:
+acqmodeSingle       = c_int(0)
+acqmodeScanShift    = c_int(1)
+acqmodeScanScreen   = c_int(2)
+acqmodeRecord       = c_int(3)
+acqmodeOvers        = c_int(4)
+acqmodeSingle1      = c_int(5)
+
+# analog acquisition filter:
+filterDecimate = c_int(0)
+filterAverage  = c_int(1)
+filterMinMax   = c_int(2)
+
+# analog in trigger mode:
+trigtypeEdge         = c_int(0)
+trigtypePulse        = c_int(1)
+trigtypeTransition   = c_int(2)
+trigtypeWindow       = c_int(3)
+
+# trigger slope:
+DwfTriggerSlopeRise   = c_int(0)
+DwfTriggerSlopeFall   = c_int(1)
+DwfTriggerSlopeEither = c_int(2)
+
+# trigger length condition
+triglenLess       = c_int(0)
+triglenTimeout    = c_int(1)
+triglenMore       = c_int(2)
+
+# error codes for the functions:                         
+dwfercNoErc                  = c_int(0)		#  No error occurred
+dwfercUnknownError           = c_int(1)		#  API waiting on pending API timed out
+dwfercApiLockTimeout         = c_int(2)		#  API waiting on pending API timed out
+dwfercAlreadyOpened          = c_int(3)		#  Device already opened
+dwfercNotSupported           = c_int(4)		#  Device not supported
+dwfercInvalidParameter0      = c_int(16)	#  Invalid parameter sent in API call
+dwfercInvalidParameter1      = c_int(17)	#  Invalid parameter sent in API call
+dwfercInvalidParameter2      = c_int(18)	#  Invalid parameter sent in API call
+dwfercInvalidParameter3      = c_int(19)	#  Invalid parameter sent in API call
+dwfercInvalidParameter4      = c_int(20)	#  Invalid parameter sent in API call
+
+# analog out signal types
+funcDC       = c_ubyte(0)
+funcSine     = c_ubyte(1)
+funcSquare   = c_ubyte(2)
+funcTriangle = c_ubyte(3)
+funcRampUp   = c_ubyte(4)
+funcRampDown = c_ubyte(5)
+funcNoise    = c_ubyte(6)
+funcPulse    = c_ubyte(7)
+funcTrapezium= c_ubyte(8)
+funcSinePower= c_ubyte(9)
+funcCustom   = c_ubyte(30)
+funcPlay     = c_ubyte(31)
+
+# analog io channel node types
+analogioEnable      = c_ubyte(1)
+analogioVoltage     = c_ubyte(2)
+analogioCurrent     = c_ubyte(3)
+analogioPower       = c_ubyte(4)
+analogioTemperature	= c_ubyte(5)
+analogioDmm	        = c_ubyte(6)
+analogioRange	    = c_ubyte(7)
+analogioMeasure	    = c_ubyte(8)
+analogioTime	    = c_ubyte(9)
+analogioFrequency	= c_ubyte(10)
+analogioResistance	= c_ubyte(11)
+
+DwfDmmResistance     = c_double(1)
+DwfDmmContinuity     = c_double(2)
+DwfDmmDiode          = c_double(3)
+DwfDmmDCVoltage      = c_double(4)
+DwfDmmACVoltage      = c_double(5)
+DwfDmmDCCurrent      = c_double(6)
+DwfDmmACCurrent      = c_double(7)
+DwfDmmDCLowCurrent   = c_double(8)
+DwfDmmACLowCurrent   = c_double(9)
+DwfDmmTemperature    = c_double(10)
+
+AnalogOutNodeCarrier  = c_int(0)
+AnalogOutNodeFM       = c_int(1)
+AnalogOutNodeAM       = c_int(2)
+
+DwfAnalogOutIdleDisable  = c_int(0)
+DwfAnalogOutIdleOffset   = c_int(1)
+DwfAnalogOutIdleInitial  = c_int(2)
+
+DwfDigitalInClockSourceInternal = c_int(0)
+DwfDigitalInClockSourceExternal = c_int(1)
+
+DwfDigitalInSampleModeSimple   = c_int(0)
+# alternate samples: noise|sample|noise|sample|...  
+# where noise is more than 1 transition between 2 samples
+DwfDigitalInSampleModeNoise    = c_int(1)
+
+DwfDigitalOutOutputPushPull   = c_int(0)
+DwfDigitalOutOutputOpenDrain  = c_int(1)
+DwfDigitalOutOutputOpenSource = c_int(2)
+DwfDigitalOutOutputThreeState = c_int(3) 
+
+DwfDigitalOutTypePulse      = c_int(0)
+DwfDigitalOutTypeCustom     = c_int(1)
+DwfDigitalOutTypeRandom     = c_int(2)
+DwfDigitalOutTypeROM        = c_int(3)
+DwfDigitalOutTypeState      = c_int(4)
+DwfDigitalOutTypePlay       = c_int(5)
+
+DwfDigitalOutIdleInit     = c_int(0)
+DwfDigitalOutIdleLow      = c_int(1)
+DwfDigitalOutIdleHigh     = c_int(2)
+DwfDigitalOutIdleZet      = c_int(3)
+
+DwfAnalogImpedanceImpedance         = c_int(0)
+DwfAnalogImpedanceImpedancePhase    = c_int(1)
+DwfAnalogImpedanceResistance        = c_int(2)
+DwfAnalogImpedanceReactance         = c_int(3)
+DwfAnalogImpedanceAdmittance        = c_int(4)
+DwfAnalogImpedanceAdmittancePhase   = c_int(5)
+DwfAnalogImpedanceConductance       = c_int(6)
+DwfAnalogImpedanceSusceptance       = c_int(7)
+DwfAnalogImpedanceSeriesCapacitance = c_int(8)
+DwfAnalogImpedanceParallelCapacitance = c_int(9)
+DwfAnalogImpedanceSeriesInductance  = c_int(10)
+DwfAnalogImpedanceParallelInductance = c_int(11)
+DwfAnalogImpedanceDissipation       = c_int(12)
+DwfAnalogImpedanceQuality           = c_int(13)
+DwfAnalogImpedanceVrms              = c_int(14)
+DwfAnalogImpedanceVreal             = c_int(15)
+DwfAnalogImpedanceVimag             = c_int(16)
+DwfAnalogImpedanceIrms              = c_int(17)
+DwfAnalogImpedanceIreal             = c_int(18)
+DwfAnalogImpedanceIimag             = c_int(19)
+
+DwfParamUsbPower        = c_int(2) # 1 keep the USB power enabled even when AUX is connected, Analog Discovery 2
+DwfParamLedBrightness   = c_int(3) # LED brightness 0 ... 100%, Digital Discovery
+DwfParamOnClose         = c_int(4) # 0 continue, 1 stop, 2 shutdown
+DwfParamAudioOut        = c_int(5) # 0 disable / 1 enable audio output, Analog Discovery 1, 2
+DwfParamUsbLimit        = c_int(6) # 0..1000 mA USB power limit, -1 no limit, Analog Discovery 1, 2
+DwfParamAnalogOut       = c_int(7) # 0 disable / 1 enable
+DwfParamFrequency       = c_int(8) # Hz
+DwfParamExtFreq         = c_int(9) # Hz
+DwfParamClockMode       = c_int(10) # 0 internal, 1 output, 2 input, 3 IO
+
+# obsolate
+#STS
+stsRdy		= c_ubyte(0)
+stsArm		= c_ubyte(1)
+stsDone		= c_ubyte(2)
+stsTrig		= c_ubyte(3)
+stsCfg		= c_ubyte(4)
+stsPrefill	= c_ubyte(5)
+stsNotDone	= c_ubyte(6)
+stsTrigDly	= c_ubyte(7)
+stsError	= c_ubyte(8)
+stsBusy		= c_ubyte(9)
+stsStop		= c_ubyte(10)
+
+#TRIGCOND
+trigcondRisingPositive   = c_int(0)
+trigcondFallingNegative  = c_int(1)
+
+#use deiceid
+enumfilterEExplorer  = c_int(1)
+enumfilterDiscovery  = c_int(2)
+enumfilterDiscovery2 = c_int(3)
+enumfilterDDiscovery = c_int(4)
+
+
diff --git a/src/FlexSensor/constants/qs_style_sheets.py b/src/FlexSensor/constants/qs_style_sheets.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd361c799927e8c976f0cec6c14dbc3562c54b25
--- /dev/null
+++ b/src/FlexSensor/constants/qs_style_sheets.py
@@ -0,0 +1,91 @@
+class CSSPlayPushButton:
+    @staticmethod
+    def style_play():
+        return """
+                QPushButton {		
+            background-color: rgb(36, 209, 21);
+            background-position: left center;
+            background-repeat: no-repeat;
+            border: none;
+            border-radius: 0px;
+            border-left: 22px solid transparent;
+            text-align: left;
+            padding-left: 44px;
+            background-image: url(:/icons/images/icons/cil-media-play.png);
+        }
+        
+        QPushButton:hover {
+            background-color: rgb(26, 153, 16);
+        }
+        
+        QPushButton:pressed {	
+            background-color: rgb(20, 120, 12);
+            color: rgb(255, 255, 255);
+        }
+        
+        QPushButton:disabled {	
+            background-color: rgb(153, 153, 153);
+            color: rgb(255, 255, 255);
+        }
+        
+                """
+
+    @staticmethod
+    def style_pause():
+        return """
+            QPushButton {		
+               background-color: rgb(255, 200,11);
+                background-position: left center;
+                background-repeat: no-repeat;
+                border: none;
+                border-radius: 0px;
+                border-left: 22px solid transparent;
+                text-align: left;
+                padding-left: 44px;
+                background-image: url(:/icons/images/icons/cil-media-pause.png)
+            }
+    
+            QPushButton:hover {
+                background-color: rgb(255, 182, 44);
+            }
+    
+            QPushButton:pressed {	
+                background-color: rgb(255, 146, 12);
+                color: rgb(255, 255, 255);
+            }
+    
+            QPushButton:disabled {	
+                background-color: rgb(153, 153, 153);
+                color: rgb(255, 255, 255);
+            }
+        """
+
+    @staticmethod
+    def style_stop():
+        return """
+            QPushButton {		
+                background-color: rgb(242, 41, 41);
+                background-position: left center;
+                background-repeat: no-repeat;
+                border: none;
+                border-radius: 0px;
+                border-left: 22px solid transparent;
+                text-align: left;
+                padding-left: 44px;
+                background-image: url(:/icons/images/icons/cil-media-stop.png)
+            }
+            
+            QPushButton:hover {
+                background-color: rgb(235, 64, 52);
+            }
+            
+            QPushButton:pressed {	
+                background-color: rgb(201, 17, 4);
+                color: rgb(255, 255, 255);
+            }
+            
+            QPushButton:disabled {	
+                background-color: rgb(153, 153, 153);
+                color: rgb(255, 255, 255);
+            }
+        """
diff --git a/src/FlexSensor/generics/ConsoleWindow.py b/src/FlexSensor/generics/ConsoleWindow.py
new file mode 100644
index 0000000000000000000000000000000000000000..b60abbcddd6cd4ccb81ff3de6a3eac48c20e29ed
--- /dev/null
+++ b/src/FlexSensor/generics/ConsoleWindow.py
@@ -0,0 +1,201 @@
+import logging
+import random
+import time
+import os
+
+from PySide6.QtCore import QObject, QThread, Signal, Slot
+from PySide6.QtGui import QFont, Qt
+from PySide6.QtWidgets import QWidget, QPlainTextEdit, QPushButton, QVBoxLayout
+
+#Signal = Signal
+#Slot = Slot
+logger = logging.getLogger(__name__)
+
+
+#
+# Signals need to be contained in a QObject or subclass in order to be correctly
+# initialized.
+#
+class Signaller(QObject):
+    signal = Signal(str, logging.LogRecord)
+
+#
+# Output to a Qt GUI is only supposed to happen on the main thread. So, this
+# handler is designed to take a slot function which is set up to run in the main
+# thread. In this example, the function takes a string argument which is a
+# formatted log message, and the log record which generated it. The formatted
+# string is just a convenience - you could format a string for output any way
+# you like in the slot function itself.
+#
+# You specify the slot function to do whatever GUI updates you want. The handler
+# doesn't know or care about specific UI elements.
+#
+
+
+class QtHandler(logging.Handler):
+    def __init__(self, slotfunc, *args, **kwargs):
+        super(QtHandler, self).__init__(*args, **kwargs)
+        self.signaller = Signaller()
+        self.signaller.signal.connect(slotfunc)
+
+    def emit(self, record):
+        s = self.format(record)
+        self.signaller.signal.emit(s, record)
+
+#
+# This example uses QThreads, which means that the threads at the Python level
+# are named something like "Dummy-1". The function below gets the Qt name of the
+# current thread.
+#
+
+
+def ctname():
+    return ""
+    # QtCore.QThread.currentThread().objectName()
+
+
+#
+# Used to generate random levels for logging.
+#
+LEVELS = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR,
+          logging.CRITICAL)
+
+#
+# This worker class represents work that is done in a thread separate to the
+# main thread. The way the thread is kicked off to do work is via a button press
+# that connects to a slot in the worker.
+#
+# Because the default threadName value in the LogRecord isn't much use, we add
+# a qThreadName which contains the QThread name as computed above, and pass that
+# value in an "extra" dictionary which is used to update the LogRecord with the
+# QThread name.
+#
+# This example worker just outputs messages sequentially, interspersed with
+# random delays of the order of a few seconds.
+#
+
+
+class Worker(QObject):
+    @Slot()
+    def start(self):
+        extra = {'qThreadName': ctname()}
+        logger.debug('Started work', extra=extra)
+        i = 1
+        # Let the thread run until interrupted. This allows reasonably clean
+        # thread termination.
+        while not QThread.currentThread().isInterruptionRequested():
+            delay = 0.5 + random.random() * 2
+            time.sleep(delay)
+            level = random.choice(LEVELS)
+            logger.log(level, 'Message after delay of %3.1f: %d',
+                       delay, i, extra=extra)
+            i += 1
+
+#
+# Implement a simple UI for this cookbook example. This contains:
+#
+# * A read-only text edit window which holds formatted log messages
+# * A button to start work and log stuff in a separate thread
+# * A button to log something from the main thread
+# * A button to clear the log window
+#
+
+
+class ConsoleWindow(QWidget):
+
+    COLORS = {
+        logging.DEBUG: 'blue',
+        logging.INFO: 'black',
+        logging.WARNING: 'orange',
+        logging.ERROR: 'red',
+        logging.CRITICAL: 'purple',
+    }
+
+    def __init__(self, app):
+        super().__init__()
+        self.app = app
+        self.textedit = te = QPlainTextEdit(self)
+        # set the window, so it alwys stays in front
+        self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
+        # Set whatever the default monospace font is for the platform
+        #f = QFont('nosuchfont')
+        #f.setStyleHint(f.Monospace)
+        #te.setFont(f)
+        te.setReadOnly(True)
+        PB = QPushButton
+        #self.work_button = PB('Start background work', self)
+
+        self.clear_button = PB('Clear log window', self)
+        self.handler = h = QtHandler(self.update_status)
+        # Remember to use qThreadName rather than threadName in the format string.
+        fs = '%(asctime)s %(levelname)-8s %(message)s'
+        formatter = logging.Formatter(fs)
+        h.setFormatter(formatter)
+        logger.addHandler(h)
+        # Set up to terminate the QThread when we exit
+        app.aboutToQuit.connect(self.force_quit)
+
+        # Lay out all the widgets
+        layout = QVBoxLayout(self)
+        layout.addWidget(te)
+        # layout.addWidget(self.work_button)
+
+        layout.addWidget(self.clear_button)
+        self.setFixedSize(1200, 400)
+
+        # Connect the non-worker slots and signals
+
+        self.clear_button.clicked.connect(self.clear_display)
+
+        # Start a new worker thread and connect the slots for the worker
+        # self.start_thread()
+        # self.work_button.clicked.connect(self.worker.start)
+        # Once started, the button should be disabled
+        #self.work_button.clicked.connect(lambda : self.work_button.setEnabled(False))
+
+    def start_thread(self):
+        self.worker = Worker()
+        self.worker_thread = QThread()
+        self.worker.setObjectName('Worker')
+        self.worker_thread.setObjectName('WorkerThread')  # for qThreadName
+        self.worker.moveToThread(self.worker_thread)
+        # This will start an event loop in the worker thread
+        self.worker_thread.start()
+
+    def kill_thread(self):
+        # Just tell the worker to stop, then tell it to quit and wait for that
+        # to happen
+        self.worker_thread.requestInterruption()
+        if self.worker_thread.isRunning():
+            self.worker_thread.quit()
+            self.worker_thread.wait()
+        else:
+            print('worker has already exited.')
+
+    def force_quit(self):
+        pass
+        # For use when the window is closed
+        # if self.worker_thread.isRunning():
+        #    self.kill_thread()
+
+    # The functions below update the UI and run in the main thread because
+    # that's where the slots are set up
+
+    @Slot(str, logging.LogRecord)
+    def update_status(self, status, record):
+        color = self.COLORS.get(record.levelno, 'black')
+        s = '<pre><font color="%s">%s</font></pre>' % (color, status)
+        self.textedit.appendHtml(s)
+
+    @Slot()
+    def manual_update(self):
+        # This function uses the formatted message passed in, but also uses
+        # information from the record to format the message in an appropriate
+        # color according to its severity (level).
+        level = random.choice(LEVELS)
+        extra = {'qThreadName': ctname()}
+        logger.log(level, 'Manually logged!', extra=extra)
+
+    @Slot()
+    def clear_display(self):
+        self.textedit.clear()
diff --git a/src/FlexSensor/generics/FolderHandler.py b/src/FlexSensor/generics/FolderHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce9dd9fd0e0a8a61a29ef053342df29bb3db6a57
--- /dev/null
+++ b/src/FlexSensor/generics/FolderHandler.py
@@ -0,0 +1,47 @@
+import logging
+import os
+
+from ConfigHandler.controller.VAutomatorConfig import VAutomatorConfig
+from ConfigHandler.controller.VFSObject import VFSObject
+
+
+class FolderHandler(object):
+
+    @staticmethod
+    def create_output_folder():
+        VAutomatorConfig.output_dir = FolderHandler.create_folder(VAutomatorConfig.output_dir)
+
+        return VAutomatorConfig.output_dir
+
+    @staticmethod
+    def create_folder(vfs_obj: VFSObject):
+        '''
+        Check if the folder exists, if not create it
+        '''
+        # Check if the given argument is a file
+        if os.path.isfile(vfs_obj.absolute):
+            folder = os.path.dirname(vfs_obj.absolute)
+
+        # Try creating the output directory
+        if not os.path.exists(folder):
+            try:
+                os.makedirs(folder)
+            except Exception as exc:
+                logging.error("Could not create folder {folder}. Exception: {exc}")
+                raise exc
+        return folder
+
+    @staticmethod
+    def set_and_create_file(filename):
+        '''
+        Check if the folder for file exists, if not create it
+        '''
+        logging.info("Setting file: %s" % filename)
+        # Try creating the output directory
+        if not os.path.exists(os.path.dirname(filename)):
+            try:
+                os.makedirs(os.path.dirname(filename))
+            except OSError as exc:
+                raise  Exception("Could not create folder %s/%s for path." % (os.path.dirname(filename), filename))
+        # create the file
+        return filename
\ No newline at end of file
diff --git a/src/FlexSensor/generics/GenericProperties.py b/src/FlexSensor/generics/GenericProperties.py
new file mode 100644
index 0000000000000000000000000000000000000000..eaa5bed4fc76759d4815d959976aa59fa6f90c3c
--- /dev/null
+++ b/src/FlexSensor/generics/GenericProperties.py
@@ -0,0 +1,34 @@
+from PySide6.QtCore import QObject
+from numpy import ndarray
+
+
+class GenericProperties(QObject):
+    def __init__(self):
+        super().__init__()
+
+    def to_str(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return str(value[0])
+        else:
+            return str(value)
+
+    def to_int(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return int(value[0])
+        else:
+            return int(value)
+
+    def to_float(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return float(value[0])
+        else:
+            return float(value)
+
+    def to_tuple(self, value):
+        if (isinstance(value, list) or isinstance(value, ndarray)) and len(value) == 1:
+            return tuple(value[0])
+        else:
+            return tuple(value)
+
+    def fields(self) -> dict:
+      raise NotImplementedError
diff --git a/src/FlexSensor/generics/PandasTableModel.py b/src/FlexSensor/generics/PandasTableModel.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c199832356abb7b39b9e08cf59a4ab742535720
--- /dev/null
+++ b/src/FlexSensor/generics/PandasTableModel.py
@@ -0,0 +1,30 @@
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QMenu
+
+
+class PandasTableModel(QAbstractTableModel):
+    def __init__(self, df):
+        super().__init__()
+        self.df = df
+
+    def rowCount(self, parent=None):
+        return self.df.shape[0]
+
+    def columnCount(self, parent=None):
+
+        return self.df.shape[1]
+
+    def data(self, index, role=Qt.DisplayRole):
+        if role == Qt.DisplayRole:
+            row = index.row()
+            col = index.column()
+            return str(self.df.iloc[row, col])
+        return None
+
+    def headerData(self, section, orientation, role=Qt.DisplayRole):
+        if role == Qt.DisplayRole:
+            if orientation == Qt.Horizontal:
+                return str(self.df.columns[section])
+            elif orientation == Qt.Vertical:
+                return str(self.df.index[section])
+        return None
diff --git a/src/FlexSensor/generics/__init__.py b/src/FlexSensor/generics/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/FlexSensor/generics/generics.py b/src/FlexSensor/generics/generics.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f2c679af1fbe343bb27995d794724e53ec17bf1
--- /dev/null
+++ b/src/FlexSensor/generics/generics.py
@@ -0,0 +1,4 @@
+def pch(c, num):
+    return ''.join([str(c) for i in range(0, num)])
+
+
diff --git a/src/FlexSensor/generics/logger.py b/src/FlexSensor/generics/logger.py
new file mode 100644
index 0000000000000000000000000000000000000000..89c95c6eca27bb4d0b69a51b51e101f69dfe0cef
--- /dev/null
+++ b/src/FlexSensor/generics/logger.py
@@ -0,0 +1,145 @@
+import logging
+
+from PySide6 import QtCore, QtWidgets
+from PySide6.QtCore import Signal
+from rich.logging import RichHandler
+from scipy.signal import find_peaks#, find_peaks_cwt
+import os
+#from PySide6.QtNetwork import QAbstractSocket
+from os import mkdir
+from multiprocessing import Pool, Value
+import os.path
+from datetime import datetime
+# Needed for Digilent Analog Discovery 2 data acquisition	
+from ctypes import *
+try:
+    from generics.ConsoleWindow import ConsoleWindow
+except:
+    pass
+
+
+class QTextEditLogger(logging.Handler, QtCore.QObject):
+    appendPlainText = Signal(str)
+
+    def __init__(self, parent):
+        super().__init__()
+        QtCore.QObject.__init__(self)
+        self.widget = QtWidgets.QPlainTextEdit(parent)
+        self.widget.setReadOnly(True)
+        self.appendPlainText.connect(self.widget.appendPlainText)
+
+    def emit(self, record):
+        msg = self.format(record)
+        self.appendPlainText.emit(msg)
+
+
+class Logger:
+   
+    log_file_full = None
+    @staticmethod
+    def set_output_file(logfile):
+        Logger.log_file_full = logfile
+        print("%s" % Logger.log_file_full)
+
+    FORMAT="%Y-%m-%d %H-%M-%S.%f"
+
+    @staticmethod
+    def check_or_create_log_file():
+        if log_file_full is None:
+            raise ValueError("Log file can't be None")
+        if not os.path.exists(os.path.dirname(Logger.log_file_full)):
+            try:
+                os.makedirs(os.path.dirname(Logger.log_file_full))
+            except OSError as exc:  
+                    raise  Exception("Could not create log file.")
+        Logger.info("Log file created: %s" % Logger.log_file_full)
+
+    @staticmethod 
+    def debug(*args):
+        msg =  datetime.now().strftime(Logger.FORMAT) + " [DEBUG] " + "".join(str(arg) for arg in args)
+        # check if folder exists
+        #logger.check_or_create_log_file()
+
+        with open(Logger.log_file_full, "a+") as f:
+            f.write(msg+ "\n")
+            
+        #status_bar.showMessage("[DEBUG] " + "".join(str(arg) for arg in args))
+        #status_bar.setStyleSheet('border: 0; color:  blue;')
+        print(msg)
+        return msg
+
+    @staticmethod
+    def info(*args):
+        msg =   datetime.now().strftime(Logger.FORMAT) + "  [INFO] " + "".join(str(arg) for arg in args)
+        # check if folder exists
+        #logger.check_or_create_log_file()
+
+        with open(Logger.log_file_full, "a+") as f:
+            f.write(msg + "\n")
+        
+        #status_bar.showMessage("[INFO] " + "".join(str(arg) for arg in args))
+        #status_bar.setStyleSheet('border: 0; color:  black;')
+        print(msg)
+        return msg
+
+    @staticmethod
+    def warning(*args):
+        msg =  datetime.now().strftime(Logger.FORMAT) + "  [WARN] " + "".join(str(arg) for arg in args)
+        # check if folder exists
+        #logger.check_or_create_log_file()
+
+        with open(Logger.log_file_full, "a+") as f:
+            f.write(msg+ "\n")
+
+        #status_bar.showMessage("[WARN] " + "".join(str(arg) for arg in args))
+        #status_bar.setStyleSheet('border: 0; color:  orange;')
+        print(msg)
+        return msg
+
+    @staticmethod
+    def error(*args):
+        msg =  datetime.now().strftime(Logger.FORMAT) + " [ERROR] " + "".join(str(arg) for arg in args)
+        # check if folder exists
+        #logger.check_or_create_log_file()
+
+        with open(Logger.log_file_full, "a+") as f:
+            f.write(msg + "\n")
+        
+        #status_bar.showMessage("[ERROR] " + "".join(str(arg) for arg in args))
+        #status_bar.setStyleSheet('border: 0; color:  red;')
+        print(msg)
+        return msg
+    
+    @staticmethod
+    def fatal(*args):
+        msg =   datetime.now().strftime(Logger.FORMAT) + " [FATAL] " + "".join(str(arg) for arg in args)
+        # check if folder exists
+        #logger.check_or_create_log_file()
+
+        with open(Logger.log_file_full, "a+") as f:
+            f.write(msg + "\n")
+        
+        #status_bar.showMessage("[FATAL] " + "".join(str(arg) for arg in args))
+        #status_bar.setStyleSheet('border: 0; color:  red;')
+        print(msg)
+        return msg
+
+
+def setup_logging(window: ConsoleWindow = None):
+    for log_name, log_obj in logging.Logger.manager.loggerDict.items():
+        if log_name != '<module name>':
+            log_obj.disabled = True
+    # Format the Rich logger
+    FORMAT = "%(message)s"
+    if window is not None:
+        logging.basicConfig(
+            level="DEBUG", format=FORMAT, datefmt="[%X]", handlers=[
+                RichHandler(rich_tracebacks=True), window.handler
+            ]
+        )
+    else:
+        logging.basicConfig(
+            level="DEBUG", format=FORMAT, datefmt="[%X]", handlers=[
+                RichHandler(rich_tracebacks=True)
+            ]
+        )
\ No newline at end of file
diff --git a/src/FlexSensor/generics/widgets.py b/src/FlexSensor/generics/widgets.py
new file mode 100644
index 0000000000000000000000000000000000000000..b61e4714c47be8efeba0e3b813d883a6db9fd96b
--- /dev/null
+++ b/src/FlexSensor/generics/widgets.py
@@ -0,0 +1,24 @@
+from PySide6.QtWidgets import QLabel
+
+
+class LEDIndicatorWidget(QLabel):
+    def __init__(self, color="yellow"):
+        super().__init__()
+        self.size = 8
+        self._create_led(color)
+
+    def _create_led(self, color):
+        self.set_color(color)
+
+    def set_color(self, color):
+        self.setStyleSheet(
+            "QLabel {background-color : " f"{color};"
+            "border-color : black; "
+            "border-width: 1px; "
+            "border-style: solid; "
+            f"border-radius: {int(self.size / 2)}px; "
+            f"min-height: {self.size}px; "
+            f"min-width: {self.size}px; "
+            f"max-height: {self.size}px; "
+            f"max-width: {self.size}px"
+            "}")