diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml
new file mode 100644
index 0000000..f3e3890
--- /dev/null
+++ b/bitbucket-pipelines.yml
@@ -0,0 +1,10 @@
+image: python:3.7.3
+options:
+ max-time: 1
+pipelines:
+ pull-requests:
+ '**':
+ - step:
+ script:
+ - git submodule update --init
+ - python twincat_version_manager.py
\ No newline at end of file
diff --git a/solution/solution.tsproj b/solution/solution.tsproj
index 3678528..729ffe6 100644
--- a/solution/solution.tsproj
+++ b/solution/solution.tsproj
@@ -411,8 +411,7 @@
AxisState
UDINT
-
-
-
+]]>
32
64
@@ -440,8 +438,7 @@ External Setpoint Generation:
HomingState
UDINT
-
-
-
+]]>
32
128
CoupleState
UDINT
-
-
-
+]]>
32
160
@@ -690,13 +684,13 @@ External Setpoint Generation:
NCAXLESTRUCT_TOPLC4
-
+
-
+
-
+
@@ -913,30 +907,22 @@ External Setpoint Generation:
PlcTask Inputs
GVL.axes[1].inputs.bLimitFwd
-
-
-
+
BOOL
GVL.axes[1].inputs.bLimitBwd
-
-
-
+
BOOL
GVL.axes[1].inputs.bHomeSensor
-
-
-
+
BOOL
GVL.axes[1].inputs.bEncLAtch
-
-
-
+
BOOL
@@ -944,8 +930,7 @@ External Setpoint Generation:
NCTOPLC_AXIS_REF
AxisState
-
-
-
+]]>
HomingState
-
-
-
+]]>
CoupleState
-
-
-
+]]>
GVL.axes[2].inputs.bLimitFwd
-
-
-
+
BOOL
GVL.axes[2].inputs.bLimitBwd
-
-
-
+
BOOL
GVL.axes[2].inputs.bHomeSensor
-
-
-
+
BOOL
GVL.axes[2].inputs.bEncLAtch
-
-
-
+
BOOL
@@ -1021,8 +993,7 @@ External Setpoint Generation:
NCTOPLC_AXIS_REF
AxisState
-
-
-
+]]>
HomingState
-
-
-
+]]>
CoupleState
-
-
-
+]]>
GVL.axes[3].inputs.bLimitFwd
-
-
-
+
BOOL
GVL.axes[3].inputs.bLimitBwd
-
-
-
+
BOOL
GVL.axes[3].inputs.bHomeSensor
-
-
-
+
BOOL
GVL.axes[3].inputs.bEncLAtch
-
-
-
+
BOOL
@@ -1098,8 +1056,7 @@ External Setpoint Generation:
NCTOPLC_AXIS_REF
AxisState
-
-
-
+]]>
HomingState
-
-
-
+]]>
CoupleState
-
-
-
+]]>
@@ -1147,9 +1099,7 @@ External Setpoint Generation:
PlcTask Outputs
MAIN.bOutput1
-
-
-
+
BOOL
@@ -1172,7 +1122,4 @@ External Setpoint Generation:
-
-
-
diff --git a/solution/tc_epicscommodule b/solution/tc_epicscommodule
index 370c81a..3794bb7 160000
--- a/solution/tc_epicscommodule
+++ b/solution/tc_epicscommodule
@@ -1 +1 @@
-Subproject commit 370c81aa67f1a39bac865b098d611720ebc82d7b
+Subproject commit 3794bb7a9801d08901fe8efcf3e103582b5d7e2c
diff --git a/solution/tc_project_app/tc_mca_std_lib b/solution/tc_project_app/tc_mca_std_lib
index 7003429..c74a21a 160000
--- a/solution/tc_project_app/tc_mca_std_lib
+++ b/solution/tc_project_app/tc_mca_std_lib
@@ -1 +1 @@
-Subproject commit 7003429e2198b2e194ecb0583c6ea4ec83b898ec
+Subproject commit c74a21a99d2749be86a12e4406bbfcfbb3618841
diff --git a/twincat_version_manager.py b/twincat_version_manager.py
new file mode 100644
index 0000000..3483331
--- /dev/null
+++ b/twincat_version_manager.py
@@ -0,0 +1,40 @@
+import glob
+import xml.etree.ElementTree as ET
+
+VERSION_TAGS = {"**/*.Tc*": "ProductVersion", "**/*.tsproj": "TcVersion"}
+CORRECT_VERSION = "3.1.4024.0"
+
+
+def check_versions():
+ """
+ Checks the Twincat version used to create a file.
+ It assumes that the version is stored as an attribute on the top element of the file, the attribute names are
+ listed in VERSION_TAGS.
+ :return: A dictionary of incorrect files and their version numbers
+ """
+ incorrect_files = dict()
+ for file_path, version_attrib in VERSION_TAGS.items():
+ found_files = glob.glob(file_path, recursive=True)
+ if not found_files:
+ raise IOError("ERROR: No files of type {} found".format(file_path))
+ for file in found_files:
+ tree = ET.parse(file)
+ try:
+ found_version = tree.getroot().attrib[version_attrib]
+ if found_version != CORRECT_VERSION:
+ incorrect_files[file] = found_version
+ except KeyError:
+ print("WARNING: No version found for {}".format(file))
+ return incorrect_files
+
+
+if __name__ == "__main__":
+ try:
+ incorrect_files = check_versions()
+ for file, version in incorrect_files.items():
+ print("ERROR: {} has incorrect version {}, expected version {}".format(file, version, CORRECT_VERSION))
+ if incorrect_files:
+ exit(1)
+ except IOError as e:
+ print(e) # Likely no files found
+ exit(2)