├── .gitattributes ├── .gitignore ├── 00_introduction ├── .tours │ └── 00_codetour_introduction.tour ├── apax.yml └── slides │ ├── img │ ├── codetour_explorer.png │ ├── open_folder.png │ └── path.svg │ ├── reveal.json │ ├── slides.md │ └── theme │ ├── .DS_Store │ ├── siemens.svg │ └── simatic-ax.css ├── 01_introduction_to_ax_code ├── apax.yml └── slides │ ├── img │ ├── apax-build.png │ ├── autosave.png │ ├── ax-extensions.png │ ├── axcode.png │ ├── built-in-extensions.png │ ├── f1command.png │ ├── marketplace.png │ ├── output.png │ └── window-customization.PNG │ ├── slides.md │ └── theme │ ├── siemens.svg │ └── simatic-ax.css ├── 03_loading_and_debugging ├── apax.yml ├── assets │ ├── ax │ │ ├── HwConfiguration.hwdat │ │ ├── HwConfiguration.hwdat.hash │ │ ├── Meta.json │ │ ├── PkiContainer.hwdat │ │ └── PkiContainer.hwdat.hash │ ├── certificateForConnection.crt │ ├── plcsim_advanced_v6_image.7z │ └── tia │ │ └── AxHwTemplate.zap19 ├── exercises │ └── 0_first_exercise │ │ ├── README.md │ │ └── apax.yml └── slides │ ├── img │ ├── DownloadHardwareTia.gif │ ├── ExportCertificate.gif │ ├── PGPCInterface.gif │ ├── sdb_logpoint.gif │ ├── sdb_start.png │ ├── tiaxDirectLoading.png │ └── watchtable.gif │ ├── slides.md │ └── theme │ ├── .DS_Store │ ├── siemens.svg │ └── simatic-ax.css ├── 04_introduction_to_st ├── .gitignore ├── .tours │ ├── additional_information.tour │ ├── learning_path_st.tour │ └── monitoring.PNG ├── .vscode │ ├── extensions.json │ └── launch.json ├── apax-lock.json ├── apax.yml ├── exercises │ ├── 1_implement_valve │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── img │ │ │ ├── Valve.png │ │ │ └── ValveBehav.png │ │ └── src │ │ │ ├── configuration.st │ │ │ └── program.st │ ├── 2_implement_tank │ │ ├── .vscode │ │ │ └── launch.json │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── img │ │ │ ├── Tank.png │ │ │ └── TankBehav.png │ │ ├── src │ │ │ ├── configuration.st │ │ │ ├── fluidProgram.st │ │ │ └── valve.st │ │ └── watchTable.mon │ ├── 3_extend_tank_functionality │ │ ├── .vscode │ │ │ └── launch.json │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── img │ │ │ ├── TankBehav.png │ │ │ ├── TankBehavState.png │ │ │ └── TankModify.png │ │ ├── src │ │ │ ├── configuration.st │ │ │ ├── fluidProgram.st │ │ │ ├── tank.st │ │ │ └── valve.st │ │ └── watchTable.mon │ ├── 4_timer_for_tank │ │ ├── .vscode │ │ │ └── launch.json │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── img │ │ │ ├── TankModify.png │ │ │ └── ValveFbClosedBehav.png │ │ ├── src │ │ │ ├── configuration.st │ │ │ ├── fluidProgram.st │ │ │ ├── tank.st │ │ │ ├── types.st │ │ │ └── valve.st │ │ └── watchTable.mon │ └── 5_solution_exercise_4 │ │ ├── .vscode │ │ └── launch.json │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── src │ │ ├── configuration.st │ │ ├── fluidProgram.st │ │ ├── tank.st │ │ ├── types.st │ │ └── valve.st │ │ └── watchTable.mon ├── slides │ ├── slides.md │ └── theme │ │ ├── .DS_Store │ │ ├── siemens.svg │ │ └── simatic-ax.css └── src │ ├── ExampleProgram.st │ ├── Namespace │ ├── NamespaceExample.st │ └── UsageOfNameSpace.st │ ├── TankFb.st │ ├── Valve.st │ └── configuration.st ├── 05_oop_in_st ├── .gitignore ├── apax.yml ├── exercises │ ├── 0_basic_valve_class │ │ ├── .gitignore │ │ ├── .vscode │ │ │ └── launch.json │ │ ├── README.md │ │ ├── apax.yml │ │ ├── src │ │ │ ├── Tank.st │ │ │ ├── TankBase.st │ │ │ ├── Valve.st │ │ │ ├── ValveBase.st │ │ │ └── ValveStates.st │ │ └── test │ │ │ └── test.st │ ├── 1_interfaces │ │ ├── README.md │ │ ├── apax.yml │ │ └── src │ │ │ ├── ItfTank.st │ │ │ ├── ItfValve.st │ │ │ ├── TankBase.st │ │ │ ├── ValveBase.st │ │ │ └── ValveStates.st │ ├── 3_calculator_current_volume │ │ ├── README.md │ │ ├── apax.yml │ │ └── src │ │ │ ├── ItfTank.st │ │ │ ├── ItfValve.st │ │ │ ├── TankBase.st │ │ │ ├── ValveBase.st │ │ │ └── ValveStates.st │ ├── 4_inheritance_complex_valve │ │ ├── README.md │ │ ├── apax.yml │ │ └── src │ │ │ ├── ItfTank.st │ │ │ ├── ItfValve.st │ │ │ ├── TankBase.st │ │ │ ├── TankStates.st │ │ │ ├── TankWithVolume.st │ │ │ ├── ValveBase.st │ │ │ ├── ValveStates.st │ │ │ ├── configuration.st │ │ │ └── program.st │ └── solution │ │ ├── README.md │ │ ├── apax.yml │ │ └── src │ │ ├── CalculatorWithRegulation.st │ │ ├── ITank.st │ │ ├── IValve.st │ │ ├── TankStates.st │ │ ├── TankWithShape.st │ │ ├── TankWithVolume.st │ │ ├── ValveStates.st │ │ ├── basicValve.st │ │ ├── complexValve.st │ │ └── configuration.st ├── new.md └── slides │ ├── img │ ├── valvescheme.png │ └── valveuml.svg │ ├── new_structure.md │ ├── reveal-md.json │ ├── slides.md │ └── theme │ ├── .DS_Store │ ├── siemens.css │ ├── siemens.svg │ └── simatic-ax.css ├── 06_unit_testing ├── apax.yml ├── exercises │ ├── 1_starting_tests │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── src │ │ │ └── NumberIsEven.st │ │ └── test │ │ │ └── test.st │ ├── 2_testing_classes │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── src │ │ │ └── SimpleCounter.st │ │ └── test │ │ │ └── test.st │ ├── 3_parametrized_test │ │ ├── README.md │ │ ├── apax-lock.json │ │ ├── apax.yml │ │ ├── src │ │ │ └── SimpleCounter.st │ │ └── test │ │ │ └── test.st │ └── solutions │ │ ├── 1_starting_tests_solution │ │ └── test.st │ │ ├── 2_testing_classes_solution │ │ └── test.st │ │ └── 3_parametrized_test_solution │ │ └── test.st └── slides │ ├── img │ ├── Target.png │ ├── TestExplorer.png │ ├── apaxyml.png │ ├── debugging.png │ └── ui_buttons.png │ ├── slides.md │ └── theme │ ├── .DS_Store │ ├── siemens.css │ ├── siemens.svg │ └── simatic-ax.css ├── 07_tools_for_commissioning ├── apax.yml ├── exercises │ └── 0_first_exercise │ │ ├── README.md │ │ └── apax.yml └── slides │ ├── img │ ├── DiagBuffPanelWeb.png │ ├── PerformanceInfo.png │ ├── PlcOnlineHub.png │ └── plc-browser.gif │ ├── slides.md │ └── theme │ ├── .DS_Store │ ├── siemens.svg │ └── simatic-ax.css ├── 08_package_management ├── apax.yml ├── exercises │ ├── 1_creating_and_testing_a_library │ │ └── README.md │ ├── 2_publishing_a_library │ │ ├── README.md │ │ └── solution.md │ └── 3_consuming_a_library │ │ ├── README.md │ │ └── solution.md └── slides │ ├── img │ ├── box.png │ ├── cake.jpg │ ├── create_lib_project.PNG │ ├── key.jpg │ ├── library.jpg │ └── target.png │ ├── slides.md │ └── theme │ ├── .DS_Store │ ├── siemens.svg │ └── simatic-ax.css ├── CODEOWNERS ├── README.md ├── assets └── img │ ├── download_archive.png │ └── new_issue.png └── renovate.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # `.gitattributes` reclassify `.st` files as iec-st: 2 | ** linguist-vendored 3 | # *.ppjs linguist-language=ST -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.apax 2 | /.vs 3 | **/node_modules 4 | -------------------------------------------------------------------------------- /00_introduction/.tours/00_codetour_introduction.tour: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://aka.ms/codetour-schema", 3 | "title": "00_codetour_introduction", 4 | "steps": [] 5 | } -------------------------------------------------------------------------------- /00_introduction/apax.yml: -------------------------------------------------------------------------------- 1 | name: 00_introduction 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | setup-training-environment: npm install -g reveal-md 8 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch -------------------------------------------------------------------------------- /00_introduction/slides/img/codetour_explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/00_introduction/slides/img/codetour_explorer.png -------------------------------------------------------------------------------- /00_introduction/slides/img/open_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/00_introduction/slides/img/open_folder.png -------------------------------------------------------------------------------- /00_introduction/slides/reveal.json: -------------------------------------------------------------------------------- 1 | { 2 | "controls": true, 3 | "progress": false 4 | } -------------------------------------------------------------------------------- /00_introduction/slides/slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction to SIMATIC AX 3 | progress: true 4 | revealOptions: 5 | transition: 'fade' 6 | mouseWheel: true, 7 | --- 8 | 9 | 10 |

Introduction to SIMATIC AX

11 |

A complete introduction to the new engineering generation for SIMATIC controllers

12 | 13 | --- 14 | 15 |

Overview

16 | 17 | 18 |
19 |

20 | In this introductory course you will learn everything required to get started with the new engineering environment SIMATIC AX. Regardless if you are coming from TIA Portal or are starting new in the SIMATIC environment this learning path will guide you through the journey. 21 |

22 |
23 |

24 | To navigate between chapters (pages), please use the left/right arrows. To see more chapter content, use the up/down arrows when available. For a detailed overview of the controls, press F1 at any time of the presenation. 25 |

26 |
27 |

28 | To exit apax present in the terminal, please use "ctrl" + "c". 29 |

30 |
31 | 32 | 33 | --- 34 | 35 | # Agenda 36 | 37 | | | | 38 | | -- | ----- | 39 | | **00** | **Introduction to the workshop** | 40 | | 01 | Introduction to AX Code IDE | 41 | | 02 | Get started with your first AX Project | 42 | | 03 | Loading and Debugging | 43 | | 04 | Introduction to ST Programming | 44 | | 05 | OOP Elements of ST | 45 | | 06 | Unit Testing | 46 | | 07 | Tools for commissioning | 47 | | 08 | Package management | 48 | | 09 | Versioning and Continuous Integration | 49 | 50 | --- 51 | 52 |
53 |

Organization

54 |

Path structure

55 |
56 | 57 |
58 |
59 |

60 | The learning path is split into submodules for each specific topic. 61 |
62 |
63 | Each submodule contains a description in form of a slide deck as well as an interactive CodeTour about a specific topic. 64 |

65 | 66 |
67 | 68 | ---- 69 | 70 |
71 |

Organization

72 |

Folder structure

73 |
74 | 75 |
76 |
77 |

78 | Each learning module is contained in a subfolder of the repository 79 |
80 | It is made up of these components: 81 |

82 | 87 |
88 | 89 |
90 | 91 | ---- 92 | 93 |
94 |

Organization

95 |

Slides

96 |
97 | 98 |
99 |
100 |

101 | The slides can be interactively hosted locally on your PC. You need to install the tool reveal-md by typing this in your commandline:

102 |
103 |
104 |       
105 |         npm install reveal-md --global
106 |       
107 |     
108 |
109 | Note that this will install "third-party" software and is done at your own risk 110 |
111 |

You can then start the presentation by navigating to the module directory (e.g. 00_introduction) in the commandline and entering:

112 |
113 |

114 |       apax present
115 |     
116 |
117 | 118 |
119 | 120 | ---- 121 | 122 |
123 |
124 |
125 |

Organization

126 |

CodeTour

127 |
128 |
129 |

CodeTour is a Visual Studio Code extension, that can be used to create interactive tours in a VS Code project. To use the tours, please install the extension provided by Microsoft in the marketplace.

130 |

You will then find an additional drawer section in your explorer view:

131 |
132 |
133 |
134 | 135 |
136 | 137 |
138 | 139 | ---- 140 | 141 |
142 |
143 |
144 |

Organization

145 |

Exercises

146 |
147 |
148 |

Some modules contain additional training materials, that allow you to apply the skills you've learned through hands-on exercises.

149 |

You can start the exercise by opening the folder in AX Code and following the README.md

150 |
151 |
152 |
153 | 154 |
155 | 156 |
157 | 158 | --- 159 | 160 | 161 |

Have fun learning

162 |

SIMATIC AX

