diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b1ac876
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,57 @@
+### TwinCAT3 ###
+# website: https://www.beckhoff.com/twincat3/
+
+# TwinCAT PLC
+*.plcproj.bak
+*.plcproj.orig
+*.tpy
+*.tclrs
+#*.library
+#*.compiled-library
+*.compileinfo
+*.asm
+*.core
+LineIDs.dbg
+LineIDs.dbg.bak
+
+# TwinCAT C++ and shared types
+# ignoring the TMC file is only useful for plain PLC programming
+# as soon as shared data types (via tmc), C++ or in general TcCom-Module are used, the TMC file has to be part of the repository
+*.tmc
+*.tmcRefac
+
+# TwinCAT project files
+*.tsproj.bak
+*.tspproj.bak
+*.tsproj.b?k
+*.tsproj.orig
+*.xti.bak
+*.xti.bk?
+*.xti.orig
+*.xtv
+*.xtv.bak
+*.xtv.bk?
+*.tnzip
+
+# Multiuser specific
+**/.TcGit/
+
+# exclude not required folders
+**/_Boot/
+**/_CompileInfo/
+**/_Libraries/
+**/_ModuleInstall/
+**/_Deployment/
+**/_Repository/
+
+# VS Shell project specific files and folders
+**/.vs/
+*.~u
+*.project.~u
+*.suo
+
+# Own Ignores
+commit.txt
+*.txt
+*.exe
+*.xlsx
\ No newline at end of file
diff --git a/BaseComponents.sln b/BaseComponents.sln
new file mode 100644
index 0000000..a478669
--- /dev/null
+++ b/BaseComponents.sln
@@ -0,0 +1,89 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# TcXaeShell Solution File, Format Version 11.00
+VisualStudioVersion = 17.10.35827.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{B1E792BE-AA5F-4E3C-8C82-674BF9C0715B}") = "BaseComponents", "BaseComponents.tsproj", "{775BE4FD-89CE-48D5-8E68-5C84AF95981A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|TwinCAT OS (ARMV7-A) = Debug|TwinCAT OS (ARMV7-A)
+ Debug|TwinCAT OS (ARMV7-M) = Debug|TwinCAT OS (ARMV7-M)
+ Debug|TwinCAT OS (ARMV8-A) = Debug|TwinCAT OS (ARMV8-A)
+ Debug|TwinCAT OS (x64) = Debug|TwinCAT OS (x64)
+ Debug|TwinCAT OS (x64-E) = Debug|TwinCAT OS (x64-E)
+ Debug|TwinCAT RT (x64) = Debug|TwinCAT RT (x64)
+ Debug|TwinCAT RT (x86) = Debug|TwinCAT RT (x86)
+ Release|TwinCAT OS (ARMV7-A) = Release|TwinCAT OS (ARMV7-A)
+ Release|TwinCAT OS (ARMV7-M) = Release|TwinCAT OS (ARMV7-M)
+ Release|TwinCAT OS (ARMV8-A) = Release|TwinCAT OS (ARMV8-A)
+ Release|TwinCAT OS (x64) = Release|TwinCAT OS (x64)
+ Release|TwinCAT OS (x64-E) = Release|TwinCAT OS (x64-E)
+ Release|TwinCAT RT (x64) = Release|TwinCAT RT (x64)
+ Release|TwinCAT RT (x86) = Release|TwinCAT RT (x86)
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (ARMV7-A).ActiveCfg = Debug|TwinCAT OS (ARMV7-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (ARMV7-A).Build.0 = Debug|TwinCAT OS (ARMV7-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (ARMV7-M).ActiveCfg = Debug|TwinCAT OS (ARMV7-M)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (ARMV7-M).Build.0 = Debug|TwinCAT OS (ARMV7-M)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (ARMV8-A).ActiveCfg = Debug|TwinCAT OS (ARMV8-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (ARMV8-A).Build.0 = Debug|TwinCAT OS (ARMV8-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (x64).ActiveCfg = Debug|TwinCAT OS (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (x64).Build.0 = Debug|TwinCAT OS (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (x64-E).ActiveCfg = Debug|TwinCAT OS (x64-E)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT OS (x64-E).Build.0 = Debug|TwinCAT OS (x64-E)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (ARMV7-A).ActiveCfg = Release|TwinCAT OS (ARMV7-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (ARMV7-A).Build.0 = Release|TwinCAT OS (ARMV7-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (ARMV7-M).ActiveCfg = Release|TwinCAT OS (ARMV7-M)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (ARMV7-M).Build.0 = Release|TwinCAT OS (ARMV7-M)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (ARMV8-A).ActiveCfg = Release|TwinCAT OS (ARMV8-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (ARMV8-A).Build.0 = Release|TwinCAT OS (ARMV8-A)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (x64).ActiveCfg = Release|TwinCAT OS (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (x64).Build.0 = Release|TwinCAT OS (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (x64-E).ActiveCfg = Release|TwinCAT OS (x64-E)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT OS (x64-E).Build.0 = Release|TwinCAT OS (x64-E)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86)
+ {775BE4FD-89CE-48D5-8E68-5C84AF95981A}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (ARMV7-A).ActiveCfg = Debug|TwinCAT OS (ARMV7-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (ARMV7-A).Build.0 = Debug|TwinCAT OS (ARMV7-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (ARMV7-M).ActiveCfg = Debug|TwinCAT OS (ARMV7-M)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (ARMV7-M).Build.0 = Debug|TwinCAT OS (ARMV7-M)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (ARMV8-A).ActiveCfg = Debug|TwinCAT OS (ARMV8-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (ARMV8-A).Build.0 = Debug|TwinCAT OS (ARMV8-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (x64).ActiveCfg = Debug|TwinCAT OS (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (x64).Build.0 = Debug|TwinCAT OS (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (x64-E).ActiveCfg = Debug|TwinCAT OS (x64-E)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT OS (x64-E).Build.0 = Debug|TwinCAT OS (x64-E)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (ARMV7-A).ActiveCfg = Release|TwinCAT OS (ARMV7-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (ARMV7-A).Build.0 = Release|TwinCAT OS (ARMV7-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (ARMV7-M).ActiveCfg = Release|TwinCAT OS (ARMV7-M)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (ARMV7-M).Build.0 = Release|TwinCAT OS (ARMV7-M)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (ARMV8-A).ActiveCfg = Release|TwinCAT OS (ARMV8-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (ARMV8-A).Build.0 = Release|TwinCAT OS (ARMV8-A)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (x64).ActiveCfg = Release|TwinCAT OS (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (x64).Build.0 = Release|TwinCAT OS (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (x64-E).ActiveCfg = Release|TwinCAT OS (x64-E)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT OS (x64-E).Build.0 = Release|TwinCAT OS (x64-E)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86)
+ {4E62D9E7-436C-457D-8DC4-82D2FEF91C96}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86)
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {774463EE-2F3E-4F1B-B601-3BD67A7A2115}
+ EndGlobalSection
+EndGlobal
diff --git a/BaseComponents.tsproj b/BaseComponents.tsproj
new file mode 100644
index 0000000..479ff0e
--- /dev/null
+++ b/BaseComponents.tsproj
@@ -0,0 +1,508 @@
+
+
+
+
+ AnalogOutput
+
+
+ ConfigError
+
+ Error
+
+
+
+
+
+
+ Valve
+
+
+ DidNotOpen
+
+ Error
+
+
+ DidNotClose
+
+ Error
+
+
+ AnalogFeedbackOC
+
+ Error
+
+
+ AnalogOutputOC
+
+ Error
+
+
+ NotInRange
+
+ Error
+
+
+
+
+
+
+ AnalogInput
+
+
+ ErrorHigh
+
+ Error
+
+
+ WarningHigh
+
+ Warning
+
+
+ WarningLow
+
+ Warning
+
+
+ ErrorLow
+
+ Error
+
+
+ AIConfigError
+
+ Error
+
+
+ AIShortCircuit
+
+ Error
+
+
+ AICardFailure
+
+ Error
+
+
+ AIOpenCircuit
+
+ Error
+
+
+
+
+
+
+
+ Motor
+
+
+ NotInTarget
+
+ Error
+
+
+ RepairSwitchOpen
+
+ Error
+
+
+ MCBTripped
+
+ Error
+
+
+
+
+
+
+
+
+
+
+
+ {9FD32FC8-0CF9-4C5B-95FB-F35423496A77}
+
+
+
+
+
+ PlcTask
+
+
+
+
+
+
+
+
+
+ BasicComponents Instance
+ {08500001-0000-0000-F000-000000000064}
+
+ PlcTask Outputs
+
+ PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xOpenValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xCloseValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xOpenValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xCloseValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xOpenValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xCloseValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xOpenValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xCloseValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValveTestHMI._fbValveOC.xOpenValve
+
+ BOOL
+
+
+ PRG_MAIN._fbValveTestHMI._fbValveOC.xCloseValve
+
+ BOOL
+
+
+
+ PlcTask Inputs
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOn.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOn.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOn.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOn.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOn.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOn.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOn.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOn.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOn.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOn.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOn.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOn.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOn.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOn.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOn.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOn.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOn.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOn.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOn.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOn.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOn.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOn.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOn.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOn.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOff.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOff.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOff.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorLowOff.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOff.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOff.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOff.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningLowOff.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOff.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOff.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOff.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIWarningHighOff.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOff.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOff.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOff.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIErrorHighOff.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOff.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOff.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOff.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIUnderrangeOff.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOff.iAnalogValue
+
+ INT
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOff.xUnderrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOff.xOverrange
+
+ BOOL
+
+
+ PRG_MAIN._fbAnalogInputTest._fbAIOverrangeOff.xErrorCard
+
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xOpenFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestOpen._fbValveTimeout.xCloseFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xOpenFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimeoutTestClose._fbValveTimeout.xCloseFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xOpenFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerOpen._fbValveTimeout.xCloseFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xOpenFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValve_TimoutTriggerClose._fbValveTimeout.xCloseFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValveTestHMI._fbValveOC.xOpenFeedback
+ BOOL
+
+
+ PRG_MAIN._fbValveTestHMI._fbValveOC.xCloseFeedback
+ BOOL
+
+
+
+
+ 0
+ PlcTask
+
+ #x02010030
+
+ 20
+ 10000000
+
+
+
+
+
+
+
+
+
+
diff --git a/BasicComponents.library b/BasicComponents.library
new file mode 100644
index 0000000..4ba6317
Binary files /dev/null and b/BasicComponents.library differ
diff --git a/BasicComponents/BasicComponents.plcproj b/BasicComponents/BasicComponents.plcproj
new file mode 100644
index 0000000..492bd9f
--- /dev/null
+++ b/BasicComponents/BasicComponents.plcproj
@@ -0,0 +1,2679 @@
+
+
+
+ 1.0.0.0
+ 2.0
+ {4e62d9e7-436c-457d-8dc4-82d2fef91c96}
+ true
+ true
+ false
+ false
+ BasicComponents
+ 3.1.4026.19
+ {7cc9c530-510c-48e6-a294-2e6b5e6fa820}
+ {951d7a0c-817c-4013-8204-ecd29ee0162e}
+ {e6d3915d-876b-4120-9e42-92be330ed750}
+ {86bdbf68-2971-41b8-9b27-17e052a7f55d}
+ {173a046e-fc1b-4ea3-9ec8-0d52397c403c}
+ {c870d3c5-a637-481e-9586-ab8eaa6f8f36}
+ false
+ false
+ false
+ Heisig GmbH
+ BaseComponents
+ 1.0
+ BC
+ M.Heisig
+ Basic components fb's (Valves, AI, AO, Motors, etc.)
+
+
+ {3d49e892-ba18-4f02-888a-850f97d52db7}
+ 1.0.0.0
+ Heisig GmbH
+
+
+ {eb1097e9-64c5-43a2-8e69-a580a5ac7866}
+ 1.0.0.0
+
+ {3d49e892-ba18-4f02-888a-850f97d52db7}
+
+ Standard Libraries
+
+
+
+ {3d49e892-ba18-4f02-888a-850f97d52db7}
+ {eb1097e9-64c5-43a2-8e69-a580a5ac7866}
+
+
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+ true
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+ true
+
+
+ Code
+ true
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+ Code
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tc2_MC2, * (Beckhoff Automation GmbH)
+ Tc2_MC2
+
+
+ Tc2_Standard, * (Beckhoff Automation GmbH)
+ Tc2_Standard
+
+
+ Tc2_System, * (Beckhoff Automation GmbH)
+ Tc2_System
+
+
+ Tc2_Utilities, * (Beckhoff Automation GmbH)
+ Tc2_Utilities
+
+
+ Tc3_EventLogger, * (Beckhoff Automation GmbH)
+ Tc3_EventLogger
+
+
+ Tc3_IotBase, * (Beckhoff Automation GmbH)
+ Tc3_IotBase
+
+
+ Tc3_JsonXml, * (Beckhoff Automation GmbH)
+ Tc3_JsonXml
+
+
+ Tc3_Module, * (Beckhoff Automation GmbH)
+ Tc3_Module
+ true
+
+
+ TcUnit, * (www.tcunit.org)
+ TcUnit
+
+
+
+
+ Content
+
+
+
+
+ Content
+
+
+
+
+
+
+
+ "<ProjectRoot>"
+
+ {192FAD59-8248-4824-A8DE-9177C94C195A}
+
+ "{192FAD59-8248-4824-A8DE-9177C94C195A}"
+
+
+
+ {246001F4-279D-43AC-B241-948EB31120E1}
+
+ "{246001F4-279D-43AC-B241-948EB31120E1}"
+
+
+
+ {29BD8D0C-3586-4548-BB48-497B9A01693F}
+
+ "{29BD8D0C-3586-4548-BB48-497B9A01693F}"
+
+ Metrics
+
+ "Metrics"
+
+ 0ade9a3b-311c-4293-bc26-bcf994cdbbdc
+
+ "0ade9a3b-311c-4293-bc26-bcf994cdbbdc"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 0ba696f2-ce22-4330-931f-4ddd5c597896
+
+ "0ba696f2-ce22-4330-931f-4ddd5c597896"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 15c07c54-9586-460c-802f-b3b4a408e3c7
+
+ "15c07c54-9586-460c-802f-b3b4a408e3c7"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 19fab17a-876c-4a8d-9d74-3e5d92b63dc8
+
+ "19fab17a-876c-4a8d-9d74-3e5d92b63dc8"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 2a5d0bd7-5767-43e1-92ab-90d924ade69e
+
+ "2a5d0bd7-5767-43e1-92ab-90d924ade69e"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 2ee16325-7a34-4109-82cd-e99144bdbf43
+
+ "2ee16325-7a34-4109-82cd-e99144bdbf43"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 3fb5ac29-8ac7-4ca4-863e-49c3c89643b9
+
+ "3fb5ac29-8ac7-4ca4-863e-49c3c89643b9"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 40f104a2-99f0-486d-9c44-47e8c759ca07
+
+ "40f104a2-99f0-486d-9c44-47e8c759ca07"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 571980c1-792d-4355-a9cb-4c3a8f254ab0
+
+ "571980c1-792d-4355-a9cb-4c3a8f254ab0"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 62b98ef9-b4c6-4777-bc0a-29245bb8b9f3
+
+ "62b98ef9-b4c6-4777-bc0a-29245bb8b9f3"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 6549803a-9e82-4b28-aff1-2425cbec813b
+
+ "6549803a-9e82-4b28-aff1-2425cbec813b"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 6c74d656-f35f-41b9-b449-eae882ed12fe
+
+ "6c74d656-f35f-41b9-b449-eae882ed12fe"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 6cb1bfb1-4d4a-43ed-96f4-cd0254fc33b5
+
+ "6cb1bfb1-4d4a-43ed-96f4-cd0254fc33b5"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 87b20586-90da-40d8-82ce-62a7dd0ba8af
+
+ "87b20586-90da-40d8-82ce-62a7dd0ba8af"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ 9b526466-3bbe-40a9-b5a5-1cfadd791459
+
+ "9b526466-3bbe-40a9-b5a5-1cfadd791459"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ aebdfc4d-fc4f-4fac-bf2e-22b603bc1880
+
+ "aebdfc4d-fc4f-4fac-bf2e-22b603bc1880"
+
+
+ bActive
+ false
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ b42720b9-b152-4b52-ad89-630e0f5acab1
+
+ "b42720b9-b152-4b52-ad89-630e0f5acab1"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ c4137578-73e0-4a9c-ad9c-7773a1cff401
+
+ "c4137578-73e0-4a9c-ad9c-7773a1cff401"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ cccccccc-1d56-4a6c-a0bc-05d25846cb02
+
+ "cccccccc-1d56-4a6c-a0bc-05d25846cb02"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ daa3e89b-a727-4bc9-bd38-29afc6024f90
+
+ "daa3e89b-a727-4bc9-bd38-29afc6024f90"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ e58378e8-a2fb-4a33-8013-8a91270388d0
+
+ "e58378e8-a2fb-4a33-8013-8a91270388d0"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+ f6dd9a78-1e71-4d9c-9e61-394eb38f3809
+
+ "f6dd9a78-1e71-4d9c-9e61-394eb38f3809"
+
+
+ bActive
+ true
+ stLowerLimit
+ ""
+ stUpperLimit
+ ""
+
+
+
+
+
+ NamingConventions
+
+ "NamingConventions"
+
+ 10
+
+ "10"
+
+
+ stPrefix
+ ui
+
+
+ 102
+
+ "102"
+
+
+ stPrefix
+ PRG_
+
+
+ 103
+
+ "103"
+
+
+ stPrefix
+ FB_
+
+
+ 104
+
+ "104"
+
+
+ stPrefix
+ FC_
+
+
+ 105
+
+ "105"
+
+
+ stPrefix
+
+
+
+ 106
+
+ "106"
+
+
+ stPrefix
+
+
+
+ 107
+
+ "107"
+
+
+ stPrefix
+
+
+
+ 108
+
+ "108"
+
+
+ stPrefix
+ I_
+
+
+ 11
+
+ "11"
+
+
+ stPrefix
+ udi
+
+
+ 12
+
+ "12"
+
+
+ stPrefix
+ uli
+
+
+ 121
+
+ "121"
+
+
+ stPrefix
+
+
+
+ 122
+
+ "122"
+
+
+ stPrefix
+
+
+
+ 123
+
+ "123"
+
+
+ stPrefix
+
+
+
+ 124
+
+ "124"
+
+
+ stPrefix
+
+
+
+ 13
+
+ "13"
+
+
+ stPrefix
+ si
+
+
+ 14
+
+ "14"
+
+
+ stPrefix
+ i
+
+
+ 15
+
+ "15"
+
+
+ stPrefix
+ di
+
+
+ 151
+
+ "151"
+
+
+ stPrefix
+ ST_
+
+
+ 152
+
+ "152"
+
+
+ stPrefix
+ E_
+
+
+ 153
+
+ "153"
+
+
+ stPrefix
+
+
+
+ 154
+
+ "154"
+
+
+ stPrefix
+
+
+
+ 16
+
+ "16"
+
+
+ stPrefix
+ li
+
+
+ 161
+
+ "161"
+
+ F_TRIG
+
+ "F_TRIG"
+
+
+ stPrefix
+ ftrig
+
+
+ R_TRIG
+
+ "R_TRIG"
+
+
+ stPrefix
+ rtrig
+
+
+ T_HSERVER
+
+ "T_HSERVER"
+
+
+ stPrefix
+ h
+
+
+ T_HSOCKET
+
+ "T_HSOCKET"
+
+
+ stPrefix
+ h
+
+
+ T_INTERLOCK
+
+ "T_INTERLOCK"
+
+
+ stPrefix
+ w
+
+
+ T_MaxString
+
+ "T_MaxString"
+
+
+ stPrefix
+ s
+
+
+ TOF
+
+ "TOF"
+
+
+ stPrefix
+ fb
+
+
+ TON
+
+ "TON"
+
+
+ stPrefix
+ fb
+
+
+
+
+
+ 17
+
+ "17"
+
+
+ stPrefix
+ r
+
+
+ 18
+
+ "18"
+
+
+ stPrefix
+ lr
+
+
+ 19
+
+ "19"
+
+
+ stPrefix
+ s
+
+
+ 20
+
+ "20"
+
+
+ stPrefix
+ ws
+
+
+ 21
+
+ "21"
+
+
+ stPrefix
+ tim
+
+
+ 22
+
+ "22"
+
+
+ stPrefix
+ ltim
+
+
+ 23
+
+ "23"
+
+
+ stPrefix
+ d
+
+
+ 24
+
+ "24"
+
+
+ stPrefix
+ dt
+
+
+ 25
+
+ "25"
+
+
+ stPrefix
+ td
+
+
+ 26
+
+ "26"
+
+
+ stPrefix
+ p
+
+
+ 27
+
+ "27"
+
+
+ stPrefix
+ ref
+
+
+ 28
+
+ "28"
+
+
+ stPrefix
+
+
+
+ 29
+
+ "29"
+
+
+ stPrefix
+ e
+
+
+ 3
+
+ "3"
+
+
+ stPrefix
+ x
+
+
+ 30
+
+ "30"
+
+
+ stPrefix
+ a
+
+
+ 31
+
+ "31"
+
+
+ stPrefix
+ fb
+
+
+ 32
+
+ "32"
+
+
+ stPrefix
+ st
+
+
+ 33
+
+ "33"
+
+
+ stPrefix
+
+
+
+ 34
+
+ "34"
+
+
+ stPrefix
+
+
+
+ 35
+
+ "35"
+
+
+ stPrefix
+
+
+
+ 36
+
+ "36"
+
+
+ stPrefix
+ fb
+
+
+ 37
+
+ "37"
+
+
+ stPrefix
+
+
+
+ 38
+
+ "38"
+
+
+ stPrefix
+
+
+
+ 4
+
+ "4"
+
+
+ stPrefix
+
+
+
+ 5
+
+ "5"
+
+
+ stPrefix
+ b
+
+
+ 51
+
+ "51"
+
+
+ stPrefix
+
+
+
+ 53
+
+ "53"
+
+
+ stPrefix
+ _
+
+
+ 54
+
+ "54"
+
+
+ stPrefix
+ _
+
+
+ 55
+
+ "55"
+
+
+ stPrefix
+ _
+
+
+ 56
+
+ "56"
+
+
+ stPrefix
+
+
+
+ 57
+
+ "57"
+
+
+ stPrefix
+
+
+
+ 58
+
+ "58"
+
+
+ stPrefix
+
+
+
+ 59
+
+ "59"
+
+
+ stPrefix
+
+
+
+ 6
+
+ "6"
+
+
+ stPrefix
+ w
+
+
+ 61
+
+ "61"
+
+
+ stPrefix
+
+
+
+ 62
+
+ "62"
+
+
+ stPrefix
+
+
+
+ 63
+
+ "63"
+
+
+ stPrefix
+
+
+
+ 64
+
+ "64"
+
+
+ stPrefix
+
+
+
+ 65
+
+ "65"
+
+
+ stPrefix
+
+
+
+ 7
+
+ "7"
+
+
+ stPrefix
+ dw
+
+
+ 70
+
+ "70"
+
+
+ stPrefix
+
+
+
+ 71
+
+ "71"
+
+
+ stPrefix
+
+
+
+ 72
+
+ "72"
+
+
+ stPrefix
+
+
+
+ 73
+
+ "73"
+
+
+ stPrefix
+
+
+
+ 8
+
+ "8"
+
+
+ stPrefix
+ lw
+
+
+ 9
+
+ "9"
+
+
+ stPrefix
+ usi
+
+
+
+
+
+ NamingConventionsSettings
+
+ "NamingConventionsSettings"
+
+
+ CombinedDataTypesRecursive
+ True
+ CombineScopeWithDatatypePrefix
+ True
+ FirstCharUpperCase
+ True
+
+
+ Rules
+
+ "Rules"
+
+ 1
+
+ "1"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 10
+
+ "10"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 100
+
+ "100"
+
+
+ bActive
+ false
+ bWarning
+ true
+ nUpperLimit
+ 1024
+
+
+ 101
+
+ "101"
+
+
+ bActive
+ false
+ bWarning
+ false
+ Exceptions
+ ""
+ MaxChars
+ 30
+ MinChars
+ 5
+
+
+ 102
+
+ "102"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 103
+
+ "103"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 105
+
+ "105"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 106
+
+ "106"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 107
+
+ "107"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 11
+
+ "11"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 111
+
+ "111"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 112
+
+ "112"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 113
+
+ "113"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 114
+
+ "114"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 115
+
+ "115"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 117
+
+ "117"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 118
+
+ "118"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 119
+
+ "119"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 12
+
+ "12"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 120
+
+ "120"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 121
+
+ "121"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 122
+
+ "122"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 123
+
+ "123"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 124
+
+ "124"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 125
+
+ "125"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 13
+
+ "13"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 130
+
+ "130"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 133
+
+ "133"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 134
+
+ "134"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 14
+
+ "14"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 140
+
+ "140"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 145
+
+ "145"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 147
+
+ "147"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 148
+
+ "148"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 15
+
+ "15"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 150
+
+ "150"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 16
+
+ "16"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 160
+
+ "160"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 161
+
+ "161"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 162
+
+ "162"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 163
+
+ "163"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 164
+
+ "164"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 166
+
+ "166"
+
+
+ bActive
+ false
+ bWarning
+ false
+ MaxInOuts
+ 10
+ MaxInputs
+ 10
+ MaxOutputs
+ 10
+
+
+ 167
+
+ "167"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 168
+
+ "168"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 169
+
+ "169"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 17
+
+ "17"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 170
+
+ "170"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 171
+
+ "171"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 172
+
+ "172"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 175
+
+ "175"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 178
+
+ "178"
+
+
+ bActive
+ false
+ bWarning
+ true
+ nCognitiveComplexityLimit
+ 20
+
+
+ 179
+
+ "179"
+
+
+ bActive
+ true
+ bWarning
+ false
+ nCouplingLimit
+ 30
+
+
+ 18
+
+ "18"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 180
+
+ "180"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 19
+
+ "19"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 2
+
+ "2"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 20
+
+ "20"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 21
+
+ "21"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 22
+
+ "22"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 23
+
+ "23"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 24
+
+ "24"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 25
+
+ "25"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 26
+
+ "26"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 27
+
+ "27"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 28
+
+ "28"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 29
+
+ "29"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 3
+
+ "3"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 31
+
+ "31"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 32
+
+ "32"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 33
+
+ "33"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 34
+
+ "34"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 35
+
+ "35"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 36
+
+ "36"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 37
+
+ "37"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 38
+
+ "38"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 39
+
+ "39"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 4
+
+ "4"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 40
+
+ "40"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 41
+
+ "41"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 42
+
+ "42"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 43
+
+ "43"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 44
+
+ "44"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 46
+
+ "46"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 47
+
+ "47"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 48
+
+ "48"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 5
+
+ "5"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 51
+
+ "51"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 52
+
+ "52"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 53
+
+ "53"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 54
+
+ "54"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 55
+
+ "55"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 56
+
+ "56"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 57
+
+ "57"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 58
+
+ "58"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 59
+
+ "59"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 6
+
+ "6"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 60
+
+ "60"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 61
+
+ "61"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 62
+
+ "62"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 63
+
+ "63"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 64
+
+ "64"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 65
+
+ "65"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 66
+
+ "66"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 7
+
+ "7"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 72
+
+ "72"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 73
+
+ "73"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 75
+
+ "75"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 76
+
+ "76"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 77
+
+ "77"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 78
+
+ "78"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 8
+
+ "8"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 81
+
+ "81"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+ 9
+
+ "9"
+
+
+ bActive
+ False
+ bWarning
+ True
+
+
+ 90
+
+ "90"
+
+
+ bActive
+ False
+ bWarning
+ False
+
+
+ 95
+
+ "95"
+
+
+ bActive
+ True
+ bWarning
+ False
+
+
+
+
+
+
+
+ MaxStaticAnalysisErrors
+ 100U
+ MaxStaticAnalysisWarnings
+ 100U
+ PerformStaticAnalyse
+ true
+ SuppressedKeywords
+ ""
+
+
+ {40450F57-0AA3-4216-96F3-5444ECB29763}
+
+ "{40450F57-0AA3-4216-96F3-5444ECB29763}"
+
+
+ ActiveVisuProfile
+ IR0whWr8bwfyBwAAMxnWswAAAABVAgAADu3eawAAAAABAAAAAAAAAAEaUwB5AHMAdABlAG0ALgBTAHQAcgBpAG4AZwACTHsAZgA5ADUAYgBiADQAMgA2AC0ANQA1ADIANAAtADQAYgA0ADUALQA5ADQAMAAwAC0AZgBiADAAZgAyAGUANwA3AGUANQAxAGIAfQADCE4AYQBtAGUABDJUAHcAaQBuAEMAQQBUACAAMwAuADEAIABCAHUAaQBsAGQAIAA0ADAAMgA2AC4AMQA4AAUWUAByAG8AZgBpAGwAZQBEAGEAdABhAAZMewAxADYAZQA1ADUAYgA2ADAALQA3ADAANAAzAC0ANABhADYAMwAtAGIANgA1AGIALQA2ADEANAA3ADEAMwA4ADcAOABkADQAMgB9AAcSTABpAGIAcgBhAHIAaQBlAHMACEx7ADMAYgBmAGQANQA0ADUAOQAtAGIAMAA3AGYALQA0AGQANgBlAC0AYQBlADEAYQAtAGEAOAAzADMANQA2AGEANQA1ADEANAAyAH0ACUx7ADkAYwA5ADUAOAA5ADYAOAAtADIAYwA4ADUALQA0ADEAYgBiAC0AOAA4ADcAMQAtADgAOQA1AGYAZgAxAGYAZQBkAGUAMQBhAH0ACg5WAGUAcgBzAGkAbwBuAAsGaQBuAHQADApVAHMAYQBnAGUADQpUAGkAdABsAGUADhpWAGkAcwB1AEUAbABlAG0ATQBlAHQAZQByAA8OQwBvAG0AcABhAG4AeQAQDFMAeQBzAHQAZQBtABESVgBpAHMAdQBFAGwAZQBtAHMAEjBWAGkAcwB1AEUAbABlAG0AcwBTAHAAZQBjAGkAYQBsAEMAbwBuAHQAcgBvAGwAcwATKFYAaQBzAHUARQBsAGUAbQBzAFcAaQBuAEMAbwBuAHQAcgBvAGwAcwAUJFYAaQBzAHUARQBsAGUAbQBUAGUAeAB0AEUAZABpAHQAbwByABUiVgBpAHMAdQBOAGEAdABpAHYAZQBDAG8AbgB0AHIAbwBsABYUVgBpAHMAdQBJAG4AcAB1AHQAcwAXGFYAaQBzAHUARQBsAGUAbQBCAGEAcwBlABgmRABlAHYAUABsAGEAYwBlAGgAbwBsAGQAZQByAHMAVQBzAGUAZAAZCGIAbwBvAGwAGiJQAGwAdQBnAGkAbgBDAG8AbgBzAHQAcgBhAGkAbgB0AHMAG0x7ADQAMwBkADUAMgBiAGMAZQAtADkANAAyAGMALQA0ADQAZAA3AC0AOQBlADkANAAtADEAYgBmAGQAZgAzADEAMABlADYAMwBjAH0AHBxBAHQATABlAGEAcwB0AFYAZQByAHMAaQBvAG4AHRRQAGwAdQBnAGkAbgBHAHUAaQBkAB4WUwB5AHMAdABlAG0ALgBHAHUAaQBkAB9IYQBmAGMAZAA1ADQANAA2AC0ANAA5ADEANAAtADQAZgBlADcALQBiAGIANwA4AC0AOQBiAGYAZgBlAGIANwAwAGYAZAAxADcAIBRVAHAAZABhAHQAZQBJAG4AZgBvACFMewBiADAAMwAzADYANgBhADgALQBiADUAYwAwAC0ANABiADkAYQAtAGEAMAAwAGUALQBlAGIAOAA2ADAAMQAxADEAMAA0AGMAMwB9ACIOVQBwAGQAYQB0AGUAcwAjTHsAMQA4ADYAOABmAGYAYwA5AC0AZQA0AGYAYwAtADQANQAzADIALQBhAGMAMAA2AC0AMQBlADMAOQBiAGIANQA1ADcAYgA2ADkAfQAkTHsAYQA1AGIAZAA0ADgAYwAzAC0AMABkADEANwAtADQAMQBiADUALQBiADEANgA0AC0ANQBmAGMANgBhAGQAMgBiADkANgBiADcAfQAlFk8AYgBqAGUAYwB0AHMAVAB5AHAAZQAmVFUAcABkAGEAdABlAEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwARgBvAHIAQwBvAG4AdgBlAHIAdABpAGIAbABlAEwAaQBiAHIAYQByAGkAZQBzACcQTABpAGIAVABpAHQAbABlACgUTABpAGIAQwBvAG0AcABhAG4AeQApHlUAcABkAGEAdABlAFAAcgBvAHYAaQBkAGUAcgBzACo4UwB5AHMAdABlAG0ALgBDAG8AbABsAGUAYwB0AGkAbwBuAHMALgBIAGEAcwBoAHQAYQBiAGwAZQArEnYAaQBzAHUAZQBsAGUAbQBzACwMcwB5AHMAdABlAG0ALUg2AGMAYgAxAGMAZABlADEALQBkADUAZABjAC0ANABhADMAYgAtADkAMAA1ADQALQAyADEAZgBhADcANQA2AGEAMwBmAGEANAAuKEkAbgB0AGUAcgBmAGEAYwBlAFYAZQByAHMAaQBvAG4ASQBuAGYAbwAvTHsAYwA2ADEAMQBlADQAMAAwAC0ANwBmAGIAOQAtADQAYwAzADUALQBiADkAYQBjAC0ANABlADMAMQA0AGIANQA5ADkANgA0ADMAfQAwGE0AYQBqAG8AcgBWAGUAcgBzAGkAbwBuADEYTQBpAG4AbwByAFYAZQByAHMAaQBvAG4AMgxMAGUAZwBhAGMAeQAzMEwAYQBuAGcAdQBhAGcAZQBNAG8AZABlAGwAVgBlAHIAcwBpAG8AbgBJAG4AZgBvADQwTABvAGEAZABMAGkAYgByAGEAcgBpAGUAcwBJAG4AdABvAFAAcgBvAGoAZQBjAHQANRpDAG8AbQBwAGEAdABpAGIAaQBsAGkAdAB5ANAAAhoD0AMBLQTQBQYaB9AHCBoBRQcJCNAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0O0A8BLRDQAAkaBEUKCwQEAAAACAAAAAAAAAAAAAAA0AwLrQEAAADQDQEtEdAPAS0Q0AAJGgRFCgsEBAAAAAcAAAAAAAAAAAAAANAMC60CAAAA0A0BLRLQDwEtENAACRoERQoLBAQAAAAIAAAAAAAAAAAAAADQDAutAgAAANANAS0T0A8BLRDQAAkaBEUKCwQEAAAACAAAAAAAAAAAAAAA0AwLrQIAAADQDQEtFNAPAS0Q0AAJGgRFCgsEBAAAAAgAAAAAAAAAAAAAANAMC60CAAAA0A0BLRXQDwEtENAACRoERQoLBAQAAAAHAAAAAAAAAAAAAADQDAutAgAAANANAS0W0A8BLRDQAAkaBEUKCwQEAAAACAAAAAAAAAAAAAAA0AwLrQQAAADQDQEtF9APAS0Q0BgZrQFFGhsB0AAbGgJFHAsEBAAAAAIAAAAAAAAAAAAAANAdHi0f0CAhGgJFIiMC0AAkGgVFCgsEAwAAAAMAAAAAAAAACgAAANAlC60AAAAA0AMBLSbQJwEtEdAoAS0Q0AAkGgVFCgsEAwAAAAMAAAAAAAAACgAAANAlC60BAAAA0AMBLSbQJwEtEdAoAS0QmikqAUUAAQLQAAEtK9AAAS0s0AAeLS3QLi8aA9AwC60BAAAA0DELrSQAAADQMhmtANAzLxoD0DALrQIAAADQMQutBgAAANAyGa0A0DQZrQDQNRmtAA==
+
+
+ {8A0FB252-96EB-4DCC-A5B4-B4804D05E2D6}
+
+ "{8A0FB252-96EB-4DCC-A5B4-B4804D05E2D6}"
+
+
+ WriteLineIDs
+ False
+
+
+ {8F99A816-E488-41E4-9FA3-846536012284}
+
+ "{8F99A816-E488-41E4-9FA3-846536012284}"
+
+
+ DisabledWarningIds
+ 410,5410
+
+
+ {F66C7017-BDD8-4114-926C-81D6D687E35F}
+
+ "{F66C7017-BDD8-4114-926C-81D6D687E35F}"
+
+
+ CalcActiveTransOnly
+ True
+
+
+
+
+
+
+
+ System.Boolean
+ System.Collections.Hashtable
+ System.Int32
+ {54dd0eac-a6d8-46f2-8c27-2f43c7e49861}
+ System.String
+ System.UInt32
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Analog/FB_AnalogInput.TcPOU b/BasicComponents/POUs/Components/Analog/FB_AnalogInput.TcPOU
new file mode 100644
index 0000000..1aeda2a
--- /dev/null
+++ b/BasicComponents/POUs/Components/Analog/FB_AnalogInput.TcPOU
@@ -0,0 +1,584 @@
+
+
+
+
+
+ = _rMaxErrorLevel),
+ xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError),
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stAnalogEWConfig.stDelays.timErrorHighOn,
+ timOffDelay:= stAnalogEWConfig.stDelays.timErrorHighOff,
+ xInUnitTestMode:= xInUnitTestMode);
+
+_xErrorHigh := _fbAlarmErrorHigh.Triggered;
+
+// Latch error
+IF _xErrorHigh THEN
+ _xError := TRUE;
+END_IF
+
+
+// ===========================
+// Error low alarm handling
+// ===========================
+
+_fbAlarmErrorLow(
+ xActive:= (_rScaledValue <= _rMinErrorLevel),
+ xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError),
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stAnalogEWConfig.stDelays.timErrorLowOn,
+ timOffDelay:= stAnalogEWConfig.stDelays.timErrorLowOff,
+ xInUnitTestMode:= xInUnitTestMode);
+
+_xErrorLow := _fbAlarmErrorLow.Triggered;
+
+// Latch error
+IF _xErrorLow THEN
+ _xError := TRUE;
+END_IF
+
+
+// ===========================
+// Warning high alarm handling
+// ===========================
+
+_fbAlarmWarningHigh(
+ xActive:= (_rScaledValue >= _rMaxWarningLevel),
+ xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError),
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stAnalogEWConfig.stDelays.timWarningHighOn,
+ timOffDelay:= stAnalogEWConfig.stDelays.timWarningHighOff,
+ xInUnitTestMode:= xInUnitTestMode);
+
+_xWarningHigh := _fbAlarmWarningHigh.Triggered;
+
+
+// ===========================
+// Warning low alarm handling
+// ===========================
+
+_fbAlarmWarningLow(
+ xActive:= (_rScaledValue <= _rMinWarningLevel),
+ xRelease:= stAnalogIOConfig.xUsed AND xReleaseErrors AND xReleaseLimitErrors AND (NOT _xEWConfigError),
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stAnalogEWConfig.stDelays.timWarningLowOn,
+ timOffDelay:= stAnalogEWConfig.stDelays.timWarningLowOff,
+ xInUnitTestMode:= xInUnitTestMode);
+
+_xWarningLow := _fbAlarmWarningLow.Triggered;
+
+
+// ============
+// Warning flag
+// ============
+
+_xWarning := _xWarningLow OR _xWarningHigh;
+
+
+// ================
+// Reset error flag
+// ================
+
+_xAlarmsActive := _fbAlarmConfigError.Active
+ OR _fbAlarmUnderrange.Active
+ OR _fbAlarmOverload.Active
+ OR _fbAlarmCardError.Active
+ OR _fbAlarmErrorHigh.Active
+ OR _fbAlarmErrorLow.Active;
+
+_xInputErrorsActive := _fbAlarmUnderrange.Triggered
+ OR _fbAlarmOverload.Triggered
+ OR _fbAlarmCardError.Triggered;
+
+IF xConfirmAlarms AND _xError AND (NOT _xAlarmsActive) AND (NOT _xInputErrorsActive) AND (NOT _xConfigError) THEN
+ _xError := FALSE;
+END_IF
+
+// ====================
+// Handle HMI interface
+// ====================
+
+HandleHMIOutput();
+
+
+// Copy internal signals to outputs
+xWarningLow := _xWarningLow;
+xWarningHigh := _xWarningHigh;
+xWarning := _xWarning;
+
+xErrorLow := _xErrorLow;
+xErrorHigh := _xErrorHigh;
+xError := _xError;
+
+rScaledValue := _rScaledValue;]]>
+
+
+
+
+ 0.0 THEN
+ _rConversionFactor := _rNum/_rDenom;
+ _rBaseOffset := stAnalogIOConfig.rPVMin - (_rConversionFactor * INT_TO_REAL(stAnalogIOConfig.iAIMin));
+ _iAIMax := stAnalogIOConfig.iAIMax;
+ _iAIMin := stAnalogIOConfig.iAIMin;
+ _xConfigError := FALSE;
+ELSE
+ // Division by zero happened
+ // Or denom was negative
+ // Set scaling to zero
+ _rConversionFactor := 0.0;
+ _rBaseOffset := 0.0;
+ _iAIMax := 0;
+ _iAIMin := 0;
+ _xConfigError := TRUE;
+END_IF]]>
+
+
+
+
+
+ = stAnalogEWConfig.stLevels.rErrorMax THEN
+ _xEWConfigError := TRUE;
+END_IF
+
+IF stAnalogEWConfig.stLevels.rWarningMin >= stAnalogEWConfig.stLevels.rWarningMax THEN
+ _xEWConfigError := TRUE;
+END_IF
+
+
+// Only write error and warning levels when there was no config error
+IF (NOT _xEWConfigError) THEN
+ // Recreate alarm messages with the newly set limits
+ // if values have been changed
+ {analysis -54}
+ IF (_rMinErrorLevel <> stAnalogEWConfig.stLevels.rErrorMin)
+ OR (_rMinWarningLevel <> stAnalogEWConfig.stLevels.rWarningMin)
+ OR (_rMaxWarningLevel <> stAnalogEWConfig.stLevels.rWarningMax)
+ OR (_rMaxErrorLevel <> stAnalogEWConfig.stLevels.rErrorMax) THEN
+ {analysis +54}
+ CreateAlarmLimitsMSG();
+ END_IF
+
+ // Set new values
+ _rMinErrorLevel := stAnalogEWConfig.stLevels.rErrorMin;
+ _rMinWarningLevel := stAnalogEWConfig.stLevels.rWarningMin;
+ _rMaxWarningLevel := stAnalogEWConfig.stLevels.rWarningMax;
+ _rMaxErrorLevel := stAnalogEWConfig.stLevels.rErrorMax;
+END_IF
+]]>
+
+
+
+
+
+ '' THEN
+ _sTempUnit := CONCAT(' ', stAnalogIOConfig.sUnit);
+ELSE
+ _sTempUnit := '';
+END_IF
+
+// Create message parameter strings
+_sTempErrorMin := CONCAT(REAL_TO_STRING(stAnalogEWConfig.stLevels.rErrorMin), _sTempUnit);
+_sTempWarningMin := CONCAT(REAL_TO_STRING(stAnalogEWConfig.stLevels.rWarningMin), _sTempUnit);
+_sTempWarningMax := CONCAT(REAL_TO_STRING(stAnalogEWConfig.stLevels.rWarningMax), _sTempUnit);
+_sTempErrorMax := CONCAT(REAL_TO_STRING(stAnalogEWConfig.stLevels.rErrorMax), _sTempUnit);
+
+{analysis -46}
+// Inser message parameters
+_fbAlarmErrorLow.Arguments.Clear().AddString(_sName).AddString(_sTempErrorMin);
+_fbAlarmWarningLow.Arguments.Clear().AddString(_sName).AddString(_sTempWarningMin);
+_fbAlarmWarningHigh.Arguments.Clear().AddString(_sName).AddString(_sTempWarningMax);
+_fbAlarmErrorHigh.Arguments.Clear().AddString(_sName).AddString(_sTempErrorMax);
+{analysis +46}]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Analog/FB_AnalogOutput.TcPOU b/BasicComponents/POUs/Components/Analog/FB_AnalogOutput.TcPOU
new file mode 100644
index 0000000..721f1b4
--- /dev/null
+++ b/BasicComponents/POUs/Components/Analog/FB_AnalogOutput.TcPOU
@@ -0,0 +1,237 @@
+
+
+
+
+
+
+
+
+
+
+ 0.0 THEN
+ _rConversionFactor := _rNum/_rDenom;
+ _rBaseOffset := INT_TO_REAL(stAnalogIOConfig.iAIMin) - (_rConversionFactor * stAnalogIOConfig.rPVMin);
+ _rPVMax := stAnalogIOConfig.rPVMax;
+ _rPVMin := stAnalogIOConfig.rPVMin;
+ _xConfigError := FALSE;
+ELSE
+ // Division by zero happened
+ // Or denom was negative
+ // Set scaling to zero
+ _rConversionFactor := 0.0;
+ _rBaseOffset := 0.0;
+ _rPVMax := 0.0;
+ _rPVMin := 0.0;
+ _xConfigError := TRUE;
+END_IF]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT
new file mode 100644
index 0000000..6714166
--- /dev/null
+++ b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_CONFIG.TcDUT
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT
new file mode 100644
index 0000000..a683407
--- /dev/null
+++ b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_DELAYS.TcDUT
@@ -0,0 +1,31 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT
new file mode 100644
index 0000000..34f5a6c
--- /dev/null
+++ b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_EW_LEVELS.TcDUT
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT
new file mode 100644
index 0000000..19f4b77
--- /dev/null
+++ b/BasicComponents/POUs/Components/Analog/Types/ST_ANALOG_IO_CONFIG.TcDUT
@@ -0,0 +1,33 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/EventListener/FB_EventListener.TcPOU b/BasicComponents/POUs/Components/EventListener/FB_EventListener.TcPOU
new file mode 100644
index 0000000..19715ea
--- /dev/null
+++ b/BasicComponents/POUs/Components/EventListener/FB_EventListener.TcPOU
@@ -0,0 +1,334 @@
+
+
+
+
+
+ 0 THEN
+ {analysis -19}
+ _fbBuffer.A_RemoveHead(pRead:= ADR(_stBufferEventEntryFromBuffer),
+ cbRead:= SIZEOF(_stBufferEventEntryFromBuffer),
+ pBuffer:= ADR(_abAlarmBuffer),
+ cbBuffer:= SIZEOF(_abAlarmBuffer),
+ bOk=> _xSuccess,
+ nCount => _udiCurrentEntries);
+ {analysis +19}
+ IF _xSuccess THEN
+ _uiState := 10;
+ END_IF
+END_IF
+
+CASE _uiState OF
+ 0: // Idle
+
+ 10: // Get alarm text
+ _xGetTextDone := _stBufferEventEntryFromBuffer.fbAlarm.RequestEventText(
+ nLangId := 1033,
+ sResult := _sLastMessageText,
+ nResultSize := SIZEOF(_sLastMessageText),
+ bError => _xGetTextError);
+
+ IF _xGetTextError THEN
+ _sLastMessageText := '';
+ _uiState := 20;
+ ELSIF _xGetTextDone THEN
+ _uiState := 20;
+ END_IF
+
+ 20: // Create mqtt message
+ CreateMessage();
+ _uiState := 0;
+
+ ELSE
+ // Do nothing
+ ;
+END_CASE]]>
+
+
+
+
+ _xOk,
+ nCount => _udiCurrentEntries);
+{analysis +19}
+
+AddAlarmToQueue := _xOk;
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/EventListener/Types/E_EventType.TcDUT b/BasicComponents/POUs/Components/EventListener/Types/E_EventType.TcDUT
new file mode 100644
index 0000000..d7ccfed
--- /dev/null
+++ b/BasicComponents/POUs/Components/EventListener/Types/E_EventType.TcDUT
@@ -0,0 +1,17 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/EventListener/Types/ST_BufferEventEntry.TcDUT b/BasicComponents/POUs/Components/EventListener/Types/ST_BufferEventEntry.TcDUT
new file mode 100644
index 0000000..c8db92e
--- /dev/null
+++ b/BasicComponents/POUs/Components/EventListener/Types/ST_BufferEventEntry.TcDUT
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Motor/FB_MotorBecker.TcPOU b/BasicComponents/POUs/Components/Motor/FB_MotorBecker.TcPOU
new file mode 100644
index 0000000..01c9dab
--- /dev/null
+++ b/BasicComponents/POUs/Components/Motor/FB_MotorBecker.TcPOU
@@ -0,0 +1,497 @@
+
+
+
+
+
+ _rSetpoint,
+ xInTarget=> _xRampGenInTarget);
+
+// Calculate target tolerance
+_rPVTargetMax := _rSetpoint + stMotorConfig.rTargetTolerance;
+_rPVTargetMin := _rSetpoint - stMotorConfig.rTargetTolerance;
+
+
+// =============
+// Handle alarms
+// =============
+
+_fbMCBTrippedDelayedSignal(
+ xSignal:= (NOT xMCBOk),
+ xRelease:= stMotorConfig.xHasMCBFeedback AND xReleaseErrors,
+ timOnDelay:= ,
+ timOffDelay:= ,
+ xReleaseSignal=> );
+
+
+// ================
+// Reset error flag
+// ================
+
+
+// ================================
+// Copy internal signals to outputs
+// ================================
+
+udiControlword := DWORD_TO_UDINT(_dwControlword);
+xError := _xError;
+
+// ==================
+// Handle HMI outputs
+// ==================]]>
+
+
+
+
+ 0 THEN
+ _xProcessINTLKOk := FALSE;
+END_IF
+
+// Check safety interlocks
+// Safety interlocks will not automatically reset
+// They need to be reset via the xConfirmAlarms input
+IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN
+ _xSafetyINTLKOk := FALSE;
+END_IF]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT b/BasicComponents/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT
new file mode 100644
index 0000000..501c906
--- /dev/null
+++ b/BasicComponents/POUs/Components/Motor/Types/ST_MOTOR_BECKER_CONFIG.TcDUT
@@ -0,0 +1,50 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Utilities/FB_AlarmMessage.TcPOU b/BasicComponents/POUs/Components/Utilities/FB_AlarmMessage.TcPOU
new file mode 100644
index 0000000..c990f8a
--- /dev/null
+++ b/BasicComponents/POUs/Components/Utilities/FB_AlarmMessage.TcPOU
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Utilities/FB_Blinker.TcPOU b/BasicComponents/POUs/Components/Utilities/FB_Blinker.TcPOU
new file mode 100644
index 0000000..0fbf8b4
--- /dev/null
+++ b/BasicComponents/POUs/Components/Utilities/FB_Blinker.TcPOU
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Utilities/FB_RampGenerator.TcPOU b/BasicComponents/POUs/Components/Utilities/FB_RampGenerator.TcPOU
new file mode 100644
index 0000000..5983a0e
--- /dev/null
+++ b/BasicComponents/POUs/Components/Utilities/FB_RampGenerator.TcPOU
@@ -0,0 +1,132 @@
+
+
+
+
+
+ T#0S THEN
+ _rRampUpSpeed := (rTargetMax - rTargetMin) * (_rCycleTime / TIME_TO_REAL(timRampUp));
+ELSE
+ _rRampUpSpeed := rTargetMax;
+END_IF
+IF timRampDown <> T#0S THEN
+ _rRampDownSpeed := -(rTargetMax - rTargetMin) * (_rCycleTime / TIME_TO_REAL(timRampDown));
+ELSE
+ _rRampDownSpeed := -rTargetMax;
+END_IF
+
+
+// Calculate distance left to go
+_rDistanceToGo := rTarget - rSetpoint;
+
+// Calculate new setpoint
+IF (_rDistanceToGo > 0.0) THEN
+ IF (_rDistanceToGo > _rRampUpSpeed) THEN
+ rSetpoint := rSetpoint + _rRampUpSpeed;
+ ELSE
+ rSetpoint := rTarget;
+ END_IF
+ELSIF (_rDistanceToGo < 0.0) THEN
+ IF (_rDistanceToGo < _rRampDownSpeed) THEN
+ rSetpoint := rSetpoint + _rRampDownSpeed;
+ ELSE
+ rSetpoint := rTarget;
+ END_IF
+ELSE
+ rSetpoint := rTarget;
+END_IF
+
+// Check if we are in range of target range
+IF ABS(rSetpoint-rTarget) <= 0.001 THEN
+ xInTarget := TRUE;
+ELSE
+ xInTarget := FALSE;
+END_IF ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Utilities/FB_ReleaseSignal.TcPOU b/BasicComponents/POUs/Components/Utilities/FB_ReleaseSignal.TcPOU
new file mode 100644
index 0000000..5b916fa
--- /dev/null
+++ b/BasicComponents/POUs/Components/Utilities/FB_ReleaseSignal.TcPOU
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU b/BasicComponents/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU
new file mode 100644
index 0000000..9624e5d
--- /dev/null
+++ b/BasicComponents/POUs/Components/Utilities/FC_HashFNV1a_32Bit.TcPOU
@@ -0,0 +1,34 @@
+
+
+
+
+
+ 0 DO
+ _udiHash := (_udiHash XOR BYTE_TO_UDINT(psKey^[_uiCounter])) * udiPrime;
+ _uiCounter := _uiCounter + 1;
+END_WHILE
+
+// Return calculated Hash
+FC_HashFNV1a_32Bit := _udiHash;]]>
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Valves/FB_Valve.TcPOU b/BasicComponents/POUs/Components/Valves/FB_Valve.TcPOU
new file mode 100644
index 0000000..7360b4c
--- /dev/null
+++ b/BasicComponents/POUs/Components/Valves/FB_Valve.TcPOU
@@ -0,0 +1,520 @@
+
+
+
+
+
+ stValveConfig.xNormallyOpen) THEN
+ _xManualOpen := stValveConfig.xNormallyOpen;
+ END_IF
+END_IF
+
+// Handle open close feedback
+_xIsOpen := (stValveConfig.xHasOpenFeedback AND xOpenFeedback AND (NOT xCloseFeedback)) OR ((NOT stValveConfig.xHasOpenFeedback) AND _xOpenValve);
+_xIsClosed := (stValveConfig.xHasClosedFeedback AND xCloseFeedback AND (NOT xOpenFeedback)) OR ((NOT stValveConfig.xHasClosedFeedback) AND (NOT _xOpenValve));
+
+
+// ===========================
+// Valve did not open in time
+// ===========================
+
+_fbAlarmDidNotOpen(
+ xActive:= _xOpenValve AND (NOT _xIsOpen),
+ xRelease:= xReleaseErrors,
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stValveConfig.timTimeoutOpen,
+ timOffDelay:= T#0S,
+ xInUnitTestMode:= xInUnitTestMode);
+
+// Latch error signal
+IF _fbAlarmDidNotOpen.Triggered THEN
+ _xError := TRUE;
+END_IF
+
+
+// ===========================
+// Valve did not close in time
+// ===========================
+
+_fbAlarmDidNotClose(
+ xActive:= (NOT _xOpenValve) AND (NOT _xIsClosed),
+ xRelease:= xReleaseErrors,
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stValveConfig.timTimeoutClose,
+ timOffDelay:= T#0S,
+ xInUnitTestMode:= xInUnitTestMode);
+
+// Latch error signal
+IF _fbAlarmDidNotClose.Triggered THEN
+ _xError := TRUE;
+END_IF
+
+
+// ================
+// Reset error flag
+// ================
+
+_xAlarmsActive := _fbAlarmDidNotOpen.Active OR _fbAlarmDidNotClose.Active;
+_xInputErrorsActive := _fbAlarmDidNotOpen.Triggered OR _fbAlarmDidNotClose.Triggered;
+
+IF xConfirmAlarms AND _xError AND (NOT _xAlarmsActive) AND (NOT _xInputErrorsActive) THEN
+ _xError := FALSE;
+END_IF
+
+
+// ================================
+// Copy internal signals to outputs
+// ================================
+
+xOpenValve := _xOpenValve;
+xCloseValve := (NOT _xOpenValve);
+
+xError := _xError;
+
+
+// ==================
+// Handle HMI outputs
+// ==================
+
+HandleHMIOutput();]]>
+
+
+
+
+ 0 THEN
+ _xProcessINTLKOk := FALSE;
+END_IF
+
+// Check safety interlocks
+// Safety interlocks will not automatically reset
+// They need to be reset via the xConfirmAlarms input
+IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN
+ _xSafetyINTLKOk := FALSE;
+END_IF]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Valves/FB_ValveAnalog.TcPOU b/BasicComponents/POUs/Components/Valves/FB_ValveAnalog.TcPOU
new file mode 100644
index 0000000..2d6372a
--- /dev/null
+++ b/BasicComponents/POUs/Components/Valves/FB_ValveAnalog.TcPOU
@@ -0,0 +1,689 @@
+
+
+
+
+
+ iSetpoint,
+ xError => _xAnalogOutputError,
+ stHMIInterface:= stHMIInterface.stSetpoint);
+
+IF _fbAnalogOutput.xError THEN
+ _xError := TRUE;
+END_IF
+
+// ===================
+// Handle analog input
+// ===================
+
+IF stValveConfig.xHasAnalogFeedback THEN
+ stValveConfig.stAnalogInputConfig.xUsed := TRUE;
+ELSE
+ stValveConfig.stAnalogInputConfig.xUsed := FALSE;
+END_IF
+
+_fbAnalogInput(
+ iAnalogValue:= iFeedbackValue,
+ xUnderrange:= _xHasUnderrangeFeedback AND xFeedbackUnderrange,
+ xOverrange:= _xHasOverrangeFeedback AND xFeedbackOverrange,
+ xErrorCard:= _xHasCardError AND xErrorCard,
+ stAnalogIOConfig:= stValveConfig.stAnalogInputConfig,
+ stAnalogEWConfig:= stValveConfig.stAnalogInputEWConfig,
+ xReleaseErrors:= xReleaseErrors,
+ xReleaseLimitErrors:= FALSE,
+ xReleaseHardwareErrors:= TRUE,
+ xInUnitTestMode := xInUnitTestMode,
+ xConfirmAlarms:= xConfirmAlarms,
+ rScaledValue=> _rCurrentValvePosition,
+ xError=> _xAnalogInputError,
+ xWarning=> _xWarningAnalogInput,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+IF _fbAnalogInput.xError THEN
+ _xError := TRUE;
+END_IF
+
+IF NOT stValveConfig.xHasAnalogFeedback THEN
+ _rCurrentValvePosition := _rSetpoint;
+END_IF
+
+
+// Handle open close feedback
+_xIsOpen := (stValveConfig.xHasOpenFeedback AND xOpenFeedback AND (NOT xCloseFeedback)) OR ((NOT stValveConfig.xHasOpenFeedback) AND (_rCurrentValvePosition >= stValveConfig.rPVIsOpen));
+_xIsClosed := (stValveConfig.xHasClosedFeedback AND xCloseFeedback AND (NOT xOpenFeedback)) OR ((NOT stValveConfig.xHasClosedFeedback) AND (_rCurrentValvePosition <= stValveConfig.rPVIsOpen));
+
+
+// Calculate target tolerance
+_rPVTargetMax := _rSetpoint + stValveConfig.rTargetTolerance;
+_rPVTargetMin := _rSetpoint - stValveConfig.rTargetTolerance;
+
+// Check if valve position is in target
+_xNotInRange := stValveConfig.xHasAnalogFeedback AND ((_rCurrentValvePosition < _rPVTargetMin) OR (_rCurrentValvePosition > _rPVTargetMax));
+
+// ==================
+// Not in range alarm
+// ==================
+
+_fbAlarmNotInRange(
+ xActive:= _xNotInRange,
+ xRelease:= xReleaseErrors,
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stValveConfig.timNotInRange,
+ timOffDelay:= T#0S,
+ xInUnitTestMode:= xInUnitTestMode);
+
+// Latch error signal
+IF _fbAlarmNotInRange.Triggered THEN
+ _xError := TRUE;
+END_IF
+
+
+// ===========================
+// Valve did not open in time
+// ===========================
+
+_fbAlarmDidNotOpen(
+ xActive:= _xOpenValve AND (NOT _xIsOpen),
+ xRelease:= xReleaseErrors,
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stValveConfig.timTimeoutOpen,
+ timOffDelay:= T#0S,
+ xInUnitTestMode:= xInUnitTestMode);
+
+// Latch error signal
+IF _fbAlarmDidNotOpen.Triggered THEN
+ _xError := TRUE;
+END_IF
+
+
+// ===========================
+// Valve did not close in time
+// ===========================
+
+_fbAlarmDidNotClose(
+ xActive:= (NOT _xOpenValve) AND (NOT _xIsClosed),
+ xRelease:= xReleaseErrors,
+ xAcknowledge:= xConfirmAlarms,
+ timOnDelay:= stValveConfig.timTimeoutClose,
+ timOffDelay:= T#0S,
+ xInUnitTestMode:= xInUnitTestMode);
+
+// Latch error signal
+IF _fbAlarmDidNotClose.Triggered THEN
+ _xError := TRUE;
+END_IF
+
+
+// ================
+// Reset error flag
+// ================
+
+_xAlarmsActive := _fbAlarmDidNotOpen.Active OR _fbAlarmDidNotClose.Active OR _fbAlarmNotInRange.Raised OR _xAnalogInputError OR _xAnalogOutputError;
+_xInputErrorsActive := _fbAlarmDidNotOpen.Triggered OR _fbAlarmDidNotClose.Triggered OR _fbAlarmNotInRange.Triggered;
+
+IF xConfirmAlarms AND _xError AND (NOT _xAlarmsActive) AND (NOT _xInputErrorsActive) THEN
+ _xError := FALSE;
+END_IF
+
+
+// ================================
+// Copy internal signals to outputs
+// ================================
+
+xError := _xError;
+
+
+// ==================
+// Handle HMI outputs
+// ==================
+
+HandleHMIOutput();]]>
+
+
+
+
+ 0 THEN
+ _xProcessINTLKOk := FALSE;
+END_IF
+
+// Check safety interlocks
+// Safety interlocks will not automatically reset
+// They need to be reset via the xConfirmAlarms input
+IF ((wSafetyINTLK AND wSafetyINTLKUsed) XOR wSafetyINTLKUsed) > 0 THEN
+ _xSafetyINTLKOk := FALSE;
+END_IF]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT b/BasicComponents/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT
new file mode 100644
index 0000000..6c2d13c
--- /dev/null
+++ b/BasicComponents/POUs/Components/Valves/Types/ST_ValveAnalogConfig.TcDUT
@@ -0,0 +1,60 @@
+
+
+
+ =5%
+ {attribute 'OPC.UA.DA' := '1'}
+ rPVIsOpen : REAL := 5.0;
+
+ // Maximum allowable difference between setpoint and process value
+ // Defaults to +-5
+ {attribute 'OPC.UA.DA' := '1'}
+ rTargetTolerance : REAL := 5.0;
+
+ // Time for the valve to get to the requested setpoint
+ {attribute 'OPC.UA.DA' := '1'}
+ timNotInRange : TIME := T#30S;
+
+ // Config parameters for the analog input
+ stAnalogInputConfig : ST_ANALOG_IO_CONFIG := (iAIMax := 32767, iAIMin := 0, rPVMax := 100, rPVMin := 0);
+ stAnalogInputEWConfig : ST_ANALOG_EW_CONFIG;
+
+ // Config parameters for the analog output
+ stAnalogOutputConfig : ST_ANALOG_IO_CONFIG := (iAIMax := 32767, iAIMin := 0, rPVMax := 100, rPVMin := 0);
+
+ // Timeout for the valve to open
+ // 0 = deactivated
+ {attribute 'OPC.UA.DA' := '1'}
+ timTimeoutOpen : TIME := T#0S;
+
+ // Timeout for the valve to close
+ // 0 = deactivated
+ {attribute 'OPC.UA.DA' := '1'}
+ timTimeoutClose : TIME := T#0S;
+
+ // Valve has open feedback signal
+ {attribute 'OPC.UA.DA' := '1'}
+ xHasOpenFeedback : BOOL;
+
+ // Valve has close feedback signal
+ {attribute 'OPC.UA.DA' := '1'}
+ xHasClosedFeedback : BOOL;
+
+ // Valve has analog feedback signal
+ {attribute 'OPC.UA.DA' := '1'}
+ xHasAnalogFeedback : BOOL;
+
+ // Set setpoint to use if interlocks are active
+ // defaults to 0
+ rSetpointWhenInterlocksActive : REAL := 0;
+
+ // Valve is used
+ {attribute 'OPC.UA.DA' := '1'}
+ xUsed : BOOL := TRUE;
+END_STRUCT
+END_TYPE
+]]>
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT b/BasicComponents/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT
new file mode 100644
index 0000000..ad97b0a
--- /dev/null
+++ b/BasicComponents/POUs/Components/Valves/Types/ST_ValveConfig.TcDUT
@@ -0,0 +1,35 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Constants/GVL_TYPE_CONST.TcGVL b/BasicComponents/POUs/Constants/GVL_TYPE_CONST.TcGVL
new file mode 100644
index 0000000..486713b
--- /dev/null
+++ b/BasicComponents/POUs/Constants/GVL_TYPE_CONST.TcGVL
@@ -0,0 +1,24 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/GVL/GVL_CONFIGS.TcGVL b/BasicComponents/POUs/GVL/GVL_CONFIGS.TcGVL
new file mode 100644
index 0000000..0372d33
--- /dev/null
+++ b/BasicComponents/POUs/GVL/GVL_CONFIGS.TcGVL
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT
new file mode 100644
index 0000000..00fbb33
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_MOTOR_DATA.TcDUT
@@ -0,0 +1,54 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT
new file mode 100644
index 0000000..f570dab
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALUE.TcDUT
@@ -0,0 +1,46 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT
new file mode 100644
index 0000000..1370b96
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ANALOG_VALVE_DATA.TcDUT
@@ -0,0 +1,54 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT
new file mode 100644
index 0000000..6666a42
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_CONTROL_BUTTON.TcDUT
@@ -0,0 +1,26 @@
+
+
+
+ PLC
+ // The HMI writes here to signal the plc
+ // that it wants to command this button
+ {attribute 'OPC.UA.DA' := '1'}
+ xRequest : BOOL;
+
+ // Signals if the Button can be used by the HMI (read only)
+ {attribute 'OPC.UA.DA' := '1'}
+ {attribute 'OPC.UA.DA.Access' := '1'}
+ xRelease : BOOL;
+
+ // Current state of the button (read only)
+ // 0 = none, 1 = active, 2 = pending, 3 = waring, 4 = error (Type int)
+ {attribute 'OPC.UA.DA' := '1'}
+ {attribute 'OPC.UA.DA.Access' := '1'}
+ eFeedback : E_HMI_BUTTON_FEEDBACK;
+END_STRUCT
+END_TYPE
+]]>
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT
new file mode 100644
index 0000000..41150af
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_INTEGER_VALUE.TcDUT
@@ -0,0 +1,46 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT
new file mode 100644
index 0000000..2b6ba3c
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_INTERLOCK.TcDUT
@@ -0,0 +1,50 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT
new file mode 100644
index 0000000..941f421
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_ORP_SENSOR_DATA.TcDUT
@@ -0,0 +1,47 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT
new file mode 100644
index 0000000..6237868
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/ST_HMI_VALVE_DATA.TcDUT
@@ -0,0 +1,49 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT b/BasicComponents/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT
new file mode 100644
index 0000000..15d4bad
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Datentypen/T_INTERLOCK.TcDUT
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT b/BasicComponents/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT
new file mode 100644
index 0000000..fb1f1dc
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Enum/E_HMI_ANALOG_VALUE_STATUS.TcDUT
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT b/BasicComponents/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT
new file mode 100644
index 0000000..0e731e4
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Enum/E_HMI_BUTTON_FEEDBACK.TcDUT
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Enum/E_HMI_MODE.TcDUT b/BasicComponents/POUs/HMI/Enum/E_HMI_MODE.TcDUT
new file mode 100644
index 0000000..ab57951
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Enum/E_HMI_MODE.TcDUT
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT b/BasicComponents/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT
new file mode 100644
index 0000000..47b13c7
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Enum/E_HMI_MOTOR_STATUS.TcDUT
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT b/BasicComponents/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT
new file mode 100644
index 0000000..c1d6d45
--- /dev/null
+++ b/BasicComponents/POUs/HMI/Enum/E_HMI_VALVE_STATUS.TcDUT
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/PRG_MAIN.TcPOU b/BasicComponents/POUs/PRG_MAIN.TcPOU
new file mode 100644
index 0000000..75b1bcd
--- /dev/null
+++ b/BasicComponents/POUs/PRG_MAIN.TcPOU
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/AITests/FB_AnalogInputTest.TcPOU b/BasicComponents/POUs/Unittests/AITests/FB_AnalogInputTest.TcPOU
new file mode 100644
index 0000000..d7dd316
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/AITests/FB_AnalogInputTest.TcPOU
@@ -0,0 +1,1636 @@
+
+
+
+
+
+
+
+
+
+
+ _xError,
+ rScaledValue=> );
+
+// assert results
+AssertTrue(Condition := _xError, Message:= 'No error thrown at warning max > error max');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xError,
+ rScaledValue=> );
+
+// assert result
+AssertTrue(Condition := _xError, Message:= 'No error thrown at warning min < error min');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xError,
+ rScaledValue=> _rResult);
+
+// assert results
+AssertTrue(_xError,'Expected error when trying to devide by zero');
+AssertEquals_REAL(Expected:= 0.0, Actual:= _rResult, Delta:= 0.0, Message:= 'Division by zero not correcty handled');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active');
+AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active');
+AssertTrue(Condition:= _xResultWarningHigh, Message:= 'Warning high is not active');
+AssertTrue(Condition:= _xResultErrorHigh, Message:= 'Error high is not active');
+
+// Check without active release signal
+_fbAI(
+ iAnalogValue:= 95,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= FALSE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active without active release signal');
+AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active without active release signal');
+AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active without active release signal');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active without active release signal');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+ELSE
+ _fbErrorHighOffTimer(IN := TRUE, PT := timOffTime);
+ _fbAIErrorHighOff(
+ iAnalogValue:= 50,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= TRUE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+END_IF
+
+// Wait for the delay time to be finished and check the signal level
+// Should be high until the delay time has passed
+IF _fbErrorHighOffTimer.Q THEN
+ _xErrorHighOffTestFinished := TRUE;
+ AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is still active after the delay time');
+ELSE
+ AssertTrue(Condition:= _xResultErrorHigh, Message:= 'Error high is not active before the delay time elapsed');
+ IF NOT _xResultErrorHigh THEN
+ _xErrorHighOffTestFinished := TRUE;
+ END_IF
+END_IF
+
+IF _xErrorHighOffTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+
+// assert results
+IF NOT _fbErrorHighOnTimer.Q THEN
+ AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active before the time');
+ _fbErrorLowOnTimer.IN := FALSE;
+ELSE
+ _xErrorHighOnTestFinished := TRUE;
+ AssertTrue(Condition:= _xResultErrorHigh, Message:= 'Error high is not active after the delay time');
+END_IF
+
+IF _xErrorHighOnTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh
+ );
+
+// assert results
+AssertTrue(Condition:= _xResultErrorLow, Message:= 'Error low is not active');
+AssertTrue(Condition:= _xResultWarningLow, Message:= 'Warning low is not active');
+AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active');
+
+// Error low without release
+_fbAI(
+ iAnalogValue:= 0,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= FALSE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh
+ );
+
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active with no active release signal');
+AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active with no active release signal');
+AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active with no active release signal');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active with no active release signal');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+ELSE
+ _fbErrorLowOffTimer(IN := TRUE, PT := timOffTime);
+ _fbAIErrorLowOff(
+ iAnalogValue:= 50,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= TRUE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+END_IF
+
+// Wait for the delay time to be finished and check the signal level
+// Should be high until the delay time has passed
+IF _fbErrorLowOffTimer.Q THEN
+ _xErrorLowOffTestFinished := TRUE;
+ AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is still active after the delay time');
+ELSE
+ AssertTrue(Condition:= _xResultErrorLow, Message:= 'Error low is not active before the delay time elapsed');
+ IF NOT _xResultErrorLow THEN
+ _xErrorLowOffTestFinished := TRUE;
+ END_IF
+END_IF
+
+IF _xErrorLowOffTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+
+// assert results
+IF NOT _fbErrorLowOnTimer.Q THEN
+ AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active before the time');
+ _fbErrorLowOnTimer.IN := FALSE;
+ELSE
+ _xErrorLowOnTestFinished := TRUE;
+ AssertTrue(Condition:= _xResultErrorLow, Message:= 'Error low is not active after the delay time');
+ AssertTrue(Condition:= _xResultWarningLow, Message:= 'Warning low is not active after the delay time');
+END_IF
+
+IF _xErrorLowOnTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ ,
+ xInUnitTestMode := TRUE,
+ rScaledValue=> _rResult);
+
+// Value should be between 72.49 und 72.52 -> Delta = 0,03
+AssertEquals_REAL(
+ Expected := rExpected,
+ Actual := _rResult,
+ Delta := 0.03,
+ Message := 'Analog value not correct');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+// assert result
+AssertTrue(_xResultError, 'Expected overrange error');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+END_IF
+
+// run AI cyclically until overrange error is supposed to be off
+_fbAIOverrangeOff(
+ iAnalogValue:= 50,
+ stAnalogIOConfig := _stAnalogInputConfig,
+ stAnalogEWConfig := _stAnalogEWConfig,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= ,
+ xReleaseErrors := TRUE,
+ xReleaseHardwareErrors := TRUE,
+ xReleaseLimitErrors:= TRUE,
+ xConfirmAlarms := TRUE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+// assert result depending on timer
+IF NOT _fbOverrangeOffTimer.Q THEN
+ AssertTrue(_xResultError, 'Overrange error is reset before expected time');
+ELSE
+ AssertFalse(_xResultError, 'Overrange error not reset on time');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+// assert result depending on timer
+IF NOT _fbOverrangeOnTimer.Q THEN
+ AssertFalse(_xResultError, 'Overrange error set before expected time');
+ELSE
+ AssertTrue(_xResultError, 'Overrange error not set on time');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+// assert result
+AssertTrue(_xResultError, 'Expected underrange error');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+END_IF
+
+// run AI cyclically until underrange error is supposed to be off
+_fbAIUnderrangeOff(
+ iAnalogValue:= 0,
+ stAnalogIOConfig := _stAnalogInputConfig,
+ stAnalogEWConfig := _stAnalogEWConfig,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= ,
+ xReleaseErrors := TRUE,
+ xReleaseHardwareErrors := TRUE,
+ xReleaseLimitErrors:= TRUE,
+ xConfirmAlarms := TRUE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+// assert result depending on timer
+IF NOT _fbUnderrangeOffTimer.Q THEN
+ AssertTrue(_xResultError, 'Underrange error is reset before expected time');
+ELSE
+ AssertFalse(_xResultError, 'Underrange error not reset on time');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> ,
+ xWarningLow=> ,
+ xWarningHigh=> ,
+ xErrorHigh=> );
+
+// assert result depending on timer
+IF NOT _fbUnderrangeOnTimer.Q THEN
+ AssertFalse(_xResultError, 'Underrange error set before expected time');
+ELSE
+ AssertTrue(_xResultError, 'Underrange error not set on time');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh
+ );
+
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active');
+AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active');
+AssertTrue(Condition:= _xResultWarningHigh, Message:= 'Warning high is not active');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active');
+
+// Check without active release signal
+_fbAI(
+ iAnalogValue:= 85,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= FALSE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh
+ );
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active without active release signal');
+AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active without active release signal');
+AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active without active release signal');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active without active release signal');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+ELSE
+ _fbWarningHighOffTimer(IN := TRUE, PT := timOffTime);
+ _fbAIWarningHighOff(
+ iAnalogValue:= 50,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= TRUE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+END_IF
+
+// Wait for the delay time to be finished and check the signal level
+// Should be high until the delay time has passed
+IF _fbWarningHighOffTimer.Q THEN
+ _xWarningHighOffTestFinished := TRUE;
+ AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is still active after the delay time');
+ELSE
+ AssertTrue(Condition:= _xResultWarningHigh, Message:= 'Warning high is not active before the delay time elapsed');
+ IF NOT _xResultWarningHigh THEN
+ _xWarningHighOffTestFinished := TRUE;
+ END_IF
+END_IF
+
+IF _xWarningHighOffTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+
+// assert results
+IF NOT _fbWarningHighOnTimer.Q THEN
+ AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active before the time');
+ _fbErrorLowOnTimer.IN := FALSE;
+ELSE
+ _xWarningHighOnTestFinished := TRUE;
+ AssertTrue(Condition:= _xResultWarningHigh, Message:= 'Warning high is not active after the delay time');
+END_IF
+
+IF _xWarningHighOnTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh
+ );
+
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active');
+AssertTrue(Condition:= _xResultWarningLow, Message:= 'Warning low is not active');
+AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active');
+
+// Warning low without release
+_fbAI(
+ iAnalogValue:= 15,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= FALSE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh
+ );
+
+// assert results
+AssertFalse(Condition:= _xResultErrorLow, Message:= 'Error low is active without active release');
+AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active without active release');
+AssertFalse(Condition:= _xResultWarningHigh, Message:= 'Warning high is active without active release');
+AssertFalse(Condition:= _xResultErrorHigh, Message:= 'Error high is active without active release');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+ELSE
+ _fbWarningLowOffTimer(IN := TRUE, PT := timOffTime);
+ _fbAIWarningLowOff(
+ iAnalogValue:= 50,
+ xUnderrange:= FALSE,
+ xOverrange:= FALSE,
+ xErrorCard:= FALSE,
+ xReleaseLimitErrors:= TRUE,
+ xError=> _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+END_IF
+
+// Wait for the delay time to be finished and check the signal level
+// Should be high until the delay time has passed
+IF _fbWarningLowOffTimer.Q THEN
+ _xWarningLowOffTestFinished := TRUE;
+ AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is still active after the delay time');
+ELSE
+ AssertTrue(Condition:= _xResultWarningLow, Message:= 'Warning low is not active before the delay time elapsed');
+ IF NOT _xResultWarningLow THEN
+ _xWarningLowOffTestFinished := TRUE;
+ END_IF
+END_IF
+
+IF _xWarningLowOffTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xResultError,
+ rScaledValue=> ,
+ xInUnitTestMode := TRUE,
+ xErrorLow=> _xResultErrorLow,
+ xWarningLow=> _xResultWarningLow,
+ xWarningHigh=> _xResultWarningHigh,
+ xErrorHigh=> _xResultErrorHigh);
+
+// assert results
+IF NOT _fbWarningLowOnTimer.Q THEN
+ AssertFalse(Condition:= _xResultWarningLow, Message:= 'Warning low is active before the time');
+ _fbErrorLowOnTimer.IN := FALSE;
+ELSE
+ _xWarningLowOnTestFinished := TRUE;
+ AssertTrue(Condition:= _xResultWarningLow, Message:= 'Warning low is not active after the delay time');
+END_IF
+
+IF _xWarningLowOnTestFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU b/BasicComponents/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU
new file mode 100644
index 0000000..3098565
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/AOTests/FB_AnalogOutputTest.TcPOU
@@ -0,0 +1,469 @@
+
+
+
+
+
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// evaluate Error and result to zero
+AssertTrue(_xError, 'There should be an error when trying to divide by zero.');
+AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when trying to divide by zero');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// evaluate Error and result to zero
+AssertTrue(_xError, 'There should be an error when trying to divide by zero.');
+AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when trying to divide by negative number.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// due to only moving real, a delta of 0.01 should be sufficient.
+// testing all HMI values
+AssertEquals_REAL(Expected := _stAnalogOutputConfig.rPVMax, Actual := _stHMIInterface.rMax, Delta := rDelta,'rMax was not passed to HMI correctly.');
+AssertEquals_REAL(Expected := _stAnalogOutputConfig.rPVMin, Actual := _stHMIInterface.rMin, Delta := rDelta,'rMin was not passed to HMI correctly.');
+// rValue from HMI Interface functions as an Input to the FB. If the FB would write it back we would have a loop!
+{analysis -140}
+//AssertEquals_REAL(Expected := rExpected, Actual := stHMIInterface.rValue, Delta := rDelta,'rValue was not passed to HMI correctly.');
+{analysis +140}
+AssertEquals_STRING(Expected := sName, Actual := _stHMIInterface.sName, 'sName was not passed to HMI correctly.');
+AssertEquals_STRING(Expected := sUnit, Actual := _stHMIInterface.sUnit, 'sUnit was not passed to HMI correctly.');
+AssertTrue(_stHMIInterface.xUsed, 'xUsed is not passed to HMI correctly.');
+AssertEquals_INT(Expected := iOk, Actual := _stHMIInterface.iStatus, 'Status is Error when OK was expected.');
+
+// testing error passtrough (div by zero)
+_stAnalogOutputConfig.rPVMax := 0;
+_stAnalogOutputConfig.rPVMin := 0;
+
+// run analog scaling
+_fbAnalogOutput(
+ rSetpoint := 0,
+ stAnalogIOConfig := _stAnalogOutputConfig,
+ xReleaseErrors := ,
+ xConfirmAlarms := ,
+ stHMIInterface := _stHMIInterface,
+ iAnalogValue => _iAnalogOutput,
+ xError => _xError);
+
+// reading error from HMI interface
+AssertEquals_INT(Expected := iError, Actual := _stHMIInterface.iStatus, 'Status is OK when Error was expected.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// and evaluate result
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected1, Actual := _iAnalogOutput,'Result was not calculated correctly.');
+
+// run second value
+_fbAnalogOutput(
+ rSetpoint := 87.5, //87,5 * 81,9 - 4095 = 3071
+ stAnalogIOConfig := _stAnalogOutputConfig,
+ xReleaseErrors := ,
+ xConfirmAlarms := ,
+ stHMIInterface := _stHMIInterface,
+ iAnalogValue => _iAnalogOutput,
+ xError => _xError);
+
+// and evaluate result
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected2, Actual := _iAnalogOutput,'Result was not calculated correctly.');
+
+// run third value
+_fbAnalogOutput(
+ rSetpoint := 54.321, //54,321 * 81,9 - 4095 = 354
+ stAnalogIOConfig := _stAnalogOutputConfig,
+ xReleaseErrors := ,
+ xConfirmAlarms := ,
+ stHMIInterface := _stHMIInterface,
+ iAnalogValue => _iAnalogOutput,
+ xError => _xError);
+
+// and evaluate result
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected3, Actual := _iAnalogOutput,'Result was not calculated correctly.');
+
+// run forth value
+_fbAnalogOutput(
+ rSetpoint := 99, //99 * 81,9 - 4095 = 4013
+ stAnalogIOConfig := _stAnalogOutputConfig,
+ xReleaseErrors := ,
+ xConfirmAlarms := ,
+ stHMIInterface := _stHMIInterface,
+ iAnalogValue => _iAnalogOutput,
+ xError => _xError);
+
+// and evaluate result
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected4, Actual := _iAnalogOutput,'Result was not calculated correctly.');
+
+// run fifth value
+_fbAnalogOutput(
+ rSetpoint := 75.12345, // 75,12345 * 81,9 - 4095 = 2058
+ stAnalogIOConfig := _stAnalogOutputConfig,
+ xReleaseErrors := ,
+ xConfirmAlarms := ,
+ stHMIInterface := _stHMIInterface,
+ iAnalogValue => _iAnalogOutput,
+ xError => _xError);
+
+// and evaluate result
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected5, Actual := _iAnalogOutput,'Result was not calculated correctly.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// evaluate wethere the result is the equivalent of lower cap or not
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected, Actual := _iAnalogOutput,'Setpoint was expected to be capped.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// evaluate wethere the result is the equivalent of upper cap or not
+AssertFalse(_xError, 'There should not be an error here.');
+AssertEquals_INT(Expected := iExpected, Actual := _iAnalogOutput,'Setpoint was expected to be capped.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _iAnalogOutput,
+ xError => _xError,
+ xInUnitTestMode := TRUE);
+
+// test for error and output (should not be present and 0 when unused)
+AssertFalse(_xError, 'There should not be an error when unused.');
+AssertEquals_INT(Expected := 0, Actual := _iAnalogOutput, 'Output is expected to be zero when unused');
+
+TEST_FINISHED();]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU b/BasicComponents/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU
new file mode 100644
index 0000000..44cd6fe
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/AnalogValveTests/FB_ValveAnalog_Test.TcPOU
@@ -0,0 +1,547 @@
+
+
+
+
+
+
+
+
+
+
+ _xError, xInUnitTestMode := TRUE);
+
+// assert result
+AssertTrue(_xError, 'Expected NotInRangeError, got no error.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+
+
+
+
+
+
+ _xError,
+ xInUnitTestMode := TRUE);
+
+// assert result
+AssertTrue(_xError, 'Expected Overrange error, got no error.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _xError,
+ xInUnitTestMode := TRUE);
+
+// assert result
+AssertTrue(_xError, 'Expected Underrange error, got no error.');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU b/BasicComponents/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU
new file mode 100644
index 0000000..e8afac2
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ReleaseSignalTests/FB_ReleaseSignalTest.TcPOU
@@ -0,0 +1,188 @@
+
+
+
+
+
+
+
+
+
+
+ _xReturnValue);
+
+// Start timer after which the output of the Signal fb will be checked
+_fbOffTimer(IN := TRUE, PT := (timOffTime + T#50MS));
+
+IF _xSignalForOffTest THEN
+ _xSignalForOffTest := FALSE;
+END_IF
+
+// Signal must be true at the start of the test
+// If not, abort the test
+IF _xSignalForOffTest AND (NOT _xReturnValue) THEN
+ AssertTrue(Condition := _xReturnValue, Message := 'Signal not true at start of test');
+ _xTestWithOffTimeFinished := TRUE;
+END_IF
+
+// Check value after a time which is longer than the signal delay time
+IF NOT _fbOffTimer.Q THEN
+ IF (NOT _xReturnValue) THEN
+ AssertFalse(Condition := _xReturnValue, Message := 'Signal was false before the time was over');
+ _fbOnTimer.IN := FALSE;
+ _xTestWithOffTimeFinished := TRUE;
+ END_IF
+ELSE
+ AssertFalse(Condition := _xReturnValue, Message := 'Signal was not false after the time elapsed');
+ _fbOnTimer.IN := FALSE;
+ _xTestWithOffTimeFinished := TRUE;
+END_IF
+
+IF _xTestWithOffTimeFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xReturnValue);
+
+// Start timer after which the output of the Signal fb will be checked
+_fbOnTimer(IN := TRUE, PT := (timOnTime + T#50MS));
+
+// Check value after a time which is longer than the signal delay time
+IF NOT _fbOnTimer.Q THEN
+ IF _xReturnValue THEN
+ AssertTrue(Condition := _xReturnValue, Message := 'Signal was true before the time was over');
+ _fbOnTimer.IN := FALSE;
+ _xTestWithOnTimeFinished := TRUE;
+ END_IF
+ELSE
+ AssertTrue(Condition := _xReturnValue, Message := 'Signal was not true after the time elapsed');
+ _fbOnTimer.IN := FALSE;
+ _xTestWithOnTimeFinished := TRUE;
+END_IF
+
+IF _xTestWithOnTimeFinished THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xReturnValue);
+
+AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not false');
+
+
+// Test high signal
+_xSignal := TRUE;
+_xExpected := TRUE;
+_fbReleaseSignal(
+ xSignal:= _xSignal,
+ xRelease:= _xRelease,
+ timOnDelay:= T#0MS,
+ timOffDelay:= T#0MS,
+ xReleaseSignal=> _xReturnValue);
+
+AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not true');
+
+// Test with inactive release
+_xRelease := FALSE;
+_xSignal := TRUE;
+_xExpected := FALSE;
+_fbReleaseSignal(
+ xSignal:= _xSignal,
+ xRelease:= _xRelease,
+ timOnDelay:= T#0MS,
+ timOffDelay:= T#0MS,
+ xReleaseSignal=> _xReturnValue);
+
+AssertEquals(Expected:= _xExpected, Actual:= _xReturnValue, Message:= 'Signal is not false with no active release');
+
+TEST_FINISHED();]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU
new file mode 100644
index 0000000..27b6cd0
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_BlinkerTest.TcPOU
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+
+
+
+
+ _xOut);
+
+// check results for each cycle depending on alternating timers
+IF _fbDelayFreq0_1HzOnTimer.Q THEN
+ AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
+ELSE
+ AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
+END_IF
+
+// increment counter when timer is done
+IF _fbRtrigFreq0_1Hz.Q THEN
+ _iFreq0_1HzCounter := _iFreq0_1HzCounter + 1;
+END_IF
+
+// finish test after 5 blinking cycles
+IF _iFreq0_1HzCounter > 5 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xOut);
+
+// check results for each cycle depending on alternating timers
+IF _fbDelayFreq0_5HzOnTimer.Q THEN
+ AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
+ELSE
+ AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
+END_IF
+
+// increment counter when timer is done
+IF _fbRtrigFreq0_5Hz.Q THEN
+ _iFreq0_5HzCounter := _iFreq0_5HzCounter + 1;
+END_IF
+
+// finish test after 5 blinking cycles
+IF _iFreq0_5HzCounter > 5 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xOut);
+
+// check results for each cycle depending on alternating timers
+IF _fbDelayFreq1HzOnTimer.Q THEN
+ AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
+ELSE
+ AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
+END_IF
+
+// increment counter when timer is done
+IF _fbRtrigFreq1Hz.Q THEN
+ _iFreq1HzCounter := _iFreq1HzCounter + 1;
+END_IF
+
+// finish test after 5 blinking cycles
+IF _iFreq1HzCounter > 5 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xOut);
+
+// check results for each cycle depending on alternating timers
+IF _fbDelayFreq2HzOnTimer.Q THEN
+ AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
+ELSE
+ AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
+END_IF
+
+// increment counter when timer is done
+IF _fbRtrigFreq2Hz.Q THEN
+ _iFreq2HzCounter := _iFreq2HzCounter + 1;
+END_IF
+
+// finish test after 5 blinking cycles
+IF _iFreq2HzCounter > 5 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xOut);
+
+// check results for each cycle depending on alternating timers
+IF _fbDelayFreq50HzOnTimer.Q THEN
+ AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
+ELSE
+ AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
+END_IF
+
+// increment counter when timer is done
+IF _fbRtrigFreq50Hz.Q THEN
+ _iFreq50HzCounter := _iFreq50HzCounter + 1;
+END_IF
+
+// finish test after 5 blinking cycles
+IF _iFreq50HzCounter > 5 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _xOut);
+
+// check results for each cycle depending on alternating timers
+IF _fbDelayFreq5HzOnTimer.Q THEN
+ AssertTrue(_xOut, 'xOut is supposed to be true but is false.');
+ELSE
+ AssertFalse(_xOut, 'xOut is supposed to be false but is true.');
+END_IF
+
+// increment counter when timer is done
+IF _fbRtrigFreq5Hz.Q THEN
+ _iFreq5HzCounter := _iFreq5HzCounter + 1;
+END_IF
+
+// finish test after 5 blinking cycles
+IF _iFreq5HzCounter > 5 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU
new file mode 100644
index 0000000..691a5f4
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_HashFNV1a_32BitTest.TcPOU
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU
new file mode 100644
index 0000000..8f9569a
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_PT1Test.TcPOU
@@ -0,0 +1,276 @@
+
+
+
+
+
+
+
+
+
+
+ 0.0001 THEN
+ AssertTrue(FALSE, 'Project cycle time not set to 10ms!');
+ELSE
+ _fbPT1(
+ lrInput := 0,
+ timT := T#10MS,
+ lrOutput => );
+
+ // Project should be set to 10ms cycle time for this test to work
+ AssertEquals_LREAL(Expected := 10.0, Actual := _fbPT1.CycleTime, Delta := 0.01, 'Cycle time is not equal to project cycle time (10ms)');
+END_IF
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _lrOutput);
+
+// set error message according to current step
+_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_15_2345));
+_sMessage := CONCAT(_sMessage, ' did not return expected value.');
+
+// check values of current step
+AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_15_2345[_iCounterStepPT1_15_2345], Actual := _lrOutput, Delta := lrDelta, _sMessage);
+_iCounterStepPT1_15_2345 := _iCounterStepPT1_15_2345 + 1;
+
+// finish test after 20 cycles
+IF _iCounterStepPT1_15_2345 > 20 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _lrOutput);
+
+// set error message according to current step
+_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_168));
+_sMessage := CONCAT(_sMessage, ' did not return expected value.');
+
+// check values of current step
+AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_168[_iCounterStepPT1_168], Actual := _lrOutput, Delta := lrDelta, _sMessage);
+_iCounterStepPT1_168 := _iCounterStepPT1_168 + 1;
+
+// finish test after 20 cycles
+IF _iCounterStepPT1_168 > 20 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _lrOutput);
+
+// set error message according to current step
+_sMessage := CONCAT(_sMessage, TO_STRING(_iCounterStepPT1_50));
+_sMessage := CONCAT(_sMessage, ' did not return expected value.');
+
+// check values of current step
+AssertEquals_LREAL(Expected := _alrExpectedValuesStepPT1_50[_iCounterStepPT1_50], Actual := _lrOutput, Delta := lrDelta, _sMessage);
+_iCounterStepPT1_50 := _iCounterStepPT1_50 + 1;
+
+// finish test after 20 cycles
+IF _iCounterStepPT1_50 > 20 THEN
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU
new file mode 100644
index 0000000..d09b19a
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/UtilitiesTests/FB_RampGeneratorTest.TcPOU
@@ -0,0 +1,473 @@
+
+
+
+
+
+
+
+
+
+
+ 0.001 THEN
+ AssertTrue(FALSE, 'Project cycle time not set to 10ms!');
+ELSE
+ _fbRampGen(
+ rTarget:= 0.0,
+ rTargetMin:= 0.0,
+ rTargetMax:= 100.0,
+ timRampUp:= T#5S,
+ timRampDown:= T#5S,
+ rSetpoint=> ,
+ xInTarget=> );
+
+ // Project should be set to 10ms cycle time for this test to work
+ AssertEquals_REAL(Expected := 10.0, Actual := _fbRampGen.CycleTime, Delta := 0.01, 'Cycle time is not equal to project cycle time (10ms)');
+END_IF
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget => _xInTarget);
+
+// check for whether InTarget is reached at the specified time
+IF NOT _fbDelayInTargetResultDown.Q THEN
+ AssertFalse(_xInTarget, 'InTarget reached earlier then expected.');
+ELSE
+ AssertTrue(_xInTarget, 'InTarget not reached in time.');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget => _xInTarget);
+
+// check for whether InTarget is reached at the specified time
+IF NOT _fbDelayInTargetResultUp.Q THEN
+ AssertFalse(_xInTarget, 'InTarget reached earlier then expected.');
+ELSE
+ AssertTrue(_xInTarget, 'InTarget not reached in time.');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget =>);
+
+// check for clamping
+IF NOT _fbDelayMaxClamp.Q THEN
+ // too early
+ AssertTrue(_rSetpoint < rExpected,'Clamped value reached before expected time');
+ELSE
+ // after expected rampTime
+ IF NOT _fbDelayMaxClampBuffer.Q THEN
+ AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value did not stay on or did not reach MaxTarget');
+ ELSE
+ TEST_FINISHED();
+ END_IF
+END_IF]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget =>);
+
+// check for clamping
+IF NOT _fbDelayMinClamp.Q THEN
+ // too early
+ AssertTrue(_rSetpoint >= (rExpected - rDelta), 'Clamped value reached before expected time');
+ELSE
+ // after expected rampTime
+ IF NOT _fbDelayMinClampBuffer.Q THEN
+ AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value did not stay on or did not reach MinTarget');
+ ELSE
+ TEST_FINISHED();
+ END_IF
+END_IF]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget =>);
+
+// check for current expected value
+IF NOT _fbDelayRampDownContinuity.Q THEN
+ AssertEquals_REAL(Expected := _rNextExpectedDown, Actual := _rSetpoint, Delta := rDelta, 'Expected current value was not achieved.');
+ELSE
+ // check for final value
+ AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget =>);
+
+// check whether final value is reach on time or before
+IF NOT _fbDelayRampDownTime.Q THEN
+ AssertTrue(_rSetpoint > (rExpected - rDelta),'Value reached before expected time.');
+ELSE
+ AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
+ TEST_FINISHED();
+END_IF
+]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget =>);
+
+// check for current expected value
+IF NOT _fbDelayRampUpContinuity.Q THEN
+ AssertEquals_REAL(Expected := _rNextExpectedUp, Actual := _rSetpoint, Delta := rDelta, 'Expected current value was not achieved.');
+ELSE
+ // check for final value
+ AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
+
+ _rSetpoint,
+ xInTarget =>);
+
+// check whether final value is reach on time or before
+IF NOT _fbDelayRampUpTime.Q THEN
+ AssertTrue(_rSetpoint < rExpected,'Value reached before expected time.');
+ELSE
+ AssertEquals_REAL(Expected := rExpected, Actual := _rSetpoint, Delta := rDelta, 'Value was not reached in time.');
+ TEST_FINISHED();
+END_IF]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU
new file mode 100644
index 0000000..356cc0a
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestHMI.TcPOU
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+
+
+
+
+ ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= _stValveConfig,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+// Valve should now be in manual mode and xRequest should have been reset
+AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not change to manual mode');
+AssertFalse(Condition := _stHMIValve.stManualButton.xRequest, Message := 'Valve did not reset the manual mode button request');
+
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= _stValveConfig,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+AssertFalse(Condition := _stHMIValve.stManualButton.xRelease, Message := 'Manual mode button was released but should not have been');
+
+
+// Test release for HMI mode change
+_fbValve(
+ xReleaseManualMode:= TRUE,
+ wProcessINTLK:= _wInterlocks,
+ wProcessINTLKUsed:= _wInterlocksUsed,
+ stHMIInterface:= _stHMIValve,
+ xError=> ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= ,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+AssertTrue(Condition := _stHMIValve.stManualButton.xRelease, Message := 'Manual mode button was not released but should have been');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= _stValveConfig,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+// Valve should now be in manual mode
+AssertTrue(Condition := _fbValveOC.IsInManualMode, Message := 'Valve did not change to manual mode pre test');
+
+// Request open from HMI and call valve block
+_stHMIValve.stOpenButton.xRequest := TRUE;
+_fbValveOC(
+ xReleaseManualMode:= TRUE,
+ wProcessINTLK:= _wInterlocks,
+ wProcessINTLKUsed:= _wInterlocksUsed,
+ stHMIInterface:= _stHMIValve,
+ xError=> ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= ,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+// test for valve state and HMI feedback
+AssertTrue(Condition := _fbValveOC.xOpenValve, Message := 'Valve did not open as requested by hmi button');
+AssertFalse(Condition := _stHMIValve.stOpenButton.xRequest, Message := 'Valve did not reset open request');
+_eExpectedOpenButtonFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE;
+_eExpectedCloseButtonFeedback := E_HMI_BUTTON_FEEDBACK.NONE;
+AssertEquals(Expected := _eExpectedOpenButtonFeedback, Actual := _stHMIValve.stOpenButton.eFeedback, Message := 'Valve did not send correct open button feedback signal while open');
+AssertEquals(Expected := _eExpectedCloseButtonFeedback, Actual := _stHMIValve.stCloseButton.eFeedback, Message := 'Valve did not send correct close button feedback signal while open');
+
+// Request close from HMI and call valve block
+_stHMIValve.stCloseButton.xRequest := TRUE;
+_fbValveOC(
+ xReleaseManualMode:= TRUE,
+ wProcessINTLK:= _wInterlocks,
+ wProcessINTLKUsed:= _wInterlocksUsed,
+ stHMIInterface:= _stHMIValve,
+ xError=> ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= ,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+// test for valve state and HMI feedback
+AssertTrue(Condition := _fbValveOC.xCloseValve, Message := 'Valve did not close as requested by hmi button');
+AssertFalse(Condition := _stHMIValve.stCloseButton.xRequest, Message := 'Valve did not reset close request');
+_eExpectedOpenButtonFeedback := E_HMI_BUTTON_FEEDBACK.NONE;
+_eExpectedCloseButtonFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE;
+AssertEquals(Expected := _eExpectedCloseButtonFeedback, Actual := _stHMIValve.stCloseButton.eFeedback, Message := 'Valve did not send correct close button feedback signal while closed');
+AssertEquals(Expected := _eExpectedOpenButtonFeedback, Actual := _stHMIValve.stOpenButton.eFeedback, Message := 'Valve did not send correct open button feedback signal while closed');
+
+TEST_FINISHED();]]>
+
+
+
+
+
+ ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= _stValveConfig,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+// Valve should now be in manual mode
+AssertTrue(Condition := _fbValve.IsInManualMode, Message := 'Valve did not change to manual mode pre test');
+
+// Valve should not realease open button with active interlock
+AssertFalse(Condition := _stHMIValve.stOpenButton.xRelease, Message := 'Valve did release open button but should not');
+
+// Test if request is denied by valve with active interlocks
+_stHMIValve.stOpenButton.xRequest := TRUE;
+_fbValve(
+ xReleaseManualMode:= TRUE,
+ wProcessINTLK:= wInterlocks,
+ wProcessINTLKUsed:= wInterlocksUsed,
+ stHMIInterface:= _stHMIValve,
+ xError=> ,
+ xOpenFeedback:= ,
+ xCloseFeedback:= ,
+ xReleaseErrors:= ,
+ xConfirmAlarms:= ,
+ stValveConfig:= ,
+ xOpenValve=> ,
+ xCloseValve=> );
+
+AssertFalse(Condition := _fbValve.xOpenValve, Message := 'Valve did not block manual open command with active interlock');
+
+TEST_FINISHED();]]>
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU
new file mode 100644
index 0000000..b0e27bf
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTimoutClose.TcPOU
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU
new file mode 100644
index 0000000..502ee48
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTimoutOpen.TcPOU
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU
new file mode 100644
index 0000000..1ef858b
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutClose.TcPOU
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU
new file mode 100644
index 0000000..2dd502d
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ValveTests/FB_ValveTestTriggerTimoutOpen.TcPOU
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU b/BasicComponents/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU
new file mode 100644
index 0000000..3979e99
--- /dev/null
+++ b/BasicComponents/POUs/Unittests/ValveTests/FB_Valve_Test.TcPOU
@@ -0,0 +1,427 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BasicComponents/PlcTask.TcTTO b/BasicComponents/PlcTask.TcTTO
new file mode 100644
index 0000000..4838516
--- /dev/null
+++ b/BasicComponents/PlcTask.TcTTO
@@ -0,0 +1,16 @@
+
+
+
+
+ 10000
+ 20
+
+ PRG_MAIN
+
+ {a83be5e0-d5cf-4aec-b38e-29e42c090d19}
+ {4deed5d2-49a0-440e-8d82-d09251814781}
+ {fec05c77-54d5-4195-ac02-ecdaaad52f09}
+ {7536800f-d7c6-464d-a9c4-0b4ee7a1d592}
+ {6dbfee29-f644-435d-b6e8-122b6f086f52}
+
+
\ No newline at end of file
diff --git a/DOC01321154-0000_INVEOR_M EtherCAT.xml b/DOC01321154-0000_INVEOR_M EtherCAT.xml
new file mode 100644
index 0000000..8f771dd
--- /dev/null
+++ b/DOC01321154-0000_INVEOR_M EtherCAT.xml
@@ -0,0 +1,161 @@
+
+
+
+ #x00000337
+ Kostal Industrie Elektrik GmbH
+ 424DE6000000000000007600000028000000100000000E000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0088888888888888888888888888888888FFF666FFFF6666F8FFF6877FF67876FFFFF7F77FFFF67FFFFFF7F768FF6FFFFFFFF7F78FF67FFFFFFFF7FFFF67FFFFFFFFF7F78FF67FFFFFFFF7F766FFF7FFFFFFF7F77F6FFF67FFFFF6877FF67876FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+
+
+
+ drives
+ drives
+ 424DE6000000000000007600000028000000100000000E000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0088888888888888888888888888888888FFF666FFFF6666F8FFF6877FF67876FFFFF7F77FFFF67FFFFFF7F768FF6FFFFFFFF7F78FF67FFFFFFFF7FFFF67FFFFFFFFF7F78FF67FFFFFFFF7F766FFF7FFFFFFF7F77F6FFF67FFFFF6877FF67876FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+
+
+
+ INVEOR_M
+
+
+ drives
+ Outputs
+ Inputs
+ MBoxState
+ MBoxOut
+ MBoxIn
+ Outputs
+ Inputs
+
+ #x1600
+ Outputs0
+
+ #x2000
+ 1
+ 32
+ Steuerwort
+ UDINT
+
+
+ #x2000
+ 2
+ 32
+ Sollfrequenz
+ REAL
+
+
+ #x2000
+ 3
+ 32
+ Digitalausgänge / Relais
+ UDINT
+
+
+ #x2000
+ 4
+ 32
+ Analogausgang 1
+ REAL
+
+
+ #x2000
+ 5
+ 32
+ Kundenspez.SPS Eingangsgröße 1 (Digital 32Bit)
+ UDINT
+
+
+ #x2000
+ 6
+ 32
+ Kundenspez.SPS Eingangsgröße 1 (Digital 32Bit)
+ UDINT
+
+
+
+ #x1a00
+ Inputs0
+
+ #x3000
+ 1
+ 32
+ Statuswort
+ UDINT
+
+
+ #x3000
+ 2
+ 32
+ Istfrequenz
+ REAL
+
+
+ #x3000
+ 3
+ 32
+ Motorspannung
+ REAL
+
+
+ #x3000
+ 4
+ 32
+ Motorstrom
+ REAL
+
+
+ #x3000
+ 5
+ 32
+ Netzspannung
+ REAL
+
+
+ #x3000
+ 6
+ 32
+ Frequenzsollwert
+ REAL
+
+
+ #x3000
+ 7
+ 32
+ Digitaleingänge bitcodiert
+ UDINT
+
+
+ #x3000
+ 8
+ 32
+ Analogeingang 1
+ REAL
+
+
+ #x3000
+ 9
+ 32
+ Fehlerwort 1
+ UDINT
+
+
+ #x3000
+ 10
+ 32
+ Fehlerwort 2
+ UDINT
+
+
+
+
+
+
+
+ 65536
+ 06000188E8030000
+
+ 424DE6000000000000007600000028000000100000000E000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0088888888888888888888888888888888FFF666FFFF6666F8FFF6877FF67876FFFFF7F77FFFF67FFFFFF7F768FF6FFFFFFFF7F78FF67FFFFFFFF7FFFF67FFFFFFFFF7F78FF67FFFFFFFF7F766FFF7FFFFFFF7F77F6FFF67FFFFF6877FF67876FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+
+
+
diff --git a/LibraryCategories.libcat.xml b/LibraryCategories.libcat.xml
new file mode 100644
index 0000000..e302404
--- /dev/null
+++ b/LibraryCategories.libcat.xml
@@ -0,0 +1,16 @@
+
+
+
+ 3d49e892-ba18-4f02-888a-850f97d52db7
+ 1.0.0.0
+ Heisig GmbH
+
+
+ eb1097e9-64c5-43a2-8e69-a580a5ac7866
+ 1.0.0.0
+
+ 3d49e892-ba18-4f02-888a-850f97d52db7
+
+ Standard Libraries
+
+
\ No newline at end of file
diff --git a/_Config/IO/Gerät 1 (EtherCAT).xti b/_Config/IO/Gerät 1 (EtherCAT).xti
new file mode 100644
index 0000000..dda19e7
--- /dev/null
+++ b/_Config/IO/Gerät 1 (EtherCAT).xti
@@ -0,0 +1,20 @@
+
+
+
+ __FILENAME__
+
+
+
+
+ 000000000000
+
+
+
+ Prozessabbild
+
+
+
+
+
+
+
diff --git a/_Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti b/_Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti
new file mode 100644
index 0000000..1e153df
--- /dev/null
+++ b/_Config/IO/Gerät 1 (EtherCAT)/Box 1 (INVEOR_M).xti
@@ -0,0 +1,71 @@
+
+
+
+ 424de6000000000000007600000028000000100000000e000000010004000000000070000000000000000000000000000000000000000000000000008000008000000080800080000000800080008080000080808000c0c0c0000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff0088888888888888888888888888888888fff666ffff6666f8fff6877ff67876fffff7f77ffff67ffffff7f768ff6ffffffff7f78ff67ffffffff7ffff67fffffffff7f78ff67ffffffff7f766fff7fffffff7f77f6fff67fffff6877ff67876ffffffffffffffffffffffffffffffffff
+
+
+ __FILENAME__
+ 1000
+
+ 001080003600010001000000800080008000001036010000
+ 801080003200010002000000800080008000801032010000
+ 00111800740001000300000000000001c800001174010000
+ 00142800300001000400000000000001c800001430010000
+ 0000000000000000001100020100000001000000000000000000000000000000
+ 0000000000000000001400010100000002000000000000000000000000000000
+ 00000000000000000d0800010100000003000000000000000000000000000000
+
+
+ UDINT
+
+
+ REAL
+
+
+ REAL
+
+
+ REAL
+
+
+ REAL
+
+
+ REAL
+
+
+ UDINT
+
+
+ REAL
+
+
+ UDINT
+
+
+ UDINT
+
+
+
+
+ UDINT
+
+
+ REAL
+
+
+ UDINT
+
+
+ REAL
+
+
+ UDINT
+
+
+ UDINT
+
+
+
+
+