163 | 164 | -------------------------------------------------------------------------------- /00_introduction/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/00_introduction/slides/theme/.DS_Store -------------------------------------------------------------------------------- /00_introduction/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /00_introduction/slides/theme/simatic-ax.css: -------------------------------------------------------------------------------- 1 | /*! modern-normalize v2.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ 2 | 3 | /* 4 | Document 5 | ======== 6 | */ 7 | 8 | /** 9 | Use a better box model (opinionated). 10 | */ 11 | 12 | *, 13 | ::before, 14 | ::after { 15 | box-sizing: border-box; 16 | } 17 | 18 | html { 19 | /* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */ 20 | font-family: 21 | system-ui, 22 | 'Segoe UI', 23 | Roboto, 24 | Helvetica, 25 | Arial, 26 | sans-serif, 27 | 'Apple Color Emoji', 28 | 'Segoe UI Emoji'; 29 | line-height: 1.15; /* 1. Correct the line height in all browsers. */ 30 | -webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */ 31 | -moz-tab-size: 4; /* 3. Use a more readable tab size (opinionated). */ 32 | tab-size: 4; /* 3 */ 33 | } 34 | 35 | /* 36 | Sections 37 | ======== 38 | */ 39 | 40 | body { 41 | margin: 0; /* Remove the margin in all browsers. */ 42 | } 43 | body { 44 | background: rgb(0,0,40); 45 | background-color: rgb(0,0,40); 46 | /* Siemens Stone light 35%. White background makes index page unreadable (white links). */ 47 | } 48 | 49 | /* ugly trick to use white background for normal slides */ 50 | .js body { 51 | background: rgb(0,0,40); 52 | background-color: rgb(0,0,40); 53 | } 54 | 55 | section.has-dark-background, 56 | section.has-dark-background h1, 57 | section.has-dark-background h2, 58 | section.has-dark-background h3, 59 | section.has-dark-background h4, 60 | section.has-dark-background h5, 61 | section.has-dark-background h6 { 62 | color: #fff; 63 | } 64 | 65 | section { 66 | display: flex!important; 67 | flex-direction: column; 68 | align-items: left; 69 | text-align: left; 70 | height: 100%; 71 | margin: 1em 1em; 72 | overflow: hidden; 73 | } 74 | 75 | section.centered { 76 | display: flex!important; 77 | flex-direction: column; 78 | align-items: center; 79 | justify-content: center; 80 | text-align: center; 81 | } 82 | 83 | h1, h2, h3, h4, h5, p, td, li { 84 | text-shadow: transparent 0px 0px; 85 | font-family: "Siemens Sans Global", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 86 | font-weight: 700; 87 | line-height: 0.9; 88 | } 89 | 90 | p, td, li { 91 | font-weight: 500; 92 | } 93 | 94 | h1 { 95 | font-size: 5em; 96 | letter-spacing: -0.05em; 97 | background: linear-gradient(90deg, rgb(0, 190, 220), rgb(0, 215, 160)); 98 | -webkit-background-clip: text; /* clip the background to the text inside the tag*/ 99 | background-clip: text; 100 | -webkit-text-fill-color: transparent; /* make the text transparent so the background shows through*/ 101 | padding: 0 0 0.25em 0; 102 | margin: 0 0 0.25em 0; 103 | } 104 | 105 | h2 { 106 | font-size: 3em; 107 | letter-spacing: -0.05em; 108 | background: linear-gradient(90deg, rgb(0, 190, 220), rgb(0, 215, 160)); 109 | -webkit-background-clip: text; /* clip the background to the text inside the tag*/ 110 | background-clip: text; 111 | -webkit-text-fill-color: transparent; /* make the text transparent so the background shows through*/ 112 | padding: 0 0 0.25em 0; 113 | margin: 0 0 0.25em 0; 114 | } 115 | 116 | h3 { 117 | font-size: 2em; 118 | margin: -0.5em 0 0.25em 0; 119 | } 120 | 121 | h4 { 122 | font-size: 1.25em; 123 | font-weight: 900; 124 | } 125 | 126 | p, li { 127 | line-height: 1.75rem; 128 | font-size: 1.2rem; 129 | } 130 | 131 | table { 132 | 133 | } 134 | 135 | th, tr { 136 | line-height: 4rem; 137 | padding: 0.75rem 0rem; 138 | } 139 | td { 140 | padding: 0.5rem 0.05rem; 141 | font-size: 1.25rem; 142 | text-align: left; 143 | } 144 | 145 | .slide_header{ 146 | margin-bottom: 3rem; 147 | } 148 | 149 | .flex-row { 150 | display: flex; 151 | flex-direction: row; 152 | } 153 | 154 | 155 | .flex-col { 156 | display: flex; 157 | flex-direction: column; 158 | } 159 | 160 | .items-stretch{ 161 | align-items: stretch; 162 | } 163 | 164 | .items-center { 165 | align-items: center; 166 | } 167 | 168 | .justify-center { 169 | justify-content: center; 170 | } 171 | 172 | .justify-start { 173 | justify-content: start; 174 | } 175 | 176 | .grid-two-col-eq { 177 | display: grid; 178 | grid-template-columns: repeat(2, minmax(0, 1fr)); 179 | grid-column-gap: 4rem; 180 | } 181 | 182 | br { 183 | margin: 2rem; 184 | } 185 | 186 | ul { 187 | margin-top: 0.75rem; 188 | margin-left: 2rem; 189 | } 190 | 191 | li { 192 | margin: 0.25rem 0; 193 | } 194 | 195 | /* 196 | Grouping content 197 | ================ 198 | */ 199 | 200 | /** 201 | 1. Add the correct height in Firefox. 202 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 203 | */ 204 | 205 | hr { 206 | height: 0; /* 1 */ 207 | color: inherit; /* 2 */ 208 | } 209 | 210 | /* 211 | Text-level semantics 212 | ==================== 213 | */ 214 | 215 | /** 216 | Add the correct text decoration in Chrome, Edge, and Safari. 217 | */ 218 | 219 | abbr[title] { 220 | -webkit-text-decoration: underline dotted; 221 | text-decoration: underline dotted; 222 | } 223 | 224 | /** 225 | Add the correct font weight in Edge and Safari. 226 | */ 227 | 228 | b, 229 | strong { 230 | font-weight: bolder; 231 | } 232 | 233 | /** 234 | 1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) 235 | 2. Correct the odd 'em' font sizing in all browsers. 236 | */ 237 | 238 | code, 239 | kbd, 240 | samp, 241 | pre { 242 | font-family: 243 | ui-monospace, 244 | SFMono-Regular, 245 | Consolas, 246 | 'Liberation Mono', 247 | Menlo, 248 | monospace; /* 1 */ 249 | font-size: 1em; /* 2 */ 250 | } 251 | 252 | /** 253 | Add the correct font size in all browsers. 254 | */ 255 | 256 | small { 257 | font-size: 80%; 258 | } 259 | 260 | /** 261 | Prevent 'sub' and 'sup' elements from affecting the line height in all browsers. 262 | */ 263 | 264 | sub, 265 | sup { 266 | font-size: 75%; 267 | line-height: 0; 268 | position: relative; 269 | vertical-align: baseline; 270 | } 271 | 272 | sub { 273 | bottom: -0.25em; 274 | } 275 | 276 | sup { 277 | top: -0.5em; 278 | } 279 | 280 | /* 281 | Tabular data 282 | ============ 283 | */ 284 | 285 | /** 286 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 287 | 2. Correct table border color inheritance in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 288 | */ 289 | 290 | table { 291 | text-indent: 0; /* 1 */ 292 | border-color: inherit; /* 2 */ 293 | } 294 | -------------------------------------------------------------------------------- /01_introduction_to_ax_code/apax.yml: -------------------------------------------------------------------------------- 1 | name: 99_template 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/apax-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/apax-build.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/autosave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/autosave.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/ax-extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/ax-extensions.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/axcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/axcode.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/built-in-extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/built-in-extensions.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/f1command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/f1command.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/marketplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/marketplace.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/output.png -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/img/window-customization.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/01_introduction_to_ax_code/slides/img/window-customization.PNG -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction to the SIMATIC AX Code IDE 3 | progress: true 4 | revealOptions: 5 | transition: 'fade' 6 | mouseWheel: true, 7 | --- 8 | 9 | # Agenda 10 | 11 | | | | 12 | | -- | ----- | 13 | | 00 | Introduction to the workshop | 14 | | **01** | **Introduction to the SIMATIC AX Code IDE** | 15 | | 02 | Get started with your first AX Project | 16 | | 03 | Loading and Debugging | 17 | | 04 | Introduction to ST Programming | 18 | | 05 | OOP Elements of ST | 19 | | 06 | Unit Testing | 20 | | 07 | Tools for commissioning | 21 | | 08 | Package management | 22 | | 09 | Versioning and Continuous Integration | 23 | 24 | --- 25 | 26 |
27 |

Prerequisites

28 |
29 | 30 |
31 |
32 |

To get started, you need to have SIMATIC AX, apax and all its prerequisites installed. To get access to the software you need a SiemensID account and a license for SIMATIC AX.

33 | 37 |
38 |

With this you are set up to continue with this learning path.

39 |
40 |
41 | 42 | --- 43 | 44 |
45 |

46 | What will you learn in this chapter 47 |

48 |
49 | 50 |
51 |
52 |

After you completed this training section you will

53 | 62 |
63 |
64 |
65 | 66 | --- 67 | 68 |
69 |

70 | SIMATIC AX Code IDE 71 |

72 |
73 | 74 |
75 |
76 |

SIMATIC AX Code is an IDE based on Visual Studio Code, an immensly popular open source IDE created by Microsoft.

77 |

The IDE has been enriched with Siemens specific functionality to support the user while engineering a PLC.

78 |
79 | 80 |
81 | 82 | --- 83 | 84 |
85 |

86 | Built-In-Extensions 87 |

88 |
89 | 90 |
91 |
92 |

SIMATIC AX Code comes with a prefabricated set of extensions. Those extensions are available natively inside the IDE, e.g. GIT source control.

93 |
94 | 95 |
96 | 97 | --- 98 | 99 |
100 |

101 | Open VSIX Marketplace 102 |

103 |
104 | 105 |
106 |
107 |

Furthermore you have access to the Open VSIX marketplace and may add your favorite extensions like GitLens.

108 |
109 | 110 |
111 | 112 | --- 113 | 114 |
115 |

116 | Extension Manager 117 |

118 |
119 | 120 |
121 |
122 |

Besides third-party extensions, there are also SIMATIC AX specific extensions. Those extensions are installed via the extension manager, which is integrated into SIMATIC AX Code. The extension manager can also update the installed extensions automatically (optionally).

123 |

Some examples for SIMATIC AX specific extensions:

124 | 130 |
131 | 132 |
133 | 134 | --- 135 | 136 |
137 |

138 | Execute functionality in SIMATIC AX Code 139 |

140 |
141 | 142 |
143 |
144 |

While some of the functionalities of the extensions are accessible via the UI, you may access a more extended set of the functionalities via the command palette. To access them press F1 or Ctrl + Shift + P

145 |

Here you can search for the functionality you require.

146 |
147 | 148 |
149 | 150 | --- 151 | 152 |
153 |

154 | Integrated terminal 155 |

156 |
157 | 158 |
159 |
160 |

The IDE provides a built-in terminal that lets you access the file system and execute CLI commands and scripts inside. You can open a new terminal via the top bar: "Terminal" > "New Terminal".

161 |
162 | 163 |
164 | 165 | --- 166 | 167 |
168 |

169 | Output window 170 |

171 |
172 | 173 |
174 |
175 |

To support the user in debugging extension specific behavior and errors, an output panel is available. In the output panel you can take a look at outputs of various integrated extensions.

176 |

Note that the output panel is always specific to the extension selected and can be switched using the drop down menu on the right.

177 |
178 | 179 |
180 | 181 | --- 182 | 183 |
184 |

185 | Window layout 186 |

187 |
188 | 189 |
190 |
191 |

You may change the current layout of the IDE to your liking. On the top right inside of SIMATIC AX Code you have the possibility to fully customize the layout of the windows.

192 |

You can also drag and drop the tab of the current editor and move it to the desired location

193 |
194 | 195 |
196 | 197 | --- 198 | 199 |
200 |

201 | Autosaving changes 202 |

203 |
204 | 205 |
206 |
207 |

When editing files inside the IDE, changes are not immediately mirrored back to your file system. Unsaved changes in a file won't be considered while executing any of the functionalities inside the IDE.

208 |

Hence, we recommend to always enable auto save

209 |
210 | 211 |
212 | 213 | --- 214 | 215 |
216 |

217 | What did you learn 218 |

219 |
220 | 221 |
222 |
223 |

You learned about...

224 | 229 |
230 |
231 | -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /01_introduction_to_ax_code/slides/theme/simatic-ax.css: -------------------------------------------------------------------------------- 1 | /*! modern-normalize v2.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ 2 | 3 | /* 4 | Document 5 | ======== 6 | */ 7 | 8 | /** 9 | Use a better box model (opinionated). 10 | */ 11 | 12 | *, 13 | ::before, 14 | ::after { 15 | box-sizing: border-box; 16 | } 17 | 18 | html { 19 | /* Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) */ 20 | font-family: 21 | system-ui, 22 | 'Segoe UI', 23 | Roboto, 24 | Helvetica, 25 | Arial, 26 | sans-serif, 27 | 'Apple Color Emoji', 28 | 'Segoe UI Emoji'; 29 | line-height: 1.15; /* 1. Correct the line height in all browsers. */ 30 | -webkit-text-size-adjust: 100%; /* 2. Prevent adjustments of font size after orientation changes in iOS. */ 31 | -moz-tab-size: 4; /* 3. Use a more readable tab size (opinionated). */ 32 | tab-size: 4; /* 3 */ 33 | } 34 | 35 | /* 36 | Sections 37 | ======== 38 | */ 39 | 40 | body { 41 | margin: 0; /* Remove the margin in all browsers. */ 42 | } 43 | body { 44 | background: rgb(0,0,40); 45 | background-color: rgb(0,0,40); 46 | /* Siemens Stone light 35%. White background makes index page unreadable (white links). */ 47 | } 48 | 49 | /* ugly trick to use white background for normal slides */ 50 | .js body { 51 | background: rgb(0,0,40); 52 | background-color: rgb(0,0,40); 53 | } 54 | 55 | section.has-dark-background, 56 | section.has-dark-background h1, 57 | section.has-dark-background h2, 58 | section.has-dark-background h3, 59 | section.has-dark-background h4, 60 | section.has-dark-background h5, 61 | section.has-dark-background h6 { 62 | color: #fff; 63 | } 64 | 65 | section { 66 | display: flex!important; 67 | flex-direction: column; 68 | align-items: left; 69 | text-align: left; 70 | height: 100%; 71 | margin: 1em 1em; 72 | overflow: hidden; 73 | } 74 | 75 | section.centered { 76 | display: flex!important; 77 | flex-direction: column; 78 | align-items: center; 79 | justify-content: center; 80 | text-align: center; 81 | } 82 | 83 | h1, h2, h3, h4, h5, p, td, li { 84 | text-shadow: transparent 0px 0px; 85 | font-family: "Siemens Sans Global", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 86 | font-weight: 700; 87 | line-height: 0.9; 88 | } 89 | 90 | p, td, li { 91 | font-weight: 500; 92 | } 93 | 94 | h1 { 95 | font-size: 5em; 96 | letter-spacing: -0.05em; 97 | background: linear-gradient(90deg, rgb(0, 190, 220), rgb(0, 215, 160)); 98 | -webkit-background-clip: text; /* clip the background to the text inside the tag*/ 99 | background-clip: text; 100 | -webkit-text-fill-color: transparent; /* make the text transparent so the background shows through*/ 101 | padding: 0 0 0.25em 0; 102 | margin: 0 0 0.25em 0; 103 | } 104 | 105 | h2 { 106 | font-size: 3em; 107 | letter-spacing: -0.05em; 108 | background: linear-gradient(90deg, rgb(0, 190, 220), rgb(0, 215, 160)); 109 | -webkit-background-clip: text; /* clip the background to the text inside the tag*/ 110 | background-clip: text; 111 | -webkit-text-fill-color: transparent; /* make the text transparent so the background shows through*/ 112 | padding: 0 0 0.25em 0; 113 | margin: 0 0 0.25em 0; 114 | } 115 | 116 | h3 { 117 | font-size: 2em; 118 | margin: -0.5em 0 0.25em 0; 119 | } 120 | 121 | h4 { 122 | font-size: 1.25em; 123 | font-weight: 900; 124 | } 125 | 126 | p, li { 127 | line-height: 1.75rem; 128 | font-size: 1.2rem; 129 | } 130 | 131 | table { 132 | 133 | } 134 | 135 | th, tr { 136 | line-height: 4rem; 137 | padding: 0.75rem 0rem; 138 | } 139 | td { 140 | padding: 0.5rem 0.05rem; 141 | font-size: 1.25rem; 142 | text-align: left; 143 | } 144 | 145 | .slide_header{ 146 | margin-bottom: 3rem; 147 | } 148 | 149 | .flex-row { 150 | display: flex; 151 | flex-direction: row; 152 | } 153 | 154 | 155 | .flex-col { 156 | max-height: 80%; 157 | display: flex; 158 | flex-direction: column; 159 | } 160 | 161 | .items-stretch{ 162 | align-items: stretch; 163 | } 164 | 165 | .items-center { 166 | align-items: center; 167 | } 168 | 169 | .justify-center { 170 | justify-content: center; 171 | } 172 | 173 | .justify-start { 174 | justify-content: start; 175 | } 176 | 177 | .grid-two-col-eq { 178 | display: grid; 179 | grid-template-columns: repeat(2, minmax(0, 1fr)); 180 | grid-column-gap: 4rem; 181 | } 182 | 183 | .grid-two-col-foc-right { 184 | display: grid; 185 | grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); 186 | grid-column-gap: 4rem; 187 | } 188 | 189 | br { 190 | margin: 2rem; 191 | } 192 | 193 | ul { 194 | margin-top: 0.75rem; 195 | margin-left: 2rem; 196 | } 197 | 198 | li { 199 | margin: 0.25rem 0; 200 | } 201 | 202 | /* 203 | Grouping content 204 | ================ 205 | */ 206 | 207 | /** 208 | 1. Add the correct height in Firefox. 209 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) 210 | */ 211 | 212 | hr { 213 | height: 0; /* 1 */ 214 | color: inherit; /* 2 */ 215 | } 216 | 217 | /* 218 | Text-level semantics 219 | ==================== 220 | */ 221 | 222 | /** 223 | Add the correct text decoration in Chrome, Edge, and Safari. 224 | */ 225 | 226 | abbr[title] { 227 | -webkit-text-decoration: underline dotted; 228 | text-decoration: underline dotted; 229 | } 230 | 231 | /** 232 | Add the correct font weight in Edge and Safari. 233 | */ 234 | 235 | b, 236 | strong { 237 | font-weight: bolder; 238 | } 239 | 240 | /** 241 | 1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) 242 | 2. Correct the odd 'em' font sizing in all browsers. 243 | */ 244 | 245 | code, 246 | kbd, 247 | samp, 248 | pre { 249 | font-family: 250 | ui-monospace, 251 | SFMono-Regular, 252 | Consolas, 253 | 'Liberation Mono', 254 | Menlo, 255 | monospace; /* 1 */ 256 | font-size: 1em; /* 2 */ 257 | } 258 | 259 | /** 260 | Add the correct font size in all browsers. 261 | */ 262 | 263 | small { 264 | font-size: 80%; 265 | } 266 | 267 | /** 268 | Prevent 'sub' and 'sup' elements from affecting the line height in all browsers. 269 | */ 270 | 271 | sub, 272 | sup { 273 | font-size: 75%; 274 | line-height: 0; 275 | position: relative; 276 | vertical-align: baseline; 277 | } 278 | 279 | sub { 280 | bottom: -0.25em; 281 | } 282 | 283 | sup { 284 | top: -0.5em; 285 | } 286 | 287 | /* 288 | Tabular data 289 | ============ 290 | */ 291 | 292 | /** 293 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 294 | 2. Correct table border color inheritance in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 295 | */ 296 | 297 | table { 298 | text-indent: 0; /* 1 */ 299 | border-color: inherit; /* 2 */ 300 | } 301 | -------------------------------------------------------------------------------- /03_loading_and_debugging/apax.yml: -------------------------------------------------------------------------------- 1 | name: 99_template 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/ax/HwConfiguration.hwdat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/assets/ax/HwConfiguration.hwdat -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/ax/HwConfiguration.hwdat.hash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/assets/ax/HwConfiguration.hwdat.hash -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/ax/Meta.json: -------------------------------------------------------------------------------- 1 | { 2 | "FormatVersion": 1, 3 | "Containers": { 4 | "HardwareContainer": "HwConfiguration.hwdat", 5 | "PkiContainer": "PkiContainer.hwdat" 6 | } 7 | } -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/ax/PkiContainer.hwdat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/assets/ax/PkiContainer.hwdat -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/ax/PkiContainer.hwdat.hash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/assets/ax/PkiContainer.hwdat.hash -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/certificateForConnection.crt: -------------------------------------------------------------------------------- 1 | Bag Attributes 2 | localKeyID: EA D0 28 67 48 C6 66 2C 47 4C 47 C4 F8 A3 C9 9F C3 D1 1A 23 3 | subject=C = XX, ST = StateName, L = CityName, O = CompanyName, OU = CompanySectionName, CN = CommonNameOrHostname 4 | 5 | issuer=C = XX, ST = StateName, L = CityName, O = CompanyName, OU = CompanySectionName, CN = CommonNameOrHostname 6 | 7 | -----BEGIN CERTIFICATE----- 8 | MIIDqTCCApGgAwIBAgIUJOa1S67wzjvg03dS6LassartGh8wDQYJKoZIhvcNAQEL 9 | BQAwgYYxCzAJBgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcM 10 | CENpdHlOYW1lMRQwEgYDVQQKDAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFu 11 | eVNlY3Rpb25OYW1lMR0wGwYDVQQDDBRDb21tb25OYW1lT3JIb3N0bmFtZTAeFw0y 12 | NDA2MjYwNzEzMTBaFw0yNTA2MjYwNzEzMTBaMIGGMQswCQYDVQQGEwJYWDESMBAG 13 | A1UECAwJU3RhdGVOYW1lMREwDwYDVQQHDAhDaXR5TmFtZTEUMBIGA1UECgwLQ29t 14 | cGFueU5hbWUxGzAZBgNVBAsMEkNvbXBhbnlTZWN0aW9uTmFtZTEdMBsGA1UEAwwU 15 | Q29tbW9uTmFtZU9ySG9zdG5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK 16 | AoIBAQDS6sZTT0nDfcFxzAf1qpv80GCb0pchb89Pa6SAYBBIxsiA2qqU/6gpcIOs 17 | BA3fxV3JV9pPvMn7o64DHQbt/v88PIgX2o+mtdQII58oy9F1Z0gJYVPkor8c3VgR 18 | opfhwCkA0Hg9bHm8NoAMd5fCGGb/P1t0rQ7LnoVGMZNhkmA4x7IJrC4cqdXUIkc1 19 | 3oBcVdsFySNlNuEnDqwM0IAAFjKrqRhB5V9juSRWa0oqZA+n+kacwnSAjuUo4njj 20 | 2Ir0lCzw/IAChQwU8mFlK3fksmWKPqUh7Tvs6naXoxZObYJnwPx+8ZFqqhhHkms/ 21 | FYvxzcV7i1mnY67jyHF7tO9x2tZhAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZI 22 | hvcNAQELBQADggEBANAnZjdogj0OaBtLu6CFawskgHSLnVHhaYcPqaKf76fWyHNZ 23 | Fnv9ASkXfXdp1Ix+lhMfa8sroy9k7dWIi+Hx19zb8lp83rWLOFp8YE9xJOaoIGAN 24 | QZ8weOB43ijOhVWS3rZQotVS2MzwGMEICwuq8WwObU1xfExGFDK+ZijYpoOxxl55 25 | bLdgMeDiQmxgxqzXK+TfoJKGTBAy0GkYE+TctbAu4TNeoqNyFaxChT7XO0utbBLK 26 | CkS8krfP0tns6MZmyJrX95DvQ5W9pVhDCJvviq93G7ay/XwmmqjCKERI0qjKSyHW 27 | IlMLayofU4wF1lTeTuwG4nnU7FBda6W+2ehKQkc= 28 | -----END CERTIFICATE----- 29 | -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/plcsim_advanced_v6_image.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/assets/plcsim_advanced_v6_image.7z -------------------------------------------------------------------------------- /03_loading_and_debugging/assets/tia/AxHwTemplate.zap19: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/assets/tia/AxHwTemplate.zap19 -------------------------------------------------------------------------------- /03_loading_and_debugging/exercises/0_first_exercise/README.md: -------------------------------------------------------------------------------- 1 | What to do? -------------------------------------------------------------------------------- /03_loading_and_debugging/exercises/0_first_exercise/apax.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/exercises/0_first_exercise/apax.yml -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/DownloadHardwareTia.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/DownloadHardwareTia.gif -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/ExportCertificate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/ExportCertificate.gif -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/PGPCInterface.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/PGPCInterface.gif -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/sdb_logpoint.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/sdb_logpoint.gif -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/sdb_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/sdb_start.png -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/tiaxDirectLoading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/tiaxDirectLoading.png -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/img/watchtable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/img/watchtable.gif -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/03_loading_and_debugging/slides/theme/.DS_Store -------------------------------------------------------------------------------- /03_loading_and_debugging/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /04_introduction_to_st/.gitignore: -------------------------------------------------------------------------------- 1 | .apax 2 | .env 3 | bin 4 | 5 | obj 6 | testresult 7 | -------------------------------------------------------------------------------- /04_introduction_to_st/.tours/additional_information.tour: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://aka.ms/codetour-schema", 3 | "title": "Additional information", 4 | "steps": [ 5 | { 6 | "title": "Introduction", 7 | "description": "# Welcome\r\n\r\nThis tour contains additional information for the basic and advanced ST tour." 8 | }, 9 | { 10 | "title": "Elementary data types", 11 | "description": "# Elementary data types\r\nThe following elementary data types are supported: \r\n \r\n| Type\t\t\t\t| Literal example\t\t\t\t | Domain range\t\t\t\t |Size\t\t\t | Default\t\t\t\t |\r\n| :---------------- | :------------------------------ | :----------------------------- | :---------------- | :------------------------ |\r\n| BOOL\t\t\t\t| TRUE\t\t\t\t\t\t\t | 0 ‥ 1\t\t\t\t\t\t | 1 bit unsigned\t | FALSE |\r\n| BYTE\t\t\t\t| BYTE#2#1111_0101\t\t\t\t | 0 ‥ 255\t\t\t\t\t\t | 8 bit unsigned\t | 0 |\r\n| WORD\t\t\t\t| WORD#60000\t\t\t\t\t | 0 ‥ 65535\t\t\t\t\t | 16 bit unsigned | 0 |\r\n| DWORD\t\t\t\t| DWORD#16#ABCD_EF01\t\t\t | 0 ‥ 4294967295\t\t\t\t | 32 bit unsigned | 0 |\r\n| LWORD\t\t\t\t| LWORD#55\t\t\t\t\t\t | 0 ‥ 18446744073709551615\t | 64 bit unsigned | 0 |\r\n| SINT\t\t\t\t| SINT#-5\t\t\t\t\t\t | -128 ‥ 127\t\t\t\t\t | 8 bit signed\t | 0 |\r\n| INT\t\t\t\t| -5\t\t\t\t\t\t\t | -32768 ‥ 32767\t\t\t\t | 16 bit signed\t | 0 |\r\n| DINT\t\t\t\t| DINT#-56\t\t\t\t\t\t | –2147483648 ‥ 2147483647\t | 32 bit signed\t | 0 |\r\n| LINT\t\t\t\t| LINT#512\t\t\t\t\t\t | -9223372036854775808 ‥ \t | | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 9223372036854775807\t\t\t | 64 bit signed\t | 0 |\r\n| USINT\t\t\t\t| USINT#5\t\t\t\t\t\t | 0 ‥ 255\t\t\t\t\t\t | 8 bit unsigned\t | 0 |\r\n| UINT\t\t\t\t| UINT#512\t\t\t\t\t\t | 0 ‥ 65535\t\t\t\t\t | 16 bit unsigned | 0 |\r\n| UDINT\t\t\t\t| UDINT#512\t\t\t\t\t | 0 ‥ 4294967295\t\t\t\t | 32 bit unsigned | 0 |\r\n| ULINT\t\t\t\t| ULINT#512\t\t\t\t\t | 0 ‥ 18446744073709551615\t | 64 bit unsigned | 0 |\r\n| REAL\t\t\t\t| REAL#5.0\t\t\t\t\t\t | -3.402823e+38 ‥ \t | | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | +3.402823e+38\t\t\t\t | 32 bit (23 bit | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | \t\t\t\t\t\t\t | significant, | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | \t\t\t\t\t\t\t | 8 bit exponent) | 0.0 |\r\n| LREAL\t\t\t\t| 3.14159\t\t\t\t\t\t | -1.79769313486231e+308 ‥ \t | | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 1.79769313486231e+308\t\t | 64 bit (52 bit | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | \t\t\t\t\t\t\t | significant, | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | \t\t\t\t\t\t\t | 11 bit exponent) | 0.0 |\r\n| TIME\t\t\t\t| TIME#12d2h4m8s16ms\t\t\t | –9223372036854ms ‥ \t | | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 9223372036854ms\t\t\t\t | 64 bit signed\t | TIME#0ms |\r\n| LTIME\t\t\t\t| LTIME#100000d2h4m8s16ms32ns\t | -9223372036854775808ns ‥ \t | | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 9223372036854775807ns\t\t | 64 bit signed\t | LTIME#0ns |\r\n| DATE\t\t\t\t| DATE#1980-01-23\t\t\t\t | 1970-01-01 ‥ 2262-04-11\t\t | 64 bit signed\t | DATE#1970-01-01 |\r\n| LDATE\t\t\t\t| LDATE#1980-01-23\t\t\t\t | 1970-01-01 ‥ 2262-04-11\t\t | 64 bit signed\t | LDATE#1970-01-01 |\r\n| TIME_OF_DAY\t\t| TOD#13:14:33.123\t\t\t\t | 0:0:0.0 ‥ \t | \t | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 23:59:59.999999999\t\t\t | 64 bit signed\t | TOD#0:0:0.0 |\r\n| LTIME_OF_DAY\t\t| LTOD#13:14:33.123456\t\t\t | 0:0:0.0 ‥ \t | \t | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 23:59:59.999999999\t\t\t | 64 bit signed\t | LTOD#0:0:0.0 |\r\n| DATE_AND_TIME\t\t| DT#1980-01-23-13:14:33.123\t | 1970-01-01-0:0:0.0 ‥ \t | \t | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 2262-04-11-23:47:16.854775807 | 64 bit signed\t | DT#1970-01-01-0:0:0.0 |\r\n| LDATE_AND_TIME\t| LDT#1980-01-23-13:14:33.123456 | 1970-01-01-0:0:0.0 ‥ | | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t | 2262-04-11-23:47:16.854775807 | 64 bit signed\t | LDT#1970-01-01-0:0:0.0 |\r\n| CHAR\t\t\t\t| CHAR#'C'\t\t\t\t\t\t | 0 ‥ 255\t\t\t\t\t\t | 8 bit\tCHAR#0 | |\r\n| WCHAR\t\t\t\t| WCHAR#\"W\"\t\t\t\t\t \t | 0 ‥ 65535\t\t\t\t\t | 16 bit\tWCHAR#0 | |\r\n| STRING\t\t\t| STRING#'ABC'\t\t\t\t\t | \t\t\t\t\t\t\t | 1-254 characters | '' |\r\n| WSTRING\t\t\t| WSTRING#\"ABC\"\t\t\t\t | \t\t\t\t\t\t\t | 1-16328 wide | |\r\n| \t\t\t\t\t| \t\t\t\t\t\t\t\t |\t\t\t\t\t\t\t\t | characters\t\t | \"\" |\r\n \r\nTo return to [Tour 1 - Global and IO variables][Basic ST#5] click the hyper-link.", 12 | "selection": { 13 | "start": { 14 | "line": 3, 15 | "character": 1 16 | }, 17 | "end": { 18 | "line": 45, 19 | "character": 78 20 | } 21 | } 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /04_introduction_to_st/.tours/monitoring.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/.tours/monitoring.PNG -------------------------------------------------------------------------------- /04_introduction_to_st/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["vsls-contrib.codetour"] 3 | } -------------------------------------------------------------------------------- /04_introduction_to_st/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug live on PLC", 9 | "type": "plc-debug", 10 | "request": "launch", 11 | "program": "${workspaceFolder}", 12 | "ip": "192.168.0.1" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /04_introduction_to_st/apax.yml: -------------------------------------------------------------------------------- 1 | name: "introduction-to-st" 2 | version: 0.0.0 3 | type: app 4 | targets: 5 | - plcsim 6 | variables: 7 | APAX_BUILD_ARGS: 8 | - "--debug" # Generate debug information for target "1500" 9 | devDependencies: 10 | "@ax/sdk": 2311.0.1 11 | scripts: 12 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch 13 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/1_implement_valve/README.md: -------------------------------------------------------------------------------- 1 | ## Exercise 1: Implement a valve 2 | 3 | ### Function Block 'Valve' 4 | 5 | * Write a function block 'Valve' with an interface as shown below 6 | * The function block should be placed within a namespace 'ControlModules' 7 | * Create an instance the valve in VAR_GLOBAL, call it in a Program (hint: VAR_EXTERNAL) 8 | * Download the program to a PLC 9 | * Modify the cmdOpen and watch the outputs of the valve 10 | * The solution for this exercise can be found in exercise 2 11 | 12 | The interface of the valve should look like this: 13 | 14 | 15 | 16 | |parameter name|section|type| 17 | |-|-|-| 18 | |cmdOpen|INPUT|BOOL| 19 | |cmdClose|INPUT|BOOL| 20 | |ctrlOpen|OUTPUT|BOOL| 21 | |ctrlClose|OUTPUT|BOOL| 22 | 23 | The behavior of the valve is shown in the diagram: 24 | 25 | 26 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/1_implement_valve/apax.yml: -------------------------------------------------------------------------------- 1 | name: "implement_valve" 2 | version: 0.0.1 3 | type: app 4 | targets: 5 | - plcsim 6 | variables: 7 | APAX_BUILD_ARGS: 8 | - "--debug" # Generate debug information for target "1500" 9 | devDependencies: 10 | "@ax/sdk": 2504.0.0 11 | catalogs: 12 | "@ax/simatic-ax": ^2504.0.0 13 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/1_implement_valve/img/Valve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/1_implement_valve/img/Valve.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/1_implement_valve/img/ValveBehav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/1_implement_valve/img/ValveBehav.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/1_implement_valve/src/configuration.st: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/1_implement_valve/src/configuration.st -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/1_implement_valve/src/program.st: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/1_implement_valve/src/program.st -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug live on PLC", 9 | "type": "plc-debug", 10 | "request": "launch", 11 | "program": "${workspaceFolder}", 12 | "ip": "192.168.0.1", 13 | "certificate": "C:\\Users\\z004482h\\Desktop/test.cer" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/README.md: -------------------------------------------------------------------------------- 1 | ## Exercise 2: Implement a tank 2 | 3 | ### Function Block 'Tank' 4 | 5 | * Write a function block 'Tank' which has an inlet valve and an outlet valve 6 | * The tank block should be placed within a namespace 'EquipmentModules' 7 | * Logic in Tank: 8 | * Create two instances of the valve (inlet and outlet) 9 | * Call them and set the variables according to the behavior (VAR) 10 | * Create a instance of the tank in the VAR_GLOBAL section 11 | * Call it in a PROGRAM 12 | * Download the program to a PLC 13 | * Modify the variables cmdFill and cmdEmpty of the Tank instance 14 | * Monitor the inletOpen/outletOpen status of the tank 15 | 16 | Interface of the tank: 17 | 18 | drawing 19 | 20 | Behavior of the tank: 21 | drawing 22 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/apax.yml: -------------------------------------------------------------------------------- 1 | name: "implement_tank" 2 | version: 0.0.1 3 | type: app 4 | targets: 5 | - plcsim 6 | variables: 7 | APAX_BUILD_ARGS: 8 | - "--debug" # Generate debug information for target "1500" 9 | devDependencies: 10 | "@ax/sdk": 2504.0.0 11 | catalogs: 12 | "@ax/simatic-ax": ^2504.0.0 13 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/img/Tank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/2_implement_tank/img/Tank.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/img/TankBehav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/2_implement_tank/img/TankBehav.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/src/configuration.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.ControlModules; 2 | USING Siemens.AxTraining; 3 | 4 | CONFIGURATION PLC_1 5 | TASK Main(Interval := T#10ms, Priority := 1); 6 | PROGRAM P1 WITH Main: FluidProgram; 7 | 8 | VAR_GLOBAL 9 | ctrlOpenInletValve : BOOL; 10 | inletValve : Valve; 11 | END_VAR 12 | END_CONFIGURATION -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/src/fluidProgram.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.ControlModules; 2 | 3 | NAMESPACE Siemens.AxTraining 4 | PROGRAM FluidProgram 5 | 6 | VAR_EXTERNAL 7 | ctrlOpenInletValve : BOOL; 8 | inletValve : Valve; 9 | END_VAR 10 | 11 | inletValve(ctrlOpen => ctrlOpenInletValve); 12 | END_PROGRAM 13 | END_NAMESPACE -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/src/valve.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Siemens.AxTraining.ControlModules 2 | 3 | FUNCTION_BLOCK Valve 4 | VAR_INPUT 5 | cmdOpen :BOOL; 6 | cmdClose: BOOL; 7 | END_VAR 8 | VAR_OUTPUT 9 | ctrlOpen :BOOL; 10 | ctrlClose : BOOL; 11 | END_VAR 12 | 13 | ctrlClose := FALSE; 14 | ctrlOpen := FALSE; 15 | IF cmdClose THEN 16 | ctrlClose := TRUE; 17 | ELSIF cmdOpen THEN 18 | ctrlOpen := TRUE; 19 | END_IF; 20 | 21 | END_FUNCTION_BLOCK 22 | 23 | END_NAMESPACE -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/2_implement_tank/watchTable.mon: -------------------------------------------------------------------------------- 1 | ctrlOpenInletValve -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug live on PLC", 9 | "type": "plc-debug", 10 | "request": "launch", 11 | "program": "${workspaceFolder}", 12 | "ip": "192.168.0.1", 13 | "certificate": "C:\\Users\\z004482h\\Desktop/test.cer" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/README.md: -------------------------------------------------------------------------------- 1 | ## Exercise 3: Extended tank functionality 2 | 3 | * The tank should have a feedback signal that indicates the current state of the tank 4 | * Create a enum 'TankState' with the states Filling, Emptying and Stop 5 | * Hint: Create a statemachine and use CASE ... OF 6 | 7 | ### Interface 8 | drawing 9 | 10 | ##### Behavior (Timing diagram) 11 | 12 | drawing 13 | 14 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/apax.yml: -------------------------------------------------------------------------------- 1 | name: "extend_tank_funtionality" 2 | version: 0.0.1 3 | type: app 4 | targets: 5 | - plcsim 6 | variables: 7 | APAX_BUILD_ARGS: 8 | - "--debug" # Generate debug information for target "1500" 9 | devDependencies: 10 | "@ax/sdk": 2504.0.0 11 | catalogs: 12 | "@ax/simatic-ax": ^2504.0.0 13 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/img/TankBehav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/3_extend_tank_functionality/img/TankBehav.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/img/TankBehavState.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/3_extend_tank_functionality/img/TankBehavState.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/img/TankModify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/3_extend_tank_functionality/img/TankModify.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/src/configuration.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining; 2 | 3 | CONFIGURATION PLC_1 4 | TASK Main(Interval := T#10ms, Priority := 1); 5 | PROGRAM P1 WITH Main: FluidProgram; 6 | 7 | VAR_GLOBAL 8 | cmdFillTank : BOOL; 9 | cmdEmptyTank : BOOL; 10 | inletOpenTank : BOOL; 11 | outletOpenTank : BOOL; 12 | END_VAR 13 | END_CONFIGURATION -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/src/fluidProgram.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.EquipmentModules; 2 | 3 | NAMESPACE Siemens.AxTraining 4 | PROGRAM FluidProgram 5 | 6 | VAR_EXTERNAL 7 | cmdFillTank : BOOL; 8 | cmdEmptyTank : BOOL; 9 | inletOpenTank : BOOL; 10 | outletOpenTank : BOOL; 11 | END_VAR 12 | VAR 13 | tank : Tank; 14 | END_VAR 15 | 16 | tank(cmdFill := cmdFillTank, 17 | cmdEmpty := cmdEmptyTank, 18 | inletOpen => inletOpenTank, 19 | outletOpen => outletOpenTank); 20 | END_PROGRAM 21 | END_NAMESPACE -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/src/tank.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.ControlModules; 2 | NAMESPACE Siemens.AxTraining.EquipmentModules 3 | 4 | FUNCTION_BLOCK Tank 5 | 6 | VAR_INPUT 7 | cmdFill : BOOL; 8 | cmdEmpty : BOOL; 9 | END_VAR 10 | VAR_OUTPUT 11 | inletOpen : BOOL; 12 | outletOpen : BOOL; 13 | END_VAR 14 | VAR 15 | inlet : Valve; 16 | outlet : Valve; 17 | END_VAR; 18 | 19 | inlet(cmdOpen := cmdFill, 20 | cmdClose := NOT cmdFill, 21 | ctrlOpen => inletOpen); 22 | outlet(cmdOpen := cmdEmpty, 23 | cmdClose := NOT cmdEmpty, 24 | ctrlOpen => outletOpen); 25 | 26 | END_FUNCTION_BLOCK 27 | 28 | END_NAMESPACE -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/src/valve.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Siemens.AxTraining.ControlModules 2 | 3 | FUNCTION_BLOCK Valve 4 | VAR_INPUT 5 | cmdOpen :BOOL; 6 | cmdClose: BOOL; 7 | END_VAR 8 | VAR_OUTPUT 9 | ctrlOpen :BOOL; 10 | ctrlClose : BOOL; 11 | END_VAR 12 | 13 | ctrlClose := FALSE; 14 | ctrlOpen := FALSE; 15 | IF cmdClose THEN 16 | ctrlClose := TRUE; 17 | ELSIF cmdOpen THEN 18 | ctrlOpen := TRUE; 19 | END_IF; 20 | 21 | END_FUNCTION_BLOCK 22 | 23 | END_NAMESPACE -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/3_extend_tank_functionality/watchTable.mon: -------------------------------------------------------------------------------- 1 | cmdFillTank 2 | cmdEmptyTank 3 | inletOpenTank 4 | outletOpenTank -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug live on PLC", 9 | "type": "plc-debug", 10 | "request": "launch", 11 | "program": "${workspaceFolder}", 12 | "ip": "192.168.0.1", 13 | "certificate": "C:\\Users\\z004482h\\Desktop/test.cer" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/README.md: -------------------------------------------------------------------------------- 1 | ## Exercise 3: Timer for tank 2 | 3 | * Currently the tank switches directly between each state. Try to implement a 10s delay between each state change 4 | * Hint: Use apax add @ax/system-timer to use the system timer. 5 | You will learn more about apax add in chapter 8 Library Development 6 | 7 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/apax.yml: -------------------------------------------------------------------------------- 1 | name: "timer_for_tank" 2 | version: 0.0.1 3 | type: app 4 | targets: 5 | - plcsim 6 | variables: 7 | APAX_BUILD_ARGS: 8 | - "--debug" # Generate debug information for target "1500" 9 | devDependencies: 10 | "@ax/sdk": 2504.0.0 11 | catalogs: 12 | "@ax/simatic-ax": ^2504.0.0 13 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/img/TankModify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/4_timer_for_tank/img/TankModify.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/img/ValveFbClosedBehav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/exercises/4_timer_for_tank/img/ValveFbClosedBehav.png -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/src/configuration.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining; 2 | CONFIGURATION PLC_1 3 | TASK Main(Interval := T#10ms, Priority := 1); 4 | PROGRAM P1 WITH Main: FluidProgram; 5 | 6 | VAR_GLOBAL 7 | enableTank : BOOL; 8 | inletOpenTank : BOOL; 9 | outletOpenTank : BOOL; 10 | END_VAR 11 | END_CONFIGURATION -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/src/fluidProgram.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.ControlModules; 2 | USING Siemens.AxTraining.EquipmentModules; 3 | 4 | NAMESPACE Siemens.AxTraining 5 | PROGRAM FluidProgram 6 | 7 | VAR_EXTERNAL 8 | enableTank : BOOL; 9 | inletOpenTank : BOOL; 10 | outletOpenTank : BOOL; 11 | END_VAR 12 | VAR 13 | tank : Tank; 14 | END_VAR 15 | 16 | tank(enable := enableTank, 17 | inletOpen => inletOpenTank, 18 | outletOpen => outletOpenTank); 19 | END_PROGRAM 20 | END_NAMESPACE 21 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/src/tank.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.ControlModules; 2 | 3 | NAMESPACE Siemens.AxTraining.EquipmentModules 4 | FUNCTION_BLOCK Tank 5 | VAR_INPUT 6 | enable: BOOL; 7 | END_VAR 8 | 9 | VAR_OUTPUT 10 | inletOpen : BOOL; 11 | outletOpen : BOOL; 12 | state : TankState; 13 | END_VAR 14 | 15 | VAR 16 | inlet : Valve; 17 | outlet : Valve; 18 | statemachine : TankState := TankState#Stop; 19 | END_VAR; 20 | 21 | IF NOT enable THEN 22 | statemachine := TankState#Stop; 23 | END_IF; 24 | 25 | CASE statemachine OF 26 | TankState#Stop: 27 | 28 | IF enable THEN 29 | statemachine := TankState#Filling; 30 | inlet(cmdOpen := FALSE, cmdClose := TRUE, ctrlOpen => inletOpen); 31 | outlet(cmdOpen := FALSE, cmdClose := TRUE, ctrlOpen => outletOpen); 32 | END_IF; 33 | TankState#Filling: 34 | 35 | inlet(cmdOpen := TRUE, cmdClose := FALSE, ctrlOpen => inletOpen); 36 | outlet(cmdOpen := FALSE, cmdClose := TRUE, ctrlOpen => outletOpen); 37 | statemachine := TankState#Emptying; 38 | 39 | TankState#Emptying: 40 | 41 | inlet(cmdOpen := FALSE, cmdClose := TRUE, ctrlOpen => inletOpen); 42 | outlet(cmdOpen := TRUE, cmdClose := FALSE, ctrlOpen => outletOpen); 43 | statemachine := TankState#Filling; 44 | END_CASE; 45 | 46 | state := statemachine; 47 | END_FUNCTION_BLOCK 48 | END_NAMESPACE 49 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/src/types.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Siemens.AxTraining.ControlModules 2 | TYPE 3 | TankState : (Filling , Emptying, Stop) := Stop; 4 | END_TYPE 5 | 6 | END_NAMESPACE 7 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/src/valve.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Siemens.AxTraining.ControlModules 2 | 3 | FUNCTION_BLOCK Valve 4 | VAR_INPUT 5 | cmdOpen :BOOL; 6 | cmdClose: BOOL; 7 | END_VAR 8 | VAR_OUTPUT 9 | ctrlOpen :BOOL; 10 | ctrlClose : BOOL; 11 | END_VAR 12 | 13 | ctrlClose := FALSE; 14 | ctrlOpen := FALSE; 15 | 16 | IF cmdClose THEN 17 | ctrlClose := TRUE; 18 | ELSIF cmdOpen THEN 19 | ctrlOpen := TRUE; 20 | END_IF; 21 | 22 | END_FUNCTION_BLOCK 23 | 24 | END_NAMESPACE 25 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/4_timer_for_tank/watchTable.mon: -------------------------------------------------------------------------------- 1 | cmdFillTank 2 | cmdEmptyTank 3 | inletOpenTank 4 | outletOpenTank -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Debug live on PLC", 9 | "type": "plc-debug", 10 | "request": "launch", 11 | "program": "${workspaceFolder}", 12 | "ip": "192.168.0.1", 13 | "certificate": "C:\\Users\\z004482h\\Desktop/test.cer" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/apax.yml: -------------------------------------------------------------------------------- 1 | name: "solution_tank_extension" 2 | version: 0.0.1 3 | type: app 4 | targets: 5 | - plcsim 6 | variables: 7 | APAX_BUILD_ARGS: 8 | - "--debug" # Generate debug information for target "1500" 9 | devDependencies: 10 | "@ax/sdk": 2504.0.0 11 | dependencies: 12 | "@ax/system-timer": 10.0.24 13 | catalogs: 14 | "@ax/simatic-ax": ^2504.0.0 15 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/src/configuration.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining; 2 | CONFIGURATION PLC_1 3 | TASK Main(Interval := T#10ms, Priority := 1); 4 | PROGRAM P1 WITH Main: FluidProgram; 5 | 6 | VAR_GLOBAL 7 | enableTank : BOOL; 8 | inletOpenTank : BOOL; 9 | outletOpenTank : BOOL; 10 | END_VAR 11 | END_CONFIGURATION -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/src/fluidProgram.st: -------------------------------------------------------------------------------- 1 | USING Siemens.AxTraining.ControlModules; 2 | USING Siemens.AxTraining.EquipmentModules; 3 | 4 | NAMESPACE Siemens.AxTraining 5 | PROGRAM FluidProgram 6 | 7 | VAR_EXTERNAL 8 | enableTank : BOOL; 9 | inletOpenTank : BOOL; 10 | outletOpenTank : BOOL; 11 | END_VAR 12 | VAR 13 | tank : Tank; 14 | END_VAR 15 | 16 | tank(enable := enableTank, 17 | inletOpen => inletOpenTank, 18 | outletOpen => outletOpenTank); 19 | END_PROGRAM 20 | END_NAMESPACE 21 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/src/tank.st: -------------------------------------------------------------------------------- 1 | USING System.Timer; 2 | USING Siemens.AxTraining.ControlModules; 3 | NAMESPACE Siemens.AxTraining.EquipmentModules 4 | 5 | FUNCTION_BLOCK Tank 6 | 7 | VAR_INPUT 8 | enable: BOOL; 9 | END_VAR 10 | VAR_OUTPUT 11 | inletOpen : BOOL; 12 | outletOpen : BOOL; 13 | state : TankState; 14 | END_VAR 15 | VAR 16 | inlet : Valve; 17 | outlet : Valve; 18 | fillingDelay : OnDelay; 19 | statemachine : TankState := TankState#Stop; 20 | END_VAR; 21 | 22 | IF NOT enable THEN 23 | statemachine := TankState#Stop; 24 | END_IF; 25 | 26 | CASE statemachine OF 27 | TankState#Stop: 28 | IF enable THEN 29 | statemachine := TankState#Filling; 30 | END_IF; 31 | TankState#Filling: 32 | fillingDelay(signal := TRUE, duration := T#10s); 33 | 34 | inlet(cmdOpen := TRUE, cmdClose := FALSE, ctrlOpen => inletOpen); 35 | outlet(cmdOpen := FALSE, cmdClose := TRUE, ctrlOpen => outletOpen); 36 | 37 | IF fillingDelay.output THEN 38 | fillingDelay(signal := FALSE, duration := T#0s); 39 | statemachine := TankState#Emptying; 40 | END_IF; 41 | 42 | TankState#Emptying: 43 | 44 | fillingDelay(signal := TRUE, duration := T#10s); 45 | 46 | 47 | inlet(cmdOpen := FALSE, cmdClose := TRUE, ctrlOpen => inletOpen); 48 | outlet(cmdOpen := TRUE, cmdClose := FALSE, ctrlOpen => outletOpen); 49 | 50 | IF fillingDelay.output THEN 51 | fillingDelay(signal := FALSE, duration := T#0s); 52 | statemachine := TankState#Filling; 53 | END_IF; 54 | 55 | END_CASE; 56 | 57 | END_FUNCTION_BLOCK 58 | 59 | END_NAMESPACE 60 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/src/types.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Siemens.AxTraining.ControlModules 2 | TYPE 3 | TankState : (Filling , Emptying, Stop) := Stop; 4 | END_TYPE 5 | 6 | END_NAMESPACE 7 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/src/valve.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Siemens.AxTraining.ControlModules 2 | 3 | FUNCTION_BLOCK Valve 4 | VAR_INPUT 5 | cmdOpen :BOOL; 6 | cmdClose: BOOL; 7 | END_VAR 8 | VAR_OUTPUT 9 | ctrlOpen :BOOL; 10 | ctrlClose : BOOL; 11 | END_VAR 12 | 13 | ctrlClose := FALSE; 14 | ctrlOpen := FALSE; 15 | 16 | IF cmdClose THEN 17 | ctrlClose := TRUE; 18 | ELSIF cmdOpen THEN 19 | ctrlOpen := TRUE; 20 | END_IF; 21 | 22 | END_FUNCTION_BLOCK 23 | 24 | END_NAMESPACE 25 | -------------------------------------------------------------------------------- /04_introduction_to_st/exercises/5_solution_exercise_4/watchTable.mon: -------------------------------------------------------------------------------- 1 | enableTank 2 | inletOpenTank 3 | outletOpenTank -------------------------------------------------------------------------------- /04_introduction_to_st/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/04_introduction_to_st/slides/theme/.DS_Store -------------------------------------------------------------------------------- /04_introduction_to_st/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /04_introduction_to_st/src/ExampleProgram.st: -------------------------------------------------------------------------------- 1 | PROGRAM ExampleProgram 2 | VAR_EXTERNAL 3 | //global variables / instances from the configuration 4 | END_VAR 5 | 6 | VAR 7 | // program local variables / instances (static) 8 | END_VAR 9 | 10 | VAR_TEMP 11 | // temporary local variables (will be reset in each cycle) 12 | END_VAR 13 | 14 | ; // program code 15 | END_PROGRAM -------------------------------------------------------------------------------- /04_introduction_to_st/src/Namespace/NamespaceExample.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Circle 2 | FUNCTION Area : LREAL 3 | VAR_INPUT 4 | diameter : LREAL; 5 | END_VAR 6 | VAR CONSTANT 7 | PI : REAL := REAL#3.141592; 8 | END_VAR 9 | Area := diameter ** 2.0 * PI / 4.0; // (d^2*PI)/4; 10 | END_FUNCTION 11 | END_NAMESPACE 12 | 13 | NAMESPACE Square 14 | FUNCTION Area : LREAL 15 | VAR_INPUT 16 | sideLength : LREAL; 17 | END_VAR 18 | Area := sideLength ** 2.0; 19 | END_FUNCTION 20 | END_NAMESPACE -------------------------------------------------------------------------------- /04_introduction_to_st/src/Namespace/UsageOfNameSpace.st: -------------------------------------------------------------------------------- 1 | FUNCTION Calculate : LREAL 2 | VAR_TEMP 3 | result : LREAL; 4 | END_VAR 5 | result := Circle.Area(diameter := 2.0); // full qualified call 6 | result := Square.Area(sideLength := 2.0); // full qualified call 7 | ; 8 | END_FUNCTION -------------------------------------------------------------------------------- /04_introduction_to_st/src/TankFb.st: -------------------------------------------------------------------------------- 1 | FUNCTION_BLOCK Tank 2 | VAR_INPUT 3 | cmdFill : BOOL; // Inlet valve is open 4 | cmdEmptying : BOOL; // Outlet valve is open 5 | cmdFlush : BOOL; // Inlet and outlet valve is open 6 | volume : LREAL; 7 | END_VAR 8 | VAR_IN_OUT 9 | inletValve : Valve; 10 | outletValve : Valve; 11 | END_VAR 12 | ; 13 | END_FUNCTION_BLOCK 14 | -------------------------------------------------------------------------------- /04_introduction_to_st/src/Valve.st: -------------------------------------------------------------------------------- 1 | FUNCTION_BLOCK Valve 2 | VAR_INPUT 3 | cmdOpen : BOOL; 4 | END_VAR 5 | VAR_OUTPUT 6 | ctrlOpen : BOOL; 7 | isOpen : BOOL; 8 | isClosed : BOOL; 9 | END_VAR 10 | ; 11 | END_FUNCTION_BLOCK 12 | -------------------------------------------------------------------------------- /04_introduction_to_st/src/configuration.st: -------------------------------------------------------------------------------- 1 | CONFIGURATION PLC_1 2 | TASK Main (INTERVAL := T#10ms, PRIORITY := 1); 3 | PROGRAM P1 WITH Main : ExampleProgram; 4 | VAR_GLOBAL 5 | CycleCount : INT; // global variable of type integer 6 | Enable : BOOL := TRUE; 7 | END_VAR 8 | VAR_GLOBAL // Another VAR_GLOBAL section 9 | v1ctrlOpen AT %Q0.0 : BOOL; // digital output 10 | v1isClosed AT %I0.0 : BOOL; // digital input 11 | v2ctrlOpen AT %Q0.1 : BOOL; // digital output 12 | v2isClosed AT %I0.1 : BOOL; // digital input 13 | v1 : Valve; // instance of Valve (can be a function block or class) 14 | v2 : Valve; 15 | t1 : Tank := (volume := REAL#100.0); // with initialization 16 | END_VAR 17 | VAR_GLOBAL CONSTANT // Constants 18 | PI : REAL := REAL#3.141592; 19 | END_VAR 20 | END_CONFIGURATION 21 | -------------------------------------------------------------------------------- /05_oop_in_st/.gitignore: -------------------------------------------------------------------------------- 1 | .apax/ 2 | apax-lock.json 3 | -------------------------------------------------------------------------------- /05_oop_in_st/apax.yml: -------------------------------------------------------------------------------- 1 | name: 99_template 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | # present: reveal-md ./slides/new_structure.md --theme ./slides/theme/simatic-ax.css --watch 8 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch 9 | 10 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/.gitignore: -------------------------------------------------------------------------------- 1 | .apax 2 | .env 3 | bin 4 | obj 5 | testresult -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // This is the configuration file for local debugging. This is not needed in a remote environment and can be deleted 3 | // Use IntelliSense to learn about possible attributes. 4 | // Hover to view descriptions of existing attributes. 5 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Debug live on PLC", 10 | "type": "plc-debug", 11 | "request": "launch", 12 | "program": "${workspaceFolder}", 13 | "ip": "192.168.0.1" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/README.md: -------------------------------------------------------------------------------- 1 | ## Hands On (OOP01) 2 | 3 | ---- 4 |
5 | 6 | ### Goal 7 | 8 | Using the introduction to ST exercises as starting point: 9 | 10 | Transform Valve and Tank into classes: 11 | 12 | **Miniumum:** 13 | 14 | - Valve is transformed into Class ValveBase 15 | - Tank is transformed into Class TankBase 16 | 17 | **Voluntary:** 18 | 19 | - ValveWithClosedSensor is transformed into class 20 | - Valve and Tank is instanced in configuration 21 | - Valve and Tank is called in ExampleProgram 22 | - Compile and download it to the PLC 23 | - Check the functionality of the program 24 | 25 | ---- 26 | ### Valve Class 27 | 28 | |Method|Functionality| 29 | |-|-| 30 | |Open()|Open the valve| 31 | |Close()|Close the valve| 32 | |GetState : ValveState| returns the state Undefined, Open, Close (Hint: Enumeration)| 33 | |WriteCyclic(ctrlOpen : BOOL) | for the activation of the digital output. true when valve opened, false when valve is closed| 34 | 35 | **Advice:** do not change the function block. Choose a different namespace instead 36 | 37 | ---- 38 | 39 | SHORT HINT OF THE STRUCTURE OF THE CLASS AND THE ENUM 40 | ```C# 41 | NAMESPACE FluidHandlingClass 42 | CLASS ValveClass 43 | //VARIABLES 44 | _ctrlOpen : BOOL; 45 | _state : ValveState; 46 | 47 | //METHODS 48 | Open(); 49 | Close(); 50 | GetState() : ValveState; 51 | WriteCyclic(VAR_OUTPUT: (ctrlOpen : BOOL)); 52 | END_CLASS 53 | 54 | //ENUM 55 | TYPE ValveState 56 | STATES: Open, Closed, Error, Undefined 57 | END_TYPE 58 | END_NAMESPACE 59 | ``` 60 | ---- 61 | 62 | #### Create the Class Tank 63 | 64 | Transform the function block Tank into a class according the table (next slide) 65 | 66 | ```C# 67 | NAMESPACE FluidHandlingClass 68 | CLASS Tank 69 | inletValve : Valve 70 | outletValve : Valve 71 | Fill() 72 | Emptying() 73 | Flush() 74 | Close() 75 | END_CLASS 76 | END_NAMESPACE 77 | ``` 78 | ---- 79 | 80 | |Method|inletValve|outletValve| 81 | |-|-|-| 82 | |Fill()| OpenInlet() | CloseOutlet()| 83 | |Emptying()|CloseInlet()|OpenOutlet()| 84 | |Flush()|OpenInlet()|OpenOutlet()| 85 | |Close()|CloseInlet()|CloseOutlet()| 86 | 87 | --- -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "oop1" 3 | version: 0.0.1 4 | type: lib 5 | keywords: 6 | - library 7 | author: SIMATIC AX 8 | # Description will be displayed in the apax extension 9 | description: 10 | # Targets to be compiled with 'apax build' 11 | targets: 12 | - "1500" 13 | - llvm 14 | # Dependencies 15 | devDependencies: 16 | "@ax/sdk": 2504.0.0 17 | 18 | # Environment variables 19 | variables: 20 | APAX_BUILD_ARGS: 21 | - "--debug" # Generate debug information for target "1500" 22 | 23 | # Files, which will be shipped with the library 24 | files: 25 | - bin 26 | catalogs: 27 | "@ax/simatic-ax": ^2504.0.0 28 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/src/Tank.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandling 2 | FUNCTION_BLOCK Tank 3 | VAR_INPUT 4 | cmdFill: BOOL; 5 | cmdEmpty: BOOL; 6 | END_VAR 7 | VAR_OUTPUT 8 | inletOpen: BOOL; 9 | outletOpen: BOOL; 10 | END_VAR 11 | VAR 12 | inlet: Valve; 13 | outlet: Valve; 14 | END_VAR 15 | 16 | inlet(cmdOpen := cmdFill, 17 | ctrlOpen => inletOpen); 18 | outlet(cmdOpen := cmdEmpty, 19 | ctrlOpen => outletOpen); 20 | END_FUNCTION_BLOCK 21 | 22 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/src/TankBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS TankBase 6 | VAR 7 | 8 | END_VAR 9 | 10 | METHOD PUBLIC Fill 11 | ; 12 | END_METHOD 13 | 14 | METHOD PUBLIC Flush 15 | ; 16 | END_METHOD 17 | 18 | METHOD PUBLIC Close 19 | ; 20 | END_METHOD 21 | 22 | METHOD PUBLIC Emptying 23 | ; 24 | END_METHOD 25 | 26 | END_CLASS 27 | 28 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/src/Valve.st: -------------------------------------------------------------------------------- 1 | 2 | NAMESPACE FluidHandling 3 | FUNCTION_BLOCK Valve 4 | VAR_INPUT 5 | cmdOpen: BOOL; 6 | END_VAR 7 | VAR_OUTPUT 8 | ctrlOpen : BOOL; 9 | isOpen : BOOL; 10 | isClosed : BOOL; 11 | END_VAR 12 | 13 | IF (cmdOpen) THEN 14 | isOpen := TRUE; 15 | isClosed := FALSE; 16 | ctrlOpen := TRUE; 17 | ELSE 18 | isOpen := FALSE; 19 | isClosed := TRUE; 20 | ctrlOpen := FALSE; 21 | END_IF; 22 | 23 | END_FUNCTION_BLOCK 24 | 25 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/src/ValveBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS ValveBase 6 | VAR 7 | 8 | END_VAR 9 | 10 | METHOD PUBLIC Open 11 | ; 12 | END_METHOD 13 | 14 | METHOD PUBLIC Close 15 | ; 16 | END_METHOD 17 | 18 | METHOD PUBLIC GetState: FluidHandlingClass.ValveState 19 | ; 20 | END_METHOD 21 | 22 | METHOD PUBLIC WriteCyclic 23 | ; 24 | END_METHOD 25 | 26 | END_CLASS 27 | 28 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/src/ValveStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | ValveState : (Open, Closed, Error, Undefined) := Undefined; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/0_basic_valve_class/test/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit; 2 | 3 | NAMESPACE MyTest 4 | 5 | {TestFixture} 6 | CLASS MyTestFixture 7 | 8 | VAR PROTECTED 9 | END_VAR 10 | 11 | {Test} 12 | METHOD PUBLIC MyTestMethod 13 | VAR_TEMP 14 | result : BOOL; 15 | END_VAR 16 | 17 | Assert.Equal(actual := FALSE, expected := FALSE); 18 | 19 | END_METHOD 20 | END_CLASS 21 | 22 | END_NAMESPACE 23 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/README.md: -------------------------------------------------------------------------------- 1 | ## Hands On (OOP02) 2 | 3 | ---- 4 |
5 | 6 | ### Goal 7 | 8 | Using the solution for the HandsOn1 as the starting point: 9 | 10 | 11 | >* Create two interfaces, one for the tanks and the other for the valves. 12 | >* This interface will work as a "contract" that the classes must implement. 13 | >* In this case, we are going to include all the methods implemented in the HandsOn1 in the interface. 14 | 15 | 16 | 17 | ---- 18 | ### Valve Interface 19 | 20 | |**Method**| 21 | |-| 22 | |Open()| 23 | |Close()| 24 | |GetState : ValveState| 25 | |WriteCyclic(ctrlOpen : BOOL) | 26 | 27 | **Advice:** remember that the interface does not include any implementation, only the definition. 28 | 29 | ---- 30 | 31 | ### Tank Interface 32 | 33 | ---- 34 | 35 | |**Method**| 36 | |-| 37 | |Fill()| 38 | |Flush()| 39 | |Close()| 40 | |Emptying()| 41 | 42 | 43 | **Advice:** remember that the interface does not include any implementation, only the definition. 44 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "oop1" 3 | version: 0.0.1 4 | type: lib 5 | keywords: 6 | - library 7 | author: SIMATIC AX 8 | # Description will be displayed in the apax extension 9 | description: 10 | # Targets to be compiled with 'apax build' 11 | targets: 12 | - "1500" 13 | - llvm 14 | # Dependencies 15 | devDependencies: 16 | "@ax/sdk": 2504.0.0 17 | 18 | # Environment variables 19 | variables: 20 | APAX_BUILD_ARGS: 21 | - "--debug" # Generate debug information for target "1500" 22 | 23 | # Files, which will be shipped with the library 24 | files: 25 | - bin 26 | catalogs: 27 | "@ax/simatic-ax": ^2504.0.0 28 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/src/ItfTank.st: -------------------------------------------------------------------------------- 1 | //File to create the interface to implement the class tank 2 | NAMESPACE FluidHandlingClass 3 | 4 | INTERFACE ItfTank 5 | END_INTERFACE 6 | 7 | END_NAMESPACE 8 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/src/ItfValve.st: -------------------------------------------------------------------------------- 1 | //File to create the interface to implement the class valve 2 | //File to create the interface to implement the class tank 3 | NAMESPACE FluidHandlingClass 4 | 5 | INTERFACE ItfValve 6 | END_INTERFACE 7 | 8 | END_NAMESPACE 9 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/src/TankBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS TankBase 6 | VAR PRIVATE 7 | inletValve: ValveBase; 8 | outletValve: ValveBase; 9 | END_VAR 10 | 11 | METHOD PUBLIC Fill 12 | inletValve.Open(); 13 | outletValve.Close(); 14 | END_METHOD 15 | 16 | METHOD PUBLIC Flush 17 | inletValve.Open(); 18 | outletValve.Open(); 19 | END_METHOD 20 | 21 | METHOD PUBLIC Close 22 | inletValve.Close(); 23 | outletValve.Close(); 24 | END_METHOD 25 | 26 | METHOD PUBLIC Emptying 27 | this.Close(); 28 | outletValve.Open(); 29 | END_METHOD 30 | END_CLASS 31 | 32 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/src/ValveBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS ValveBase 6 | VAR 7 | _ctrlOpen : BOOL; 8 | _state : ValveState; 9 | _isClosed : BOOL; 10 | _isOpen : BOOL; 11 | END_VAR 12 | 13 | METHOD PUBLIC Open 14 | _ctrlOpen := TRUE; 15 | _isOpen := TRUE; 16 | _isClosed := FALSE; 17 | END_METHOD 18 | 19 | METHOD PUBLIC Close 20 | _ctrlOpen := FALSE; 21 | _isOpen := FALSE; 22 | _isClosed := TRUE; 23 | END_METHOD 24 | 25 | METHOD PUBLIC GetState: FluidHandlingClass.ValveState 26 | IF (_ctrlOpen) THEN 27 | GetState := ValveState#Open; 28 | ELSE 29 | GetState := ValveState#Closed; 30 | END_IF; 31 | _state := GetState; 32 | END_METHOD 33 | 34 | METHOD PUBLIC WriteCyclic 35 | VAR_OUTPUT 36 | ctrlOpen : BOOL; 37 | isOpen : BOOL; 38 | isClosed : BOOL; 39 | state : ValveState; 40 | END_VAR 41 | ctrlOpen := _ctrlOpen; 42 | isOpen := _isOpen; 43 | isClosed := _isClosed; 44 | state := _state; 45 | END_METHOD 46 | END_CLASS 47 | 48 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/1_interfaces/src/ValveStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | ValveState : (Open, Closed, Error, Undefined) := Undefined; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/README.md: -------------------------------------------------------------------------------- 1 | ## Hands On (OOP03) 2 | 3 | ---- 4 |
5 | 6 | ### Goal 7 | 8 | Using the solution for the HandsOn2 as the starting point: 9 | 10 | 11 | >* **FIRST:** Create a TYPE for the Tank State as the Valve one. 12 | >* **SECOND:** Create a second class: *TankWithVolume* that implements also the interface *ItfTank* created in the HandsOn2. 13 | >* **THIRD:** Create a program that calculates and displays as an output the current volume of the tank . 14 | 15 | 16 | 17 | ---- 18 | ### TYPE for Tank State 19 | 20 | |Status| 21 | |-| 22 | |Filling| 23 | |Emptying| 24 | |Flushing| 25 | |Closed| 26 | 27 | **Advice:** remember that the starting state is closed and you should include it on the definition. 28 | 29 | ---- 30 | 31 | ### Tank with Volume 32 | 33 | ---- 34 | > This tank implements also the ITank interface created on the previous hands On. 35 | 36 | > It also has a new parameter **volume** given as an entry by the user with the tank volume as a REAL. 37 | 38 | > To handle the different status transitions, it will have entries to activate the different states: fill, empty, flush and close. 39 | 40 | > In addition, it has three new methods: 41 | > **WriteCyclic(Capacity : REAL)** 42 | 43 | > **Capacity : REAL** that returns a real with the percentage of capacity of the volume of the tank. 44 | 45 | > **ReadCyclic(Fill : BOOL, Empty : BOOL, Flush : BOOL, Close : BOOL)** to read the entries. 46 | 47 | ---- 48 | 49 | ### Program for calculating and displaying 50 | 51 | ---- 52 | 53 | Structure the program as: 54 | 55 | >1. Declaration of the external variables that you will use on the program: valves, tank, phyisical entries... 56 | 57 | >2. Then, declarate the complements that you will need to execute the program. For example, a timer, the filling and emptying rates... 58 | 59 | >3. Initialize the variables and read the entries that you need. 60 | 61 | > 4. Evaluate the different tank phases and update the current volume in each phase. We define here that the filling/emptying is **5 L/s**. So every second we activate and reinitialize a timer and increment/decrement a variable in 5 units. 62 | 63 | > 5. Write on the outputs. -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "oop1" 3 | version: 0.0.1 4 | type: lib 5 | keywords: 6 | - library 7 | author: SIMATIC AX 8 | # Description will be displayed in the apax extension 9 | description: 10 | # Targets to be compiled with 'apax build' 11 | targets: 12 | - "1500" 13 | - llvm 14 | # Dependencies 15 | devDependencies: 16 | "@ax/sdk": 2504.0.0 17 | 18 | # Environment variables 19 | variables: 20 | APAX_BUILD_ARGS: 21 | - "--debug" # Generate debug information for target "1500" 22 | 23 | # Files, which will be shipped with the library 24 | files: 25 | - bin 26 | catalogs: 27 | "@ax/simatic-ax": ^2504.0.0 28 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/src/ItfTank.st: -------------------------------------------------------------------------------- 1 | //File to create the interface to implement the class tank 2 | NAMESPACE FluidHandlingClass 3 | 4 | INTERFACE ItfTank 5 | METHOD Fill 6 | END_METHOD 7 | METHOD Flush 8 | END_METHOD 9 | METHOD Close 10 | END_METHOD 11 | METHOD Emptying 12 | END_METHOD 13 | END_INTERFACE 14 | 15 | END_NAMESPACE 16 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/src/ItfValve.st: -------------------------------------------------------------------------------- 1 | //File to create the interface to implement the class valve 2 | //File to create the interface to implement the class tank 3 | NAMESPACE FluidHandlingClass 4 | 5 | INTERFACE ItfValve 6 | METHOD Open 7 | END_METHOD 8 | METHOD Close 9 | END_METHOD 10 | METHOD GetState : ValveState 11 | END_METHOD 12 | END_INTERFACE 13 | 14 | END_NAMESPACE 15 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/src/TankBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS TankBase IMPLEMENTS ItfTank 6 | VAR PRIVATE 7 | inletValve: ValveBase; 8 | outletValve: ValveBase; 9 | END_VAR 10 | 11 | METHOD PUBLIC Fill 12 | inletValve.Open(); 13 | outletValve.Close(); 14 | END_METHOD 15 | 16 | METHOD PUBLIC Flush 17 | inletValve.Open(); 18 | outletValve.Open(); 19 | END_METHOD 20 | 21 | METHOD PUBLIC Close 22 | inletValve.Close(); 23 | outletValve.Close(); 24 | END_METHOD 25 | 26 | METHOD PUBLIC Emptying 27 | this.Close(); 28 | outletValve.Open(); 29 | END_METHOD 30 | END_CLASS 31 | 32 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/src/ValveBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS ValveBase IMPLEMENTS ItfValve 6 | VAR 7 | _ctrlOpen : BOOL; 8 | _state : ValveState; 9 | _isClosed : BOOL; 10 | _isOpen : BOOL; 11 | END_VAR 12 | 13 | METHOD PUBLIC Open 14 | _ctrlOpen := TRUE; 15 | _isOpen := TRUE; 16 | _isClosed := FALSE; 17 | END_METHOD 18 | 19 | METHOD PUBLIC Close 20 | _ctrlOpen := FALSE; 21 | _isOpen := FALSE; 22 | _isClosed := TRUE; 23 | END_METHOD 24 | 25 | METHOD PUBLIC GetState: FluidHandlingClass.ValveState 26 | IF (_ctrlOpen) THEN 27 | GetState := ValveState#Open; 28 | ELSE 29 | GetState := ValveState#Closed; 30 | END_IF; 31 | _state := GetState; 32 | END_METHOD 33 | 34 | METHOD PUBLIC WriteCyclic 35 | VAR_OUTPUT 36 | ctrlOpen : BOOL; 37 | isOpen : BOOL; 38 | isClosed : BOOL; 39 | state : ValveState; 40 | END_VAR 41 | ctrlOpen := _ctrlOpen; 42 | isOpen := _isOpen; 43 | isClosed := _isClosed; 44 | state := _state; 45 | END_METHOD 46 | END_CLASS 47 | 48 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/3_calculator_current_volume/src/ValveStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | ValveState : (Open, Closed, Error, Undefined) := Undefined; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/README.md: -------------------------------------------------------------------------------- 1 | ## Hands On (OOP04) 2 | 3 | ---- 4 |
5 | 6 | ### Goal 7 | 8 | Using the solution for the HandsOn3 as the starting point: 9 | 10 | 11 | >* Applying **inheritance** create a class: *ComplexValve* that has an entry: *Regulator* and instead of boolean the regulation can be adjusted from 0 to 100 for both states, open and closed. We will store the regulator value as a protected value that we will read in a method called *ReadCyclic*. For example: if the regulator for the entry valve is 30, the valve will be opened the 30%. 12 | 13 | >* For testing in next chapter, here also in the *ComplexValve* we will overwrite the methods Open/Close but we will not use them. Give this methods an entry variable with an integer of the percentage of regulation for the valve. And return the same regulation value but in decimal (as a real). The interface will consider this methods as new methods and do not lead to problems on the implementation. 14 | 15 | >* Applying **inheritance** create a file: *TankWithShape* that has an two classes: *CylindricalTank* and *CubicTank*. These classes extend the properties of the *TankWithVolume* but now the volume is calculated with a method called *VolumeCalculator* and the result stored in the property *volume*. 16 | 17 | > * For the cylindrical tank it is needed to provide to the method the properties: *radius* and *height* 18 | > * For the cube tank only a single property (it is a regular cube): *side_length* 19 | 20 | ---- 21 | 22 | >* With this new valves, **modify the previous volume calculator**. To guide you through the process and facilitate the understanding: 23 | > * You need to modify the filling/emptying rate by multiplying the rate plus the regulation value. This regulation value is a value that is needed to read from an entry of the valve in the first program lines after the declaration of variables. 24 | 25 | > * To use the new classes tankCube/tankCylinder, choose your favorite and provide the properties in the declaration. Then, in the initialization call the method to Calculate the tank volume that writes on the tank property volume. 26 | 27 | 28 | **For example**: If the regulation is 50% on the entry valve. In this case, the filling rate will be: 5 * 50/100 = 2.5 L/s. So here, every second that the timer is executed you add to the current_volume := current_volume + filling_rate * MAX_FILLING_RATE; 29 | 30 | 31 | >* **HINT:** Now for the **flushing state** you must take into account that the filling and emptying rates can be different. So in this state the tank can be filled or emptied too. 32 | 33 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "oop1" 3 | version: 0.0.1 4 | type: app 5 | keywords: 6 | - library 7 | author: SIMATIC AX 8 | # Description will be displayed in the apax extension 9 | description: 10 | # Targets to be compiled with 'apax build' 11 | targets: 12 | - "1500" 13 | - llvm 14 | # Dependencies 15 | devDependencies: 16 | "@ax/sdk": 2504.0.0 17 | 18 | # Environment variables 19 | variables: 20 | APAX_BUILD_ARGS: 21 | - "--debug" # Generate debug information for target "1500" 22 | 23 | # Files, which will be shipped with the library 24 | files: 25 | - bin 26 | dependencies: 27 | "@ax/system-timer": 10.0.24 28 | catalogs: 29 | "@ax/simatic-ax": ^2504.0.0 30 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/ItfTank.st: -------------------------------------------------------------------------------- 1 | //File to create the interface to implement the class tank 2 | NAMESPACE FluidHandlingClass 3 | 4 | INTERFACE ItfTank 5 | METHOD Fill 6 | END_METHOD 7 | METHOD Flush 8 | END_METHOD 9 | METHOD Close 10 | END_METHOD 11 | METHOD Emptying 12 | END_METHOD 13 | END_INTERFACE 14 | 15 | END_NAMESPACE 16 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/ItfValve.st: -------------------------------------------------------------------------------- 1 | //File to create the interface to implement the class valve 2 | //File to create the interface to implement the class tank 3 | NAMESPACE FluidHandlingClass 4 | 5 | INTERFACE ItfValve 6 | METHOD Open 7 | END_METHOD 8 | METHOD Close 9 | END_METHOD 10 | METHOD GetState : ValveState 11 | END_METHOD 12 | END_INTERFACE 13 | 14 | END_NAMESPACE 15 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/TankBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS TankBase IMPLEMENTS ItfTank 6 | VAR PRIVATE 7 | inletValve: ValveBase; 8 | outletValve: ValveBase; 9 | END_VAR 10 | 11 | METHOD PUBLIC Fill 12 | inletValve.Open(); 13 | outletValve.Close(); 14 | END_METHOD 15 | 16 | METHOD PUBLIC Flush 17 | inletValve.Open(); 18 | outletValve.Open(); 19 | END_METHOD 20 | 21 | METHOD PUBLIC Close 22 | inletValve.Close(); 23 | outletValve.Close(); 24 | END_METHOD 25 | 26 | METHOD PUBLIC Emptying 27 | this.Close(); 28 | outletValve.Open(); 29 | END_METHOD 30 | END_CLASS 31 | 32 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/TankStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | TankState : (Filling, Emptying, Flushing, Close) := Close; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/TankWithVolume.st: -------------------------------------------------------------------------------- 1 | USING FluidHandlingClass; 2 | 3 | NAMESPACE FluidHandlingClass 4 | CLASS TankWithVolume IMPLEMENTS ItfTank 5 | VAR PUBLIC 6 | inletValve: ItfValve; 7 | outletValve: ItfValve; 8 | volume: REAL; 9 | END_VAR 10 | VAR PROTECTED 11 | _capacity : REAL; 12 | _fill : BOOL; 13 | _empty : BOOL; 14 | _flush : BOOL; 15 | _close : BOOL; 16 | END_VAR 17 | 18 | 19 | METHOD PUBLIC Capacity : REAL 20 | VAR_INPUT 21 | currentVolume : REAL; 22 | END_VAR 23 | _capacity := (currentVolume / volume) * 100; 24 | END_METHOD 25 | 26 | METHOD PUBLIC OpenInlet 27 | inletValve.Open(); 28 | END_METHOD 29 | METHOD PUBLIC OpenOutlet 30 | outletValve.Open(); 31 | END_METHOD 32 | METHOD PUBLIC CloseInlet 33 | inletValve.Close(); 34 | END_METHOD 35 | METHOD PUBLIC CloseOutlet 36 | outletValve.Close(); 37 | END_METHOD 38 | 39 | METHOD PUBLIC Fill 40 | this.OpenInlet(); 41 | this.CloseOutlet(); 42 | END_METHOD 43 | 44 | METHOD PUBLIC Flush 45 | this.OpenInlet(); 46 | this.OpenOutlet(); 47 | END_METHOD 48 | 49 | METHOD PUBLIC Close 50 | this.CloseInlet(); 51 | this.CloseOutlet(); 52 | END_METHOD 53 | 54 | METHOD PUBLIC Emptying 55 | this.CloseInlet(); 56 | this.OpenOutlet(); 57 | END_METHOD 58 | METHOD PUBLIC ReadCyclic 59 | VAR_INPUT 60 | Fill : BOOL; 61 | Empty : BOOL; 62 | Flush : BOOL; 63 | Close : BOOL; 64 | END_VAR 65 | _fill := Fill; 66 | _empty := Empty; 67 | _flush := Flush; 68 | _close := Close; 69 | END_METHOD 70 | METHOD PUBLIC WriteCyclic 71 | VAR_OUTPUT 72 | Capacity : REAL; 73 | END_VAR 74 | Capacity := _capacity; 75 | END_METHOD 76 | 77 | 78 | END_CLASS 79 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/ValveBase.st: -------------------------------------------------------------------------------- 1 | //Use the same namespace than the TYPE for the Valves state 2 | 3 | NAMESPACE FluidHandlingClass 4 | 5 | CLASS ValveBase IMPLEMENTS ItfValve 6 | VAR 7 | _ctrlOpen : BOOL; 8 | _state : ValveState; 9 | _isClosed : BOOL; 10 | _isOpen : BOOL; 11 | END_VAR 12 | 13 | METHOD PUBLIC Open 14 | _ctrlOpen := TRUE; 15 | _isOpen := TRUE; 16 | _isClosed := FALSE; 17 | END_METHOD 18 | 19 | METHOD PUBLIC Close 20 | _ctrlOpen := FALSE; 21 | _isOpen := FALSE; 22 | _isClosed := TRUE; 23 | END_METHOD 24 | 25 | METHOD PUBLIC GetState: FluidHandlingClass.ValveState 26 | IF (_ctrlOpen) THEN 27 | GetState := ValveState#Open; 28 | ELSE 29 | GetState := ValveState#Closed; 30 | END_IF; 31 | _state := GetState; 32 | END_METHOD 33 | 34 | METHOD PUBLIC WriteCyclic 35 | VAR_OUTPUT 36 | ctrlOpen : BOOL; 37 | isOpen : BOOL; 38 | isClosed : BOOL; 39 | state : ValveState; 40 | END_VAR 41 | ctrlOpen := _ctrlOpen; 42 | isOpen := _isOpen; 43 | isClosed := _isClosed; 44 | state := _state; 45 | END_METHOD 46 | END_CLASS 47 | 48 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/ValveStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | ValveState : (Open, Closed, Error, Undefined) := Undefined; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/configuration.st: -------------------------------------------------------------------------------- 1 | USING FluidHandlingClass; 2 | CONFIGURATION MyConfiguration 3 | TASK Main(Interval := T#1000ms, Priority := 1); 4 | PROGRAM P1 WITH Main: CalculatorCurrentVolume; 5 | VAR_GLOBAL 6 | 7 | //FIRST IMPLEMENTATION SIMPLE 8 | vIn : ValveBase; 9 | vOut: ValveBase; 10 | tank : TankWithVolume := (inletValve := vIn, outletValve := vOut, volume := 100); 11 | 12 | 13 | //SIMPLE VALVES 14 | vInCtrl AT %Q1.0 : BOOL; 15 | vOutCtrl AT %Q1.1 : BOOL; 16 | 17 | vInOpen : BOOL; 18 | vOutOpen : BOOL; 19 | vInClosed : BOOL; 20 | vOutClosed : BOOL; 21 | 22 | statusIn : ValveState; 23 | statusOut : ValveState; 24 | 25 | 26 | //CONTROL TANK 27 | Close AT %I0.0 : BOOL; 28 | Fill AT %I0.1 : BOOL; 29 | Empty AT %I0.2 : BOOL; 30 | Flush AT %I0.3 : BOOL; 31 | phase : TankState; 32 | END_VAR 33 | END_CONFIGURATION 34 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/4_inheritance_complex_valve/src/program.st: -------------------------------------------------------------------------------- 1 | USING FluidHandlingClass; 2 | USING System.Timer; 3 | 4 | // Imagine that the filling rate is 5 L/s when the inlet valve is Open 5 | 6 | PROGRAM CalculatorCurrentVolume 7 | VAR_EXTERNAL 8 | vIn : ValveBase; 9 | vOut : ValveBase; 10 | tank : TankWithVolume; 11 | 12 | vInCtrl : BOOL; 13 | vOutCtrl : BOOL; 14 | 15 | vInOpen : BOOL; 16 | vOutOpen : BOOL; 17 | vInClosed : BOOL; 18 | vOutClosed : BOOL; 19 | statusIn : ValveState; 20 | statusOut : ValveState; 21 | 22 | Close : BOOL; 23 | Fill : BOOL; 24 | Empty : BOOL; 25 | Flush : BOOL; 26 | phase : TankState; 27 | END_VAR 28 | VAR 29 | _ton : OnDelay := (duration := T#1s); 30 | _duration_max : LTIME; 31 | current_volume : REAL := 0; 32 | capacity_percentage : REAL; 33 | _filling_rate : REAL; 34 | _emptying_rate: REAL; 35 | 36 | END_VAR 37 | _ton(); 38 | _duration_max := TO_LTIME(TO_LINT(tank.volume / 5)); //Conversion to Time values 39 | _filling_rate := 1; //LATER EXPRESSION WITH THE OPENING/CLOSING RATES 40 | _emptying_rate := 1; //SAME AS FILLING RATE 41 | capacity_percentage := tank.Capacity(currentVolume := current_volume); 42 | statusIn := vIn.GetState(); 43 | statusOut := vOut.GetState(); 44 | tank.ReadCyclic(Fill := Fill, Empty := Empty, Flush := Flush, Close := Close); 45 | 46 | CASE phase OF 47 | //----------------------------------- 48 | // here's the tank phase close 49 | //----------------------------------- 50 | 51 | TankState#Close: 52 | tank.Close(); 53 | IF (Fill) THEN 54 | _ton.signal := TRUE; 55 | phase := TankState#Filling; 56 | END_IF; 57 | IF (Empty) THEN 58 | _ton.signal := TRUE; 59 | phase:= TankState#Emptying; 60 | END_IF; 61 | IF (Flush) THEN 62 | _ton.signal := TRUE; 63 | phase := TankState#Flushing; 64 | END_IF; 65 | // next phase after timeout 66 | 67 | //----------------------------------- 68 | // here's the tank phase Filling 69 | //----------------------------------- 70 | TankState#Filling: 71 | 72 | // next phase after timeout 73 | IF (Fill) THEN 74 | tank.Fill(); 75 | IF (capacity_percentage > 100) THEN 76 | _ton.signal := FALSE; 77 | phase := TankState#Close; 78 | END_IF; 79 | IF _ton.output THEN 80 | _ton.signal := FALSE; 81 | current_volume := current_volume + 5 *_filling_rate; //Increment the volume in 5 Liters per second 82 | IF current_volume > tank.volume THEN 83 | current_volume := tank.volume; //Ensure volume does not exceed the maximum volume 84 | END_IF; 85 | capacity_percentage := tank.Capacity(currentVolume := current_volume);; // Actualize the capacity percentage 86 | _ton.signal := TRUE; // Reinitialize the timer 87 | END_IF; 88 | 89 | ELSE 90 | _ton.signal := FALSE; 91 | phase := TankState#Close; 92 | END_IF; 93 | //----------------------------------- 94 | // here's the tank phase Emptying 95 | //----------------------------------- 96 | TankState#Emptying: 97 | IF (Empty) THEN 98 | tank.Emptying(); 99 | IF (capacity_percentage <= 0) THEN 100 | _ton.signal := FALSE; 101 | phase := TankState#Close; 102 | END_IF; 103 | IF _ton.output THEN 104 | _ton.signal := FALSE; 105 | current_volume := current_volume - 5 *_emptying_rate; //Reduce the volume in 5 Liters per second 106 | IF current_volume < 0 THEN 107 | current_volume := 0; // //Ensure volume does not exceed the minimum volume 108 | END_IF; 109 | capacity_percentage := tank.Capacity(currentVolume := current_volume);; //Actualize the capacity percentage 110 | _ton.signal := TRUE; // Reinitialize the timer 111 | END_IF; 112 | 113 | ELSE 114 | _ton.signal := FALSE; 115 | phase := TankState#Close; 116 | END_IF; 117 | //----------------------------------- 118 | // here's the tank phase Flushing (HERE THAT THE FILLING AND EMPTYING RATE IS THE SAME DOESN'T DO ANYTHING) 119 | //----------------------------------- 120 | TankState#Flushing: 121 | IF Flush THEN 122 | tank.Flush(); 123 | _ton.signal := TRUE; 124 | 125 | ELSE 126 | _ton.signal := FALSE; 127 | phase := TankState#Close; 128 | END_IF; 129 | END_CASE; 130 | 131 | 132 | vIn.WriteCyclic(ctrlOpen => vInCtrl, isOpen => vInOpen, isClosed => vInClosed, state => statusIn); 133 | vOut.WriteCyclic(ctrlOpen => vOutCtrl, isOpen => vOutOpen, isClosed => vOutClosed, state => statusOut); 134 | tank.WriteCyclic(Capacity => capacity_percentage); 135 | END_PROGRAM -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/README.md: -------------------------------------------------------------------------------- 1 | Final solution to volume calculator with regulation valves and a tank with a specific shape. -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "oop1" 3 | version: 0.0.1 4 | type: lib 5 | keywords: 6 | - library 7 | author: SIMATIC AX 8 | # Description will be displayed in the apax extension 9 | description: 10 | # Targets to be compiled with 'apax build' 11 | targets: 12 | - "1500" 13 | - llvm 14 | # Dependencies 15 | devDependencies: 16 | "@ax/sdk": 2504.0.0 17 | 18 | # Environment variables 19 | variables: 20 | APAX_BUILD_ARGS: 21 | - "--debug" # Generate debug information for target "1500" 22 | 23 | # Files, which will be shipped with the library 24 | files: 25 | - bin 26 | catalogs: 27 | "@ax/simatic-ax": ^2504.0.0 28 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/CalculatorWithRegulation.st: -------------------------------------------------------------------------------- 1 | USING FluidHandlingInterfaces; 2 | USING FluidHandlingClass; 3 | USING System.Timer; 4 | 5 | // Imagine that the filling rate is 5 L/s when the inlet valve is Open, so to calculate the maximum filling time: VOLUME TANK/ 5 L/s = TIME FOR TIMER 6 | 7 | 8 | 9 | //CHANGE EVERYTHING FOR REGULATION 10 | PROGRAM CalculatorWithRegulation 11 | VAR_EXTERNAL 12 | vInEntry : ValveWithEntry; 13 | vOutEntry : ValveWithEntry; 14 | tankCube : FluidHandlingInterfaces.CubicTank; 15 | tankCylinder : FluidHandlingInterfaces.CylindricalTank; 16 | 17 | 18 | vInCtrlEntry : BYTE; 19 | vOutCtrlEntry : BYTE; 20 | vInRegulator : BYTE; 21 | vOutRegulator : BYTE; 22 | 23 | statusInR : ValveState; 24 | statusOutR : ValveState; 25 | 26 | Close : BOOL; 27 | Fill : BOOL; 28 | Empty : BOOL; 29 | Flush : BOOL; 30 | phase : TankState; 31 | END_VAR 32 | VAR 33 | _ton : OnDelay := (duration := T#1s); 34 | _duration_max : LTIME; 35 | current_volume : REAL := 0; 36 | capacity_percentage : REAL; 37 | _filling_rate : REAL; 38 | _emptying_rate: REAL; 39 | END_VAR 40 | _ton(); 41 | 42 | tankCube.VolumeCalculator(); 43 | 44 | vInEntry.ReadCyclic(Regulator := TO_REAL(TO_INT(vInRegulator))); 45 | vOutEntry.ReadCyclic(Regulator := TO_REAL(TO_INT(vOutRegulator))); 46 | //_duration_max := TO_LTIME(TO_LINT(tank.volume / 5)); //Conversion to Time values 47 | _filling_rate := TO_INT(vInRegulator)/100; 48 | _emptying_rate := TO_INT(vOutRegulator)/100; 49 | statusInR := vInEntry.GetState(); 50 | statusOutR := vOutEntry.GetState(); 51 | 52 | 53 | tankCube.ReadCyclic(Fill := Fill, Empty := Empty, Flush := Flush, Close := Close); 54 | 55 | CASE phase OF 56 | //----------------------------------- 57 | // here's the tank phase close 58 | //----------------------------------- 59 | 60 | 61 | TankState#Close: 62 | tankCube.Close(); 63 | IF (Fill) THEN 64 | _ton.signal := TRUE; 65 | phase := TankState#Filling; 66 | END_IF; 67 | IF (Empty) THEN 68 | _ton.signal := TRUE; 69 | phase:= TankState#Emptying; 70 | END_IF; 71 | IF (Flush) THEN 72 | _ton.signal := TRUE; 73 | phase := TankState#Flushing; 74 | END_IF; 75 | // next phase after timeout 76 | 77 | //----------------------------------- 78 | // here's the tank phase Filling 79 | //----------------------------------- 80 | TankState#Filling: 81 | 82 | // next phase after timeout 83 | IF (Fill) THEN 84 | tankCube.Fill(); 85 | IF (capacity_percentage > 100) THEN 86 | _ton.signal := FALSE; 87 | phase := TankState#Close; 88 | END_IF; 89 | IF _ton.output THEN 90 | _ton.signal := FALSE; 91 | current_volume := current_volume + 5 *_filling_rate; // Incrementar el volumen en 5 litros por segundo 92 | IF current_volume > tankCube.volume THEN 93 | current_volume := tankCube.volume; // Asegurar que el volumen no exceda el máximo 94 | END_IF; 95 | capacity_percentage := (current_volume / tankCube.volume) * 100; // Actualizar el porcentaje de capacidad 96 | _ton.signal := TRUE; // Reiniciar el temporizador 97 | END_IF; 98 | 99 | ELSE 100 | _ton.signal := FALSE; 101 | phase := TankState#Close; 102 | END_IF; 103 | //----------------------------------- 104 | // here's the tank phase Emptying 105 | //----------------------------------- 106 | TankState#Emptying: 107 | IF (Empty) THEN 108 | tankCube.Emptying(); 109 | IF (capacity_percentage <= 0) THEN 110 | _ton.signal := FALSE; 111 | phase := TankState#Close; 112 | END_IF; 113 | IF _ton.output THEN 114 | _ton.signal := FALSE; 115 | current_volume := current_volume - 5 *_emptying_rate; // Incrementar el volumen en 5 litros por segundo 116 | IF current_volume < 0 THEN 117 | current_volume := 0; // Asegurar que el volumen no exceda el mínimo 118 | END_IF; 119 | capacity_percentage := (current_volume / tankCube.volume) * 100; // Actualizar el porcentaje de capacidad 120 | _ton.signal := TRUE; // Reiniciar el temporizador 121 | END_IF; 122 | 123 | ELSE 124 | _ton.signal := FALSE; 125 | phase := TankState#Close; 126 | END_IF; 127 | //----------------------------------- 128 | // here's the tank phase Flushing 129 | //----------------------------------- 130 | TankState#Flushing: 131 | IF Flush THEN 132 | tankCube.Flush(); 133 | _ton.signal := TRUE; 134 | IF (capacity_percentage <= 0) THEN 135 | _ton.signal := FALSE; 136 | phase := TankState#Close; 137 | END_IF; 138 | IF (capacity_percentage >= 100) THEN 139 | _ton.signal := FALSE; 140 | phase := TankState#Close; 141 | END_IF; 142 | IF _ton.output THEN 143 | _ton.signal := FALSE; 144 | current_volume := current_volume + 5 * _filling_rate - 5 *_emptying_rate; 145 | IF current_volume < 0 THEN 146 | current_volume := 0; 147 | END_IF; 148 | IF current_volume > 100 THEN 149 | current_volume := 100; 150 | END_IF; 151 | capacity_percentage := (current_volume / tankCube.volume) * 100; 152 | _ton.signal := TRUE; 153 | END_IF; 154 | ELSE 155 | _ton.signal := FALSE; 156 | phase := TankState#Close; 157 | END_IF; 158 | END_CASE; 159 | 160 | vInEntry.WriteCyclic(ctrlOpen => vInCtrlEntry); 161 | vOutEntry.WriteCyclic(ctrlOpen => vOutCtrlEntry); 162 | tankCube.WriteCyclic(Capacity => capacity_percentage); 163 | END_PROGRAM -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/ITank.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingInterfaces 2 | INTERFACE ITank 3 | 4 | METHOD OpenInlet 5 | END_METHOD 6 | METHOD OpenOutlet 7 | END_METHOD 8 | METHOD CloseInlet 9 | END_METHOD 10 | METHOD CloseOutlet 11 | END_METHOD 12 | 13 | METHOD Fill 14 | END_METHOD 15 | METHOD Flush 16 | END_METHOD 17 | 18 | METHOD Close 19 | END_METHOD 20 | 21 | METHOD Emptying 22 | END_METHOD 23 | 24 | END_INTERFACE 25 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/IValve.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | INTERFACE IValve 3 | METHOD Open 4 | END_METHOD 5 | METHOD Close 6 | END_METHOD 7 | METHOD GetState : ValveState 8 | END_METHOD 9 | END_INTERFACE 10 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/TankStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | TankState : (Filling, Emptying, Flushing, Close) := Close; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/TankWithShape.st: -------------------------------------------------------------------------------- 1 | //USING System.Math; 2 | NAMESPACE FluidHandlingInterfaces 3 | CLASS CylindricalTank EXTENDS TankWithVolume 4 | VAR PUBLIC 5 | radium : REAL; 6 | height : REAL; 7 | END_VAR 8 | METHOD VolumeCalculator : REAL 9 | //volume := TO_REAL(Constants#PI) * radium * radium * height; 10 | volume := TO_REAL(3.14) * radium * radium * height; // PI is considered Long Real and If I don't change it to real you need to change everything 11 | END_METHOD 12 | END_CLASS 13 | 14 | CLASS CubicTank EXTENDS TankWithVolume 15 | VAR PUBLIC 16 | side_length : REAL; 17 | END_VAR 18 | METHOD VolumeCalculator : REAL 19 | volume := side_length * side_length * side_length; 20 | END_METHOD 21 | END_CLASS 22 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/TankWithVolume.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingInterfaces 2 | CLASS TankWithVolume IMPLEMENTS ITank 3 | VAR PUBLIC 4 | inletValve: IValve; 5 | outletValve: IValve; 6 | volume: REAL; 7 | END_VAR 8 | VAR PROTECTED 9 | _capacity : REAL; 10 | _fill : BOOL; 11 | _empty : BOOL; 12 | _flush : BOOL; 13 | _close : BOOL; 14 | END_VAR 15 | 16 | 17 | METHOD PUBLIC Capacity : REAL 18 | VAR_INPUT 19 | currentVolume : REAL; 20 | END_VAR 21 | _capacity := (currentVolume / volume) * 100; 22 | END_METHOD 23 | 24 | METHOD PUBLIC OpenInlet 25 | inletValve.Open(); 26 | END_METHOD 27 | METHOD PUBLIC OpenOutlet 28 | outletValve.Open(); 29 | END_METHOD 30 | METHOD PUBLIC CloseInlet 31 | inletValve.Close(); 32 | END_METHOD 33 | METHOD PUBLIC CloseOutlet 34 | outletValve.Close(); 35 | END_METHOD 36 | 37 | METHOD PUBLIC Fill 38 | this.OpenInlet(); 39 | this.CloseOutlet(); 40 | END_METHOD 41 | 42 | METHOD PUBLIC Flush 43 | this.OpenInlet(); 44 | this.OpenOutlet(); 45 | END_METHOD 46 | 47 | METHOD PUBLIC Close 48 | this.CloseInlet(); 49 | this.CloseOutlet(); 50 | END_METHOD 51 | 52 | METHOD PUBLIC Emptying 53 | this.CloseInlet(); 54 | this.OpenOutlet(); 55 | END_METHOD 56 | METHOD PUBLIC ReadCyclic 57 | VAR_INPUT 58 | Fill : BOOL; 59 | Empty : BOOL; 60 | Flush : BOOL; 61 | Close : BOOL; 62 | END_VAR 63 | _fill := Fill; 64 | _empty := Empty; 65 | _flush := Flush; 66 | _close := Close; 67 | END_METHOD 68 | METHOD PUBLIC WriteCyclic 69 | VAR_OUTPUT 70 | Capacity : REAL; 71 | END_VAR 72 | Capacity := _capacity; 73 | END_METHOD 74 | 75 | 76 | END_CLASS 77 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/ValveStates.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | TYPE 3 | ValveState : (Open, Closed, Error, Undefined) := Undefined; 4 | END_TYPE 5 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/basicValve.st: -------------------------------------------------------------------------------- 1 | NAMESPACE FluidHandlingClass 2 | CLASS basicValve IMPLEMENTS IValve 3 | VAR 4 | _ctrlOpen : BOOL; 5 | _state : ValveState; 6 | _isClosed : BOOL; 7 | _isOpen : BOOL; 8 | END_VAR 9 | 10 | METHOD PUBLIC Open 11 | _ctrlOpen := TRUE; 12 | _isOpen := TRUE; 13 | _isClosed := FALSE; 14 | END_METHOD 15 | 16 | METHOD PUBLIC Close 17 | _ctrlOpen := FALSE; 18 | _isOpen := FALSE; 19 | _isClosed := TRUE; 20 | END_METHOD 21 | 22 | METHOD PUBLIC GetState: FluidHandlingClass.ValveState 23 | IF (_ctrlOpen) THEN 24 | GetState := ValveState#Open; 25 | ELSE 26 | GetState := ValveState#Closed; 27 | END_IF; 28 | _state := GetState; 29 | END_METHOD 30 | 31 | METHOD PUBLIC WriteCyclic 32 | VAR_OUTPUT 33 | ctrlOpen : BOOL; 34 | isOpen : BOOL; 35 | isClosed : BOOL; 36 | state : ValveState; 37 | END_VAR 38 | ctrlOpen := _ctrlOpen; 39 | isOpen := _isOpen; 40 | isClosed := _isClosed; 41 | state := _state; 42 | END_METHOD 43 | END_CLASS 44 | END_NAMESPACE 45 | -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/complexValve.st: -------------------------------------------------------------------------------- 1 | USING FluidHandlingClass; 2 | NAMESPACE FluidHandlingInterfaces 3 | CLASS ValveWithEntry EXTENDS basicValve 4 | VAR PROTECTED 5 | _regulator : REAL; 6 | END_VAR 7 | METHOD PUBLIC Close : REAL 8 | VAR_INPUT 9 | regulator : REAL; 10 | END_VAR 11 | 12 | Close := regulator /100; 13 | _ctrlOpen := FALSE; 14 | END_METHOD 15 | 16 | METHOD PUBLIC Open : REAL 17 | VAR_INPUT 18 | regulator : REAL; 19 | END_VAR 20 | Open := regulator/100; //return the grade of opening/closing to multiply later. If the opening in filling is 50% the filling rate is 2.5 L/s 21 | _ctrlOpen := TRUE; 22 | END_METHOD 23 | 24 | METHOD PUBLIC OVERRIDE GetState : ValveState 25 | IF (_ctrlOpen) THEN 26 | GetState := ValveState#Open; 27 | ELSE 28 | GetState := ValveState#Closed; 29 | END_IF; 30 | END_METHOD 31 | METHOD PUBLIC ReadCyclic 32 | VAR_INPUT 33 | Regulator : REAL; 34 | END_VAR 35 | 36 | _regulator := Regulator; 37 | END_METHOD 38 | METHOD PUBLIC WriteCyclic 39 | VAR_OUTPUT 40 | ctrlOpen : BYTE; 41 | END_VAR 42 | ctrlOpen := _ctrlOpen; 43 | END_METHOD 44 | 45 | END_CLASS 46 | 47 | END_NAMESPACE -------------------------------------------------------------------------------- /05_oop_in_st/exercises/solution/src/configuration.st: -------------------------------------------------------------------------------- 1 | USING FluidHandlingInterfaces; 2 | USING FluidHandlingClass; 3 | Using MATHS; 4 | CONFIGURATION MyConfiguration 5 | TASK Main(Interval := T#1000ms, Priority := 1); 6 | PROGRAM P1 WITH Main: MyProgram; 7 | PROGRAM P2 WITH Main: CalculatorCurrentVolume; 8 | PROGRAM P3 WITH Main: CalculatorWithRegulation; 9 | VAR_GLOBAL 10 | 11 | //FIRST IMPLEMENTATION SIMPLE 12 | 13 | //SECOND AND COMPLEX 14 | vInEntry : ValveWithEntry; 15 | vOutEntry: ValveWithEntry; 16 | tankCube: CubicTank :=(inletValve:= vIn, outletValve:= vOut, side_length:= 20); 17 | tankCylinder : CylindricalTank :=(inletValve := vIn, outletValve:= vOut, height:= 20, radium := 10); 18 | 19 | //SIMPLE VALVES 20 | vInCtrl AT %Q1.0 : BOOL; 21 | vOutCtrl AT %Q1.1 : BOOL; 22 | 23 | vInOpen : BOOL; 24 | vOutOpen : BOOL; 25 | vInClosed : BOOL; 26 | vOutClosed : BOOL; 27 | 28 | statusIn : ValveState; 29 | statusOut : ValveState; 30 | 31 | 32 | //COMPLEX VALVES 33 | vInRegulator AT %IB2 : BYTE; 34 | vOutRegulator AT %IB3 : BYTE; 35 | vInCtrlEntry AT %QB2 : BYTE; 36 | vOutCtrlEntry AT %QB3 : BYTE; 37 | 38 | vInOpenR : BOOL; 39 | vOutOpenR : BOOL; 40 | vInClosedR : BOOL; 41 | vOutClosedR : BOOL; 42 | 43 | statusInR : ValveState; 44 | statusOutR : ValveState; 45 | 46 | //CONTROL TANK 47 | Close AT %I0.0 : BOOL; 48 | Fill AT %I0.1 : BOOL; 49 | Empty AT %I0.2 : BOOL; 50 | Flush AT %I0.3 : BOOL; 51 | phase : TankState; 52 | END_VAR 53 | END_CONFIGURATION 54 | -------------------------------------------------------------------------------- /05_oop_in_st/new.md: -------------------------------------------------------------------------------- 1 | Selbstverständlich! Hier ist ein detaillierter Trainingsplan für Modul 4: Advanced OOP Concepts, mit Beispielen und Übungen. 2 | 3 | ### Module 4: Advanced OOP Concepts 4 | **Objectives:** Deepen the understanding of OOP concepts and their application in Structured Text (ST). 5 | 6 | #### 1. Inheritance 7 | **Goal:** Understand and implement inheritance to create base and derived classes. 8 | 9 | 1.1. **Introduction to Inheritance** 10 | - Definition and purpose of inheritance. 11 | - How inheritance promotes code reusability. 12 | 13 | 1.2. **Creating Base and Derived Classes** 14 | - **Example:** 15 | ```st 16 | // Base class definition 17 | CLASS Vehicle 18 | VAR 19 | speed: INT; 20 | capacity: INT; 21 | END_VAR 22 | METHOD SetSpeed 23 | VAR_INPUT 24 | newSpeed: INT; 25 | END_VAR 26 | speed := newSpeed; 27 | END_METHOD 28 | END_CLASS 29 | 30 | // Derived class definition 31 | CLASS Car EXTENDS Vehicle 32 | VAR 33 | fuelType: STRING; 34 | END_VAR 35 | METHOD SetFuelType 36 | VAR_INPUT 37 | newFuelType: STRING; 38 | END_VAR 39 | fuelType := newFuelType; 40 | END_METHOD 41 | END_CLASS 42 | ``` 43 | 44 | 1.3. **Overriding Methods** 45 | - **Example:** 46 | ```st 47 | // Overriding method in derived class 48 | CLASS ElectricCar EXTENDS Car 49 | METHOD SetFuelType 50 | VAR_INPUT 51 | newFuelType: STRING; 52 | END_VAR 53 | IF newFuelType = 'Electric' THEN 54 | fuelType := newFuelType; 55 | ELSE 56 | // Handle invalid fuel type 57 | END_IF 58 | END_METHOD 59 | END_CLASS 60 | ``` 61 | 62 | 1.4. **Practical Exercise:** 63 | - Create a base class `Appliance` with properties like `power` and methods like `TurnOn` and `TurnOff`. 64 | - Create derived classes `WashingMachine` and `Refrigerator` that extend `Appliance` and add specific properties and methods. 65 | - Override the `TurnOn` method in the `WashingMachine` class to include a specific start-up sequence. 66 | 67 | #### 2. Polymorphism 68 | **Goal:** Understand and implement polymorphism to allow objects to be treated as instances of their base class. 69 | 70 | 2.1. **Introduction to Polymorphism** 71 | - Definition and purpose of polymorphism. 72 | - How polymorphism enhances flexibility and maintainability. 73 | 74 | 2.2. **Using Interfaces and Abstract Classes** 75 | - **Example:** 76 | ```st 77 | // Abstract class definition 78 | ABSTRACT CLASS Shape 79 | METHOD Area: REAL; 80 | END_CLASS 81 | 82 | // Derived class Circle 83 | CLASS Circle EXTENDS Shape 84 | VAR 85 | radius: REAL; 86 | END_VAR 87 | METHOD Area: REAL 88 | Area := 3.14 * radius * radius; 89 | END_METHOD 90 | END_CLASS 91 | 92 | // Derived class Rectangle 93 | CLASS Rectangle EXTENDS Shape 94 | VAR 95 | length: REAL; 96 | width: REAL; 97 | END_VAR 98 | METHOD Area: REAL 99 | Area := length * width; 100 | END_METHOD 101 | END_CLASS 102 | ``` 103 | 104 | 2.3. **Polymorphic Behavior** 105 | - **Example:** 106 | ```st 107 | // Polymorphic method calling 108 | PROGRAM Main 109 | VAR 110 | shape: Shape; 111 | circle: Circle; 112 | rectangle: Rectangle; 113 | END_VAR 114 | 115 | // Creating instances 116 | circle := Circle(); 117 | circle.radius := 5.0; 118 | 119 | rectangle := Rectangle(); 120 | rectangle.length := 10.0; 121 | rectangle.width := 4.0; 122 | 123 | // Assigning to base class reference 124 | shape := circle; 125 | // Calling polymorphic method 126 | WriteReal('Circle Area: ', shape.Area()); 127 | 128 | shape := rectangle; 129 | // Calling polymorphic -------------------------------------------------------------------------------- /05_oop_in_st/slides/img/valvescheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/05_oop_in_st/slides/img/valvescheme.png -------------------------------------------------------------------------------- /05_oop_in_st/slides/img/valveuml.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Valve 25 | 26 | 27 | 28 | 29 | 30 | 31 | - isOpen 32 | 33 | 34 | 35 | 36 | 37 | 38 | + open() 39 | 40 | 41 | 42 | 43 | 44 | 45 | - isClosed 46 | 47 | 48 | 49 | 50 | 51 | 52 | + close() 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /05_oop_in_st/slides/reveal-md.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": [ 3 | "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs" 4 | ] 5 | } -------------------------------------------------------------------------------- /05_oop_in_st/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/05_oop_in_st/slides/theme/.DS_Store -------------------------------------------------------------------------------- /05_oop_in_st/slides/theme/siemens.css: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is darkblue. 4 | * 5 | * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. 6 | * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | section.has-dark-background, 9 | section.has-dark-background h1, 10 | section.has-dark-background h2, 11 | section.has-dark-background h3, 12 | section.has-dark-background h4, 13 | section.has-dark-background h5, 14 | section.has-dark-background h6 { 15 | color: #fff; 16 | } 17 | 18 | /********************************************* 19 | * GLOBAL STYLES 20 | *********************************************/ 21 | body { 22 | background: #fff; 23 | background-color: #becdd7; 24 | /* Siemens Stone light 35%. White background makes index page unreadable (white links). */ 25 | } 26 | 27 | /* ugly trick to use white background for normal slides */ 28 | .js body { 29 | background: #fff; 30 | background-color: #fff; 31 | } 32 | 33 | body:after { 34 | content: ""; 35 | background-image: url(siemens.svg); 36 | background-size: 200px 32px; 37 | position: fixed; 38 | top: 16px; 39 | right: 16px; 40 | height: 32px; 41 | width: 200px 42 | } 43 | 44 | .reveal { 45 | font-family: "Arial", sans-serif; 46 | font-size: 32px; 47 | font-weight: normal; 48 | color: rgba(65, 75, 85); 49 | } 50 | 51 | ::selection { 52 | color: #fff; 53 | background: rgba(0, 0, 0, 0.99); 54 | text-shadow: none; 55 | } 56 | 57 | ::-moz-selection { 58 | color: #fff; 59 | background: #000000fc; 60 | text-shadow: none; 61 | } 62 | 63 | .reveal .slides section, 64 | .reveal .slides section>section { 65 | line-height: 1.3; 66 | padding: 0 0; 67 | /* text-align: left; */ 68 | font-weight: inherit; 69 | } 70 | 71 | /********************************************* 72 | * HEADERS 73 | *********************************************/ 74 | .reveal h1, 75 | .reveal h2, 76 | .reveal h3, 77 | .reveal h4, 78 | .reveal h5, 79 | .reveal h6 { 80 | margin: 0 0 20px 0; 81 | color: #00646e; 82 | /* Siemens Accent Teal dark */ 83 | font-family: "Arial", sans-serif; 84 | font-weight: bold; 85 | line-height: 1.2; 86 | letter-spacing: normal; 87 | text-transform: normal; 88 | text-shadow: none; 89 | word-wrap: break-word; 90 | } 91 | 92 | .reveal h1 { 93 | font-size: 3em; 94 | } 95 | 96 | .reveal h2 { 97 | font-size: 2.5em; 98 | background: #ffffffb3; 99 | display: inline; 100 | padding: 15px; 101 | } 102 | 103 | .reveal h3 { 104 | font-size: 2em; 105 | } 106 | 107 | .reveal h4 { 108 | font-size: 1.5em; 109 | } 110 | 111 | /********************************************* 112 | * OTHER 113 | *********************************************/ 114 | .reveal p { 115 | margin: 20px 0; 116 | line-height: 1.3; 117 | } 118 | 119 | /* Ensure certain elements are never larger than the slide itself */ 120 | .reveal img, 121 | .reveal video, 122 | .reveal iframe { 123 | max-width: 95%; 124 | max-height: 95%; 125 | } 126 | 127 | .reveal strong, 128 | .reveal b { 129 | font-weight: bold; 130 | } 131 | 132 | .reveal em { 133 | font-style: italic; 134 | } 135 | 136 | .reveal ol, 137 | .reveal dl, 138 | .reveal ul { 139 | display: inline-block; 140 | text-align: left; 141 | margin: 0 0 0 1em; 142 | } 143 | 144 | .reveal ol { 145 | list-style-type: decimal; 146 | } 147 | 148 | .reveal ul { 149 | list-style-type: disc; 150 | } 151 | 152 | .reveal ul ul { 153 | list-style-type: square; 154 | } 155 | 156 | .reveal ul ul ul { 157 | list-style-type: circle; 158 | } 159 | 160 | .reveal ul ul, 161 | .reveal ul ol, 162 | .reveal ol ol, 163 | .reveal ol ul { 164 | display: block; 165 | margin-left: 40px; 166 | } 167 | 168 | .reveal dt { 169 | font-weight: bold; 170 | } 171 | 172 | .reveal dd { 173 | margin-left: 40px; 174 | } 175 | 176 | .reveal blockquote { 177 | display: block; 178 | position: relative; 179 | width: 70%; 180 | margin: 20px auto; 181 | padding: 5px; 182 | font-style: italic; 183 | color: #fff; 184 | background: rgba(65, 170, 170, 1); 185 | /* Siemens Accent Teal light */ 186 | box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); 187 | } 188 | 189 | .reveal blockquote p:first-child, 190 | .reveal blockquote p:last-child { 191 | display: inline-block; 192 | } 193 | 194 | .reveal q { 195 | font-style: italic; 196 | } 197 | 198 | .reveal pre { 199 | display: block; 200 | position: relative; 201 | width: 90%; 202 | margin: 20px auto; 203 | text-align: left; 204 | font-size: 0.55em; 205 | font-family: monospace; 206 | line-height: 1.2em; 207 | word-wrap: break-word; 208 | box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); 209 | } 210 | 211 | .reveal code { 212 | font-family: monospace; 213 | color: rgba(175, 35, 95); 214 | text-transform: none; 215 | } 216 | 217 | .reveal pre code { 218 | display: block; 219 | background: #7d8791; 220 | padding: 5px; 221 | overflow: auto; 222 | max-height: 400px; 223 | word-wrap: normal; 224 | } 225 | 226 | .reveal table { 227 | margin: auto; 228 | border-collapse: collapse; 229 | border-spacing: 0; 230 | } 231 | 232 | .reveal table th { 233 | font-weight: bold; 234 | } 235 | 236 | .reveal table th, 237 | .reveal table td { 238 | text-align: left; 239 | padding: 0.2em 0.5em 0.2em 0.5em; 240 | border-bottom: 1px solid; 241 | } 242 | 243 | .reveal table th[align="center"], 244 | .reveal table td[align="center"] { 245 | text-align: center; 246 | } 247 | 248 | .reveal table th[align="right"], 249 | .reveal table td[align="right"] { 250 | text-align: right; 251 | } 252 | 253 | .reveal table tbody tr:last-child th, 254 | .reveal table tbody tr:last-child td { 255 | border-bottom: none; 256 | } 257 | 258 | .reveal sup { 259 | vertical-align: super; 260 | font-size: smaller; 261 | } 262 | 263 | .reveal sub { 264 | vertical-align: sub; 265 | font-size: smaller; 266 | } 267 | 268 | .reveal small { 269 | display: inline-block; 270 | font-size: 0.6em; 271 | line-height: 1.2em; 272 | vertical-align: top; 273 | } 274 | 275 | .reveal small * { 276 | vertical-align: top; 277 | } 278 | 279 | /********************************************* 280 | * LINKS 281 | *********************************************/ 282 | .reveal a { 283 | color: rgba(60, 145, 175); 284 | text-decoration: none; 285 | -webkit-transition: color .15s ease; 286 | -moz-transition: color .15s ease; 287 | transition: color .15s ease; 288 | } 289 | 290 | .reveal a:hover { 291 | color: #cde6eb; 292 | text-shadow: none; 293 | border: none; 294 | } 295 | 296 | .reveal .roll span:after { 297 | color: #fff; 298 | background: #00003f; 299 | } 300 | 301 | /********************************************* 302 | * IMAGES 303 | *********************************************/ 304 | .reveal section img { 305 | margin: 15px 0px; 306 | background: rgba(255, 255, 255, 0.12); 307 | border: none; 308 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); 309 | } 310 | 311 | .reveal section img.plain { 312 | border: 0; 313 | box-shadow: none; 314 | } 315 | 316 | .reveal a img { 317 | -webkit-transition: all .15s linear; 318 | -moz-transition: all .15s linear; 319 | transition: all .15s linear; 320 | } 321 | 322 | .reveal a:hover img { 323 | background: rgba(255, 255, 255, 0.2); 324 | border-color: #000028; 325 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); 326 | } 327 | 328 | /********************************************* 329 | * NAVIGATION CONTROLS 330 | *********************************************/ 331 | .reveal .controls { 332 | color: #009999; 333 | } 334 | 335 | /********************************************* 336 | * PROGRESS BAR 337 | *********************************************/ 338 | .reveal .progress { 339 | background: rgba(0, 0, 0, 0.2); 340 | color: #009999; 341 | } 342 | 343 | .reveal .progress span { 344 | -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 345 | -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 346 | transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 347 | } 348 | 349 | /********************************************* 350 | * PRINT BACKGROUND 351 | *********************************************/ 352 | @media print { 353 | .backgrounds { 354 | background-color: #fff; 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /05_oop_in_st/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /06_unit_testing/apax.yml: -------------------------------------------------------------------------------- 1 | name: 99_template 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch -------------------------------------------------------------------------------- /06_unit_testing/exercises/1_starting_tests/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 1: Starting tests 2 | 3 | You will find the file "NumberIsEven.st" in the src folder. It contains a `FUNCTION` named "NumberIsEven", which will take an `INT` as input and will return `TRUE` if the number is even. 4 | 5 | Write and execute a test for this function to check if it is working properly. 6 | 7 | >Hint: You will have to use an `Assert` inside of a test function. The syntax for a test function looks like this: 8 | ``` 9 | {Test} 10 | FUNCTION EvenNumber 11 | // Put your test code here 12 | END_FUNCTION 13 | ``` -------------------------------------------------------------------------------- /06_unit_testing/exercises/1_starting_tests/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "1_start_tests" 3 | version: 1.0.0 4 | type: app 5 | # Description for your application example or app 6 | description: First exercise of the chapter Unit Testing 7 | # Targets to be compiled with 'apax build' 8 | targets: 9 | - "1500" 10 | - llvm 11 | # Dependencies 12 | devDependencies: 13 | "@ax/sdk": 2504.0.0 14 | 15 | # Project variables 16 | variables: 17 | APAX_BUILD_ARGS: 18 | - --debug # Enable debug information for value debugging 19 | BIN_FOLDER: "./bin/1500" # choose your target RT, here : any S7-1500 PLC 20 | # IP address must match with the IP address of your target device 21 | # The IP address in the .vscode/launch.json must be equal 22 | IP_ADDRESS: "192.168.0.1" 23 | 24 | # Apax scripts 25 | scripts: 26 | # call 'apax load' to download the builded program to the target. An 'apax build' might be required upfront 27 | load: apax sld load --input $BIN_FOLDER --target $IP_ADDRESS --restart --accept-security-disclaimer --log debug 28 | # call 'apax dlplc' to build and download the application to the target 29 | dlplc: 30 | - apax build 31 | - apax load 32 | catalogs: 33 | "@ax/simatic-ax": ^2504.0.0 34 | -------------------------------------------------------------------------------- /06_unit_testing/exercises/1_starting_tests/src/NumberIsEven.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Numbers 2 | FUNCTION NumberIsEven : BOOL 3 | VAR_INPUT 4 | number : INT; 5 | END_VAR 6 | 7 | IF number MOD 2 = 0 THEN 8 | NumberIsEven := TRUE; 9 | ELSE 10 | NumberIsEven := FALSE; 11 | END_IF; 12 | END_FUNCTION 13 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/1_starting_tests/test/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit.Assert; 2 | 3 | NAMESPACE Test 4 | // Add your test function here 5 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/2_testing_classes/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 2: Testing classes 2 | 3 | You will find the file "Counter.st" in the src folder. It contains a `CLASS` named "SimpleCounter". This class has the following methods: 4 | 5 | | Name | Input | Output | Description| 6 | |--|--|--|--| 7 | | SetCurrentValue| newValue | - | Sets the counter value to `newValue`| 8 | | GetCurrentValue | - | value | Returns the current counter value | 9 | | CountUp | - | - | Increments the current counter value by 1 | 10 | 11 | Write and execute a test for this class which verifies that the counter can count from a starting value of 2 to 4. 12 | 13 | >Hint: You will have to use a test method inside a `TestFixture`. The syntax for a ``TestFixture`` looks like this: 14 | ``` 15 | {TestFixture} 16 | CLASS MyTestFixture 17 | VAR 18 | END_VAR 19 | 20 | {Test} 21 | METHOD PUBLIC MyTestMethod 22 | // Put your test code here 23 | END_METHOD 24 | END_CLASS 25 | ``` -------------------------------------------------------------------------------- /06_unit_testing/exercises/2_testing_classes/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "2_testing_classes" 3 | version: 1.0.0 4 | type: app 5 | # Description for your application example or app 6 | description: Second exercise of the chapter Unit Testing 7 | # Targets to be compiled with 'apax build' 8 | targets: 9 | - "1500" 10 | - llvm 11 | # Dependencies 12 | devDependencies: 13 | "@ax/sdk": 2504.0.0 14 | 15 | # Project variables 16 | variables: 17 | APAX_BUILD_ARGS: 18 | - --debug # Enable debug information for value debugging 19 | BIN_FOLDER: "./bin/1500" # choose your target RT, here : any S7-1500 PLC 20 | # IP address must match with the IP address of your target device 21 | # The IP address in the .vscode/launch.json must be equal 22 | IP_ADDRESS: "192.168.0.1" 23 | 24 | # Apax scripts 25 | scripts: 26 | # call 'apax load' to download the builded program to the target. An 'apax build' might be required upfront 27 | load: apax sld load --input $BIN_FOLDER --target $IP_ADDRESS --restart --accept-security-disclaimer --log debug 28 | # call 'apax dlplc' to build and download the application to the target 29 | dlplc: 30 | - apax build 31 | - apax load 32 | catalogs: 33 | "@ax/simatic-ax": ^2504.0.0 34 | -------------------------------------------------------------------------------- /06_unit_testing/exercises/2_testing_classes/src/SimpleCounter.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Counter 2 | CLASS SimpleCounter 3 | VAR 4 | value : INT := 0; 5 | END_VAR 6 | 7 | METHOD PUBLIC SetCurrentValue 8 | VAR_INPUT 9 | newValue : INT; 10 | END_VAR 11 | 12 | value := newValue; 13 | END_METHOD 14 | 15 | METHOD PUBLIC GetCurrentValue : Int 16 | GetCurrentValue := value; 17 | END_METHOD 18 | 19 | METHOD PUBLIC CountUp 20 | value := value + 1; 21 | END_METHOD 22 | END_CLASS 23 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/2_testing_classes/test/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit.Assert; 2 | 3 | NAMESPACE Test 4 | // Add your test function here 5 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/3_parametrized_test/README.md: -------------------------------------------------------------------------------- 1 | # Exercise 3: Parametrized tests 2 | 3 | We want to test our `SimpleCounterClass` from exercise 2 (can again be found in the src folder of this exercise) in different scenarios. Write and execute a parametrized test for this class which verifies that the counter still works correctly in different scenarios. In the solution the counter will count up 42 times from 0, 9 times from 5 and 5 times from 100. 4 | 5 | >Hint: You will have to add input variables to your test method and call the test pragma like this: `{Test(input1 := 1, input2 := 1)}` 6 | -------------------------------------------------------------------------------- /06_unit_testing/exercises/3_parametrized_test/apax.yml: -------------------------------------------------------------------------------- 1 | # General information 2 | name: "3_parametrized_tests" 3 | version: 1.0.0 4 | type: app 5 | # Description for your application example or app 6 | description: Third exercise of the chapter Unit Testing 7 | # Targets to be compiled with 'apax build' 8 | targets: 9 | - "1500" 10 | - llvm 11 | # Dependencies 12 | devDependencies: 13 | "@ax/sdk": 2504.0.0 14 | 15 | # Project variables 16 | variables: 17 | APAX_BUILD_ARGS: 18 | - --debug # Enable debug information for value debugging 19 | BIN_FOLDER: "./bin/1500" # choose your target RT, here : any S7-1500 PLC 20 | # IP address must match with the IP address of your target device 21 | # The IP address in the .vscode/launch.json must be equal 22 | IP_ADDRESS: "192.168.0.1" 23 | 24 | # Apax scripts 25 | scripts: 26 | # call 'apax load' to download the builded program to the target. An 'apax build' might be required upfront 27 | load: apax sld load --input $BIN_FOLDER --target $IP_ADDRESS --restart --accept-security-disclaimer --log debug 28 | # call 'apax dlplc' to build and download the application to the target 29 | dlplc: 30 | - apax build 31 | - apax load 32 | catalogs: 33 | "@ax/simatic-ax": ^2504.0.0 34 | -------------------------------------------------------------------------------- /06_unit_testing/exercises/3_parametrized_test/src/SimpleCounter.st: -------------------------------------------------------------------------------- 1 | NAMESPACE Counter 2 | CLASS SimpleCounter 3 | VAR 4 | value : INT := 0; 5 | END_VAR 6 | 7 | METHOD PUBLIC SetCurrentValue 8 | VAR_INPUT 9 | newValue : INT; 10 | END_VAR 11 | 12 | value := newValue; 13 | END_METHOD 14 | 15 | METHOD PUBLIC GetCurrentValue : Int 16 | GetCurrentValue := value; 17 | END_METHOD 18 | 19 | METHOD PUBLIC CountUp 20 | value := value + 1; 21 | END_METHOD 22 | 23 | END_CLASS 24 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/3_parametrized_test/test/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit.Assert; 2 | 3 | NAMESPACE Test 4 | // Add your test function here 5 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/solutions/1_starting_tests_solution/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit.Assert; 2 | USING Numbers; 3 | 4 | NAMESPACE Test 5 | {Test} 6 | FUNCTION EvenNumber 7 | VAR_TEMP 8 | result : BOOL; 9 | END_VAR 10 | 11 | result := NumberIsEven(2); 12 | Equal(actual := result, expected := TRUE); 13 | 14 | result := NumberIsEven(5); 15 | Equal(actual := result, expected := FALSE); 16 | END_FUNCTION 17 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/solutions/2_testing_classes_solution/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit.Assert; 2 | USING Counter; 3 | 4 | NAMESPACE Test 5 | {TestFixture} 6 | CLASS CounterTest 7 | VAR 8 | simpleCounter : SimpleCounter; 9 | END_VAR 10 | 11 | {Test} 12 | METHOD PUBLIC CountFrom2To4 13 | simpleCounter.SetCurrentValue(2); 14 | simpleCounter.CountUp(); 15 | simpleCounter.CountUp(); 16 | Equal(actual := simpleCounter.GetCurrentValue(), expected := 4); 17 | END_METHOD 18 | END_CLASS 19 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/exercises/solutions/3_parametrized_test_solution/test.st: -------------------------------------------------------------------------------- 1 | USING AxUnit.Assert; 2 | USING Counter; 3 | 4 | NAMESPACE Test 5 | {TestFixture} 6 | CLASS CounterTest 7 | VAR 8 | simpleCounter : SimpleCounter; 9 | END_VAR 10 | 11 | {Test(startValue := 0, countUpXtimes := 42, result := 42)} 12 | {Test(startValue := 5, countUpXtimes := 9, result := 14)} 13 | {Test(startValue := 100, countUpXtimes := 5, result := 105)} 14 | METHOD PUBLIC CountUp 15 | VAR_INPUT 16 | startValue : INT; 17 | countUpXtimes : INT; 18 | result : INT; 19 | END_VAR 20 | 21 | VAR_TEMP 22 | index : DINT; 23 | END_VAR 24 | 25 | FOR index := 1 TO countUpXtimes DO 26 | IF index = 1 THEN 27 | simpleCounter.SetCurrentValue(startValue); 28 | END_IF; 29 | simpleCounter.CountUp(); 30 | END_FOR; 31 | 32 | Equal(actual := simpleCounter.GetCurrentValue(), expected := result); 33 | END_METHOD 34 | END_CLASS 35 | END_NAMESPACE -------------------------------------------------------------------------------- /06_unit_testing/slides/img/Target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/06_unit_testing/slides/img/Target.png -------------------------------------------------------------------------------- /06_unit_testing/slides/img/TestExplorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/06_unit_testing/slides/img/TestExplorer.png -------------------------------------------------------------------------------- /06_unit_testing/slides/img/apaxyml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/06_unit_testing/slides/img/apaxyml.png -------------------------------------------------------------------------------- /06_unit_testing/slides/img/debugging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/06_unit_testing/slides/img/debugging.png -------------------------------------------------------------------------------- /06_unit_testing/slides/img/ui_buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/06_unit_testing/slides/img/ui_buttons.png -------------------------------------------------------------------------------- /06_unit_testing/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/06_unit_testing/slides/theme/.DS_Store -------------------------------------------------------------------------------- /06_unit_testing/slides/theme/siemens.css: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is darkblue. 4 | * 5 | * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. 6 | * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | section.has-dark-background, 9 | section.has-dark-background h1, 10 | section.has-dark-background h2, 11 | section.has-dark-background h3, 12 | section.has-dark-background h4, 13 | section.has-dark-background h5, 14 | section.has-dark-background h6 { 15 | color: #fff; 16 | } 17 | 18 | /********************************************* 19 | * GLOBAL STYLES 20 | *********************************************/ 21 | body { 22 | background: #fff; 23 | background-color: #becdd7; 24 | /* Siemens Stone light 35%. White background makes index page unreadable (white links). */ 25 | } 26 | 27 | /* ugly trick to use white background for normal slides */ 28 | .js body { 29 | background: #fff; 30 | background-color: #fff; 31 | } 32 | 33 | body:after { 34 | content: ""; 35 | background-image: url(siemens.svg); 36 | background-size: 200px 32px; 37 | position: fixed; 38 | top: 16px; 39 | right: 16px; 40 | height: 32px; 41 | width: 200px 42 | } 43 | 44 | .reveal { 45 | font-family: "Arial", sans-serif; 46 | font-size: 32px; 47 | font-weight: normal; 48 | color: rgba(65, 75, 85); 49 | } 50 | 51 | ::selection { 52 | color: #fff; 53 | background: rgba(0, 0, 0, 0.99); 54 | text-shadow: none; 55 | } 56 | 57 | ::-moz-selection { 58 | color: #fff; 59 | background: rgba(0, 0, 0, 0.99); 60 | text-shadow: none; 61 | } 62 | 63 | .reveal .slides section, 64 | .reveal .slides section>section { 65 | line-height: 1.3; 66 | padding: 0 0; 67 | /* text-align: left; */ 68 | font-weight: inherit; 69 | } 70 | 71 | /********************************************* 72 | * HEADERS 73 | *********************************************/ 74 | .reveal h1, 75 | .reveal h2, 76 | .reveal h3, 77 | .reveal h4, 78 | .reveal h5, 79 | .reveal h6 { 80 | margin: 0 0 20px 0; 81 | color: #00646e; 82 | /* Siemens Accent Teal dark */ 83 | font-family: "Arial", sans-serif; 84 | font-weight: bold; 85 | line-height: 1.2; 86 | letter-spacing: normal; 87 | text-transform: normal; 88 | text-shadow: none; 89 | word-wrap: break-word; 90 | } 91 | 92 | .reveal h1 { 93 | font-size: 3em; 94 | } 95 | 96 | .reveal h2 { 97 | font-size: 2.5em; 98 | background: rgba(255, 255, 255, 0.7); 99 | display: inline; 100 | padding: 15px; 101 | } 102 | 103 | .reveal h3 { 104 | font-size: 2em; 105 | } 106 | 107 | .reveal h4 { 108 | font-size: 1.5em; 109 | } 110 | 111 | /********************************************* 112 | * OTHER 113 | *********************************************/ 114 | .reveal p { 115 | margin: 20px 0; 116 | line-height: 1.3; 117 | } 118 | 119 | /* Ensure certain elements are never larger than the slide itself */ 120 | .reveal img, 121 | .reveal video, 122 | .reveal iframe { 123 | max-width: 95%; 124 | max-height: 95%; 125 | } 126 | 127 | .reveal strong, 128 | .reveal b { 129 | font-weight: bold; 130 | } 131 | 132 | .reveal em { 133 | font-style: italic; 134 | } 135 | 136 | .reveal ol, 137 | .reveal dl, 138 | .reveal ul { 139 | display: inline-block; 140 | text-align: left; 141 | margin: 0 0 0 1em; 142 | } 143 | 144 | .reveal ol { 145 | list-style-type: decimal; 146 | } 147 | 148 | .reveal ul { 149 | list-style-type: disc; 150 | } 151 | 152 | .reveal ul ul { 153 | list-style-type: square; 154 | } 155 | 156 | .reveal ul ul ul { 157 | list-style-type: circle; 158 | } 159 | 160 | .reveal ul ul, 161 | .reveal ul ol, 162 | .reveal ol ol, 163 | .reveal ol ul { 164 | display: block; 165 | margin-left: 40px; 166 | } 167 | 168 | .reveal dt { 169 | font-weight: bold; 170 | } 171 | 172 | .reveal dd { 173 | margin-left: 40px; 174 | } 175 | 176 | .reveal blockquote { 177 | display: block; 178 | position: relative; 179 | width: 70%; 180 | margin: 20px auto; 181 | padding: 5px; 182 | font-style: italic; 183 | color: #fff; 184 | background: rgba(65, 170, 170, 1); 185 | /* Siemens Accent Teal light */ 186 | box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); 187 | } 188 | 189 | .reveal blockquote p:first-child, 190 | .reveal blockquote p:last-child { 191 | display: inline-block; 192 | } 193 | 194 | .reveal q { 195 | font-style: italic; 196 | } 197 | 198 | .reveal pre { 199 | display: block; 200 | position: relative; 201 | width: 90%; 202 | margin: 20px auto; 203 | text-align: left; 204 | font-size: 0.55em; 205 | font-family: monospace; 206 | line-height: 1.2em; 207 | word-wrap: break-word; 208 | box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); 209 | } 210 | 211 | .reveal code { 212 | font-family: monospace; 213 | color: rgba(175, 35, 95); 214 | text-transform: none; 215 | } 216 | 217 | .reveal pre code { 218 | display: block; 219 | background: rgba(125, 135, 145); 220 | padding: 5px; 221 | overflow: auto; 222 | max-height: 400px; 223 | word-wrap: normal; 224 | } 225 | 226 | .reveal table { 227 | margin: auto; 228 | border-collapse: collapse; 229 | border-spacing: 0; 230 | } 231 | 232 | .reveal table th { 233 | font-weight: bold; 234 | } 235 | 236 | .reveal table th, 237 | .reveal table td { 238 | text-align: left; 239 | padding: 0.2em 0.5em 0.2em 0.5em; 240 | border-bottom: 1px solid; 241 | } 242 | 243 | .reveal table th[align="center"], 244 | .reveal table td[align="center"] { 245 | text-align: center; 246 | } 247 | 248 | .reveal table th[align="right"], 249 | .reveal table td[align="right"] { 250 | text-align: right; 251 | } 252 | 253 | .reveal table tbody tr:last-child th, 254 | .reveal table tbody tr:last-child td { 255 | border-bottom: none; 256 | } 257 | 258 | .reveal sup { 259 | vertical-align: super; 260 | font-size: smaller; 261 | } 262 | 263 | .reveal sub { 264 | vertical-align: sub; 265 | font-size: smaller; 266 | } 267 | 268 | .reveal small { 269 | display: inline-block; 270 | font-size: 0.6em; 271 | line-height: 1.2em; 272 | vertical-align: top; 273 | } 274 | 275 | .reveal small * { 276 | vertical-align: top; 277 | } 278 | 279 | /********************************************* 280 | * LINKS 281 | *********************************************/ 282 | .reveal a { 283 | color: rgba(60, 145, 175); 284 | text-decoration: none; 285 | -webkit-transition: color .15s ease; 286 | -moz-transition: color .15s ease; 287 | transition: color .15s ease; 288 | } 289 | 290 | .reveal a:hover { 291 | color: rgba(205, 230, 235); 292 | text-shadow: none; 293 | border: none; 294 | } 295 | 296 | .reveal .roll span:after { 297 | color: #fff; 298 | background: #00003f; 299 | } 300 | 301 | /********************************************* 302 | * IMAGES 303 | *********************************************/ 304 | .reveal section img { 305 | margin: 15px 0px; 306 | background: rgba(255, 255, 255, 0.12); 307 | border: none; 308 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); 309 | } 310 | 311 | .reveal section img.plain { 312 | border: 0; 313 | box-shadow: none; 314 | } 315 | 316 | .reveal a img { 317 | -webkit-transition: all .15s linear; 318 | -moz-transition: all .15s linear; 319 | transition: all .15s linear; 320 | } 321 | 322 | .reveal a:hover img { 323 | background: rgba(255, 255, 255, 0.2); 324 | border-color: #000028; 325 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); 326 | } 327 | 328 | /********************************************* 329 | * NAVIGATION CONTROLS 330 | *********************************************/ 331 | .reveal .controls { 332 | color: #009999; 333 | } 334 | 335 | /********************************************* 336 | * PROGRESS BAR 337 | *********************************************/ 338 | .reveal .progress { 339 | background: rgba(0, 0, 0, 0.2); 340 | color: #009999; 341 | } 342 | 343 | .reveal .progress span { 344 | -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 345 | -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 346 | transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); 347 | } 348 | 349 | /********************************************* 350 | * PRINT BACKGROUND 351 | *********************************************/ 352 | @media print { 353 | .backgrounds { 354 | background-color: #fff; 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /06_unit_testing/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /07_tools_for_commissioning/apax.yml: -------------------------------------------------------------------------------- 1 | name: 99_template 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch -------------------------------------------------------------------------------- /07_tools_for_commissioning/exercises/0_first_exercise/README.md: -------------------------------------------------------------------------------- 1 | What to do? -------------------------------------------------------------------------------- /07_tools_for_commissioning/exercises/0_first_exercise/apax.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/07_tools_for_commissioning/exercises/0_first_exercise/apax.yml -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/img/DiagBuffPanelWeb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/07_tools_for_commissioning/slides/img/DiagBuffPanelWeb.png -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/img/PerformanceInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/07_tools_for_commissioning/slides/img/PerformanceInfo.png -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/img/PlcOnlineHub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/07_tools_for_commissioning/slides/img/PlcOnlineHub.png -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/img/plc-browser.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/07_tools_for_commissioning/slides/img/plc-browser.gif -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tools for commissioning 3 | progress: true 4 | revealOptions: 5 | transition: 'fade' 6 | mouseWheel: true, 7 | --- 8 | 9 | # Agenda 10 | 11 | | ID | Topic | 12 | | -- | ----- | 13 | | 00 | Introduction to the workshop | 14 | | 01 | Introduction to AX Code IDE | 15 | | 02 | Get started with your first AX Project | 16 | | 03 | Loading and Debugging | 17 | | 04 | Introduction to ST Programming | 18 | | 05 | OOP Elements of ST | 19 | | 06 | Unit Testing | 20 | | **07** | **Tools for commissioning** | 21 | | 08 | Package management | 22 | 23 | --- 24 | 25 |
26 |

Prerequisites

27 |
28 | 29 |
30 |
31 |

To get started, you need to have SIMATIC AX, apax and all its prerequisites installed.

32 |

In addition you should know the basics on how to use AX Code as well as have a starting project, that has been created in the previous section 33 |

34 |
35 |

With this you are set up to continue with this learning path.

36 |
37 |
38 | --- 39 |
40 |

41 | What will you learn in this chapter 42 |

43 |
44 |
45 |
46 |

After you completed this training section you will

47 |
    48 |
  • know about different utilities and tools you can use while commissioning.
  • 49 |
  • know how to diagnose hardware and PLC issues.
  • 50 |
51 |
52 |
53 |
54 | 55 | --- 56 | 57 |
58 |
59 |
60 |

Local Connection Setup

61 |

PLC-Browser

62 |
63 |
64 |
65 |

Most of the tools discussed in this section need to go online to the PLC to display information that is important during commissioning. To do this, we can discover PLCs in our network using the PLC Browser tool. First you need to add the dcp Utility tool with apax add --dev @ax/dcp-utility to your project.

66 |
67 |

Then you can call the tool using the command palette (F1) and select the network interface you want to scan on; selecting a PLC will add it to the local connection configuration. 68 |

69 |
70 |
71 |
72 | 78 |
79 | 80 | --- 81 | 82 |
83 |
84 |
85 |

Local Connection Setup

86 |

Manual

87 |
88 |
89 |
90 |

Alternatively you can configure the PLC connection manually with the following steps:

91 |
92 |
    93 |
  1. Create a plc.yaml in the .ax/plcs/ directory
  2. 94 |
  3. Enter the specific information of the PLC
  4. 95 |
96 |

97 |
98 |

With this you are set to continue to the commissioning tools.

99 |

100 |
101 |

102 |     host: PLC_IP_ADDRESS
103 |     certificate: PATH_TO_PLC_CERTIFICATE
104 |     displayName: CUSTOM_NAME
105 |     
106 |
107 |
108 |
    109 |
  1. Local Connection Config:
    https://console.simatic-ax.siemens.io/docs/local-connection-config
  2. 110 |
111 |
112 |
113 | 114 | 115 | --- 116 | 117 |
118 |
119 |
120 |

Diagnostics Buffer

121 |
122 |
123 |
124 |

Any alarms present in the PLC can be found in the diagnostics buffer of the PLC. This buffer can be read using the diagnostic-buffer tool

125 |
126 |

To call the tool, you can either right-click on the .ax/plcs/PLC.yaml file and select Online Diagnostics or you can search for Diagnostics Buffer in the Command Palette 127 |

128 |
129 |
130 |
131 |
132 |
    133 |
  1. Diagnostic Buffer:
    https://console.simatic-ax.siemens.io/docs/axcode/diagnostic-buffer
  2. 134 |
135 |
136 |
137 | 138 | --- 139 | 140 |
141 |
142 |
143 |

PLC Performance Info

144 |
145 |
146 |
147 |

To get more information about the cycle time and used performance on the PLC you are working on you can use the PLC Performance Info Tool

148 |
149 |

To call the tool, you can either right-click on the .ax/plcs/PLC.yaml file and select Online Diagnostics or you can search for PLC Performance Info in the Command Palette 150 |

151 |
152 |
153 |
154 |
155 |
    156 |
  1. Performance Info:
    https://console.simatic-ax.siemens.io/docs/axcode/performance-info
  2. 157 |
158 |
159 |
160 | 161 | --- 162 | 163 |
164 |
165 |
166 |

PLC Online Hub

167 |
168 |
169 |
170 |

To get more information about the PLC in general (identifying information, firmware, run state etc.) you can use the online hub.

171 |
172 |

To call the tool, you can either right-click on the .ax/plcs/PLC.yaml file and select Launch PLC Online Hub or you can search for Online Hub in the Command Palette 173 |

174 |
175 |
176 |
177 | 182 |
183 | 184 | --- 185 | 186 |
187 |

188 | What did you learn 189 |

190 |
191 | 192 |
193 |
194 |

In this section you learned about...

195 |
    196 |
  • how to configure the connection to PLCs in the network.
  • 197 |
  • how you can use AX Code to diagnose issues on the PLC.
  • 198 |
  • different tools available at your disposal to succeed at commissioning.
  • 199 |
200 |
201 |
202 |
203 | 204 | -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/07_tools_for_commissioning/slides/theme/.DS_Store -------------------------------------------------------------------------------- /07_tools_for_commissioning/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /08_package_management/apax.yml: -------------------------------------------------------------------------------- 1 | name: 99_template 2 | 3 | version: 0.0.0 4 | type: generic 5 | 6 | scripts: 7 | present: reveal-md ./slides/slides.md --theme ./slides/theme/simatic-ax.css --watch -------------------------------------------------------------------------------- /08_package_management/exercises/1_creating_and_testing_a_library/README.md: -------------------------------------------------------------------------------- 1 | ### Creating and testing a library 2 | --- 3 | - Create a new library project 4 | - Define your top-level namespace 5 | - Write a class or reuse the valve and tank classes from the previous chapters 6 | - Write unit tests for that class 7 | - Build the library 8 | - Run the tests -------------------------------------------------------------------------------- /08_package_management/exercises/2_publishing_a_library/README.md: -------------------------------------------------------------------------------- 1 | ### Publishing a library 2 | --- 3 | - Add the `files` section in the `apax.yml` and include all necessary files for your library 4 | - Build, pack and publish the library as source code library to a registry of you choice (e. g. private repository in GitHub --> step by step description in the folder of this exercise) 5 | - Optional: Build, pack and publish the library as binary library to a registry of you choice (e. g. private repository in GitHub) 6 | - Inspect the published packages (e. g. on GitHub) -------------------------------------------------------------------------------- /08_package_management/exercises/2_publishing_a_library/solution.md: -------------------------------------------------------------------------------- 1 | ## How to publish a package to a private GitHub repository 2 | --- 3 | For the following workflow you will need a GitHub account. This is just an example on how to publish a package. Other services like GitLab can be used as well, but won´t be explained in this chapter. 4 | 5 | 1. Add your registry to the ``apax.yml`` (replace <accountname> with your account name which is shown on the top left on the GitHub Dashboard) 6 | ``` 7 | registries: 8 | '@' : 'https://npm.pkg.github.com 9 | ``` 10 | 2. Add the same account name in front of the ``name`` in the ``apax.yml``: 11 | ``` 12 | name: "@/exampleprojectname" 13 | ``` 14 | 3. Run ``apax pack`` 15 | 4. Login to GitHub using ``apax login`` --> choose GitHub in the menu --> leave the user name empty and press enter --> enter your token when asked for the password (a tutorial on how to create a personal access token can be found here: https://github.com/simatic-ax/.github/blob/main/docs/personalaccesstoken.md) 16 | 5. Run ``apax publish --package .apax.tgz --registry https://npm.pkg.github.com`` (replace <packagename> with the name of the package which was created during ``apax pack``; it can be found in the explorer of your project e. g. accountname-projectname-1.0.1.apax.tgz) 17 | 6. Go to ``GitHub`` --> click your profile picture in the top right --> click on ``Your repositories`` --> click on ``Packages`` on the top left 18 | 7. You should see your published package 19 | 8. If you publish multiple versions you will see all published versions after clicking on the package -------------------------------------------------------------------------------- /08_package_management/exercises/3_consuming_a_library/README.md: -------------------------------------------------------------------------------- 1 | ## Consuming a library 2 | --- 3 | - Consume your library in a new project (e. g. from private repository in GitHub --> step by step description in the folder of this exercise) 4 | - Consume a system library (e. g. with ``apax add @ax/system-timer``) 5 | - Build and inspect the new project -------------------------------------------------------------------------------- /08_package_management/exercises/3_consuming_a_library/solution.md: -------------------------------------------------------------------------------- 1 | ## How to publish a package to a private GitHub repository 2 | --- 3 | Before starting this workflow you should finish the exercise ``2-Publishing a library``. 4 | 1. Create a new application and open it in AX Code 5 | 2. Add your registry to the ``apax.yml`` (replace <accountname> with your account name --> same as in the previous exercise) 6 | ``` 7 | registries: 8 | '@' : 'https://npm.pkg.github.com 9 | ``` 10 | 3. Login to GitHub with ``apax login`` 11 | 4. Add your pack with ``apax add @/`` (use the same GitHub account name and project name as in the previous exercise) 12 | 5. Add ``USING `` (<yournamespace> = namespace defined in library) to the top of a program or class 13 | 6. Try instantiating a class and calling a function of your library -------------------------------------------------------------------------------- /08_package_management/slides/img/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/img/box.png -------------------------------------------------------------------------------- /08_package_management/slides/img/cake.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/img/cake.jpg -------------------------------------------------------------------------------- /08_package_management/slides/img/create_lib_project.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/img/create_lib_project.PNG -------------------------------------------------------------------------------- /08_package_management/slides/img/key.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/img/key.jpg -------------------------------------------------------------------------------- /08_package_management/slides/img/library.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/img/library.jpg -------------------------------------------------------------------------------- /08_package_management/slides/img/target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/img/target.png -------------------------------------------------------------------------------- /08_package_management/slides/theme/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/08_package_management/slides/theme/.DS_Store -------------------------------------------------------------------------------- /08_package_management/slides/theme/siemens.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 21 | 24 | 27 | 30 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | @sjuergen @BeckerStS @ReinerSchinkoethe @theBadT 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## How to get the learning path 2 | 3 | To retrieve the learning path, you can either 4 | 5 | ### Clone the directory using git with the command 6 | ``` 7 | git clone https://github.com/simatic-ax/learning-path 8 | ``` 9 | This will create a new directory in the folder you executed the git clone from. 10 | 11 | ### Download the repository as an archive 12 | Click on `Code` in the gitlab repository overview and select one of the archive formats to download the entire repository. You then have to decompress the downloaded archive file with a tool like 7zip and are ready to go! 13 | 14 | ![Download archive](./assets/img/download_archive.png) 15 | 16 | > **Note:** The chapter `02_first_ax_project` has moved to a separate repository. You can access the repository and the presentation via the following links: 17 | > - [Repository: simatic-ax/axlp_apax_and_project_creation](https://github.com/simatic-ax/axlp_apax_and_project_creation) 18 | > - [Presentation: GitHub Pages](https://simatic-ax.github.io/axlp_apax_and_project_creation/#/) 19 | 20 | ## Prerequisites: 21 | For the interactive slides, you need to have a few software packages installed to your PC: 22 | - nodejs (which also installs npm) [here you can download the installer for node.js for Windows](https://nodejs.org/en) 23 | - Reveal.md (how to install it, is described below) 24 | 25 | You can install Reveal.md using the command in a terminal 26 | 27 | 28 | ``` 29 | npm install --global reveal-md 30 | ``` 31 | 32 | Please note that this will install 3rd party executable files to your PC. 33 | 34 | ## Starting the slides 35 | For starting the slides, please navigate into the respective directory in the command line 36 | ```cd ./00_introduction``` and execute the command 37 | 38 | ``` 39 | apax present 40 | ``` 41 | 42 | This will start reveal-md with the slides of the section you navigated to. 43 | 44 | ## Direct Link 45 | [Introduction](./00_introduction/slides/slides.md) 46 | 47 | ## How to report issues, ideas and suggestions 48 | This learning path is supposed to be a living document and be adjusted to your needs, the needs of your customers and the development of AX itself. 49 | 50 | To improve the slides we are in need of feedback from you, as everything with AX it is a community effort! To provide the feedback, please add an issue where you describe, what you want us to change or where there is a mistake. 51 | ![New issue](./assets/img/new_issue.png) 52 | Of course you can always do it yourself and send us a merge request! 53 | 54 | In case of questions or further discussions, feel free to get in contact with one of our [CODEOWNERS](./CODEOWNERS) 55 | -------------------------------------------------------------------------------- /assets/img/download_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/assets/img/download_archive.png -------------------------------------------------------------------------------- /assets/img/new_issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simatic-ax/learning-path/a99702a568085ac08a54aa0ac7cbc0c1f7791dec/assets/img/new_issue.png -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "local>simatic-ax/renovate-config" 5 | ] 6 | } 7 | --------------------------------------------------------------------------------