<!doctype html><htmllang=enclass="js csstransforms3d"><head><metacharset=utf-8><metaname=viewportcontent="width=device-width,initial-scale=1"><metaname=generatorcontent="Hugo 0.80.0"><metaname=descriptioncontent="Strolch is a parameterized framework for use on servers and IoT"><metaname=authorcontent="Strolch"><linkrel=iconhref=/favicon.icotype=image/ico><title>Example Set-Up - Strolch</title><linkhref=/css/nucleus.css?1626091328rel=stylesheet><linkhref=/css/fontawesome-all.min.css?1626091328rel=stylesheet><linkhref=/css/hybrid.css?1626091328rel=stylesheet><linkhref=/css/featherlight.min.css?1626091328rel=stylesheet><linkhref=/css/perfect-scrollbar.min.css?1626091328rel=stylesheet><linkhref=/css/auto-complete.css?1626091328rel=stylesheet><linkhref=/css/atom-one-dark-reasonable.css?1626091328rel=stylesheet><linkhref=/css/theme.css?1626091328rel=stylesheet><linkhref=/css/hugo-theme.css?1626091328rel=stylesheet><linkhref=/css/theme-green.css?1626091328rel=stylesheet><scriptsrc=/js/jquery-3.3.1.min.js?1626091328></script><style>:root#header+#content>#left>#rlblock_left{display:none!important}</style></head><bodydata-url=/plc/example-set-up/><navid=sidebar><divid=header-wrapper><divid=header><aid=logohref=/><imgsrc=/logo.png></a></div><divclass=searchbox><labelfor=search-by><iclass="fas fa-search"></i></label><inputdata-search-inputid=search-bytype=searchplaceholder=Search...>
<spandata-search-clear><iclass="fas fa-times"></i></span></div><scripttype=text/javascriptsrc=/js/lunr.min.js?1626091328></script><scripttype=text/javascriptsrc=/js/auto-complete.js?1626091328></script><scripttype=text/javascript>varbaseurl="https:\/\/strolch.li\/";</script><scripttype=text/javascriptsrc=/js/search.js?1626091328></script></div><sectionid=homelinks><ul><li><aclass=paddinghref=/><iclass="fas fa-home"></i>Home</a></li></ul></section><divclass=highlightable><ulclass=topics><lidata-nav-id=/api/title=APIclass=dd-item><ahref=/api/>API</a></li><lidata-nav-id=/history/title=Historyclass=dd-item><ahref=/history/>History</a></li><lidata-nav-id=/documentation/title=Documentationclass=dd-item><ahref=/documentation/>Documentation</a><ul><lidata-nav-id=/documentation/architecture/title=Architectureclass=dd-item><ahref=/documentation/architecture/>Architecture</a></li><lidata-nav-id=/documentation/model/title=Modelclass=dd-item><ahref=/documentation/model/>Model</a></li><lidata-nav-id=/documentation/do-and-donts/title="Do and Don't"class=dd-item><ahref=/documentation/do-and-donts/>Do and Don't</a></li><lidata-nav-id=/documentation/runtime-configuration/title="Runtime Configuration"class=dd-item><ahref=/documentation/runtime-configuration/>Runtime Configuration</a></li><lidata-nav-id=/documentation/realms/title=Realmsclass=dd-item><ahref=/documentation/realms/>Realms</a></li><lidata-nav-id=/documentation/components/title=Componentsclass=dd-item><ahref=/documentation/components/>Components</a></li><lidata-nav-id=/documentation/services-and-commands/title="Services and Commands"class=dd-item><ahref=/documentation/services-and-commands/>Services and Commands</a></li><lidata-nav-id=/documentation/searches/title=Searchesclass=dd-item><ahref=/documentation/searches/>Searches</a></li><lidata-nav-id=/documentation/queries/title=Queriesclass=dd-item><ahref=/documentation/queries/>Queries</a></li><lidata-nav-id=/documentation/transactions/title=Transactionsclass=dd-item><ahref=/documentation/transactions/>Transactions</a></li><lidata-nav-id=/documentation/policies/title=Policiesclass=dd-item><ahref=/documentation/policies/>Policies</a></li><lidata-nav-id=/documentation/observers/title=Observersclass=dd-item><ahref=/documentation/observers/>Observers</a></li><lidata-nav-id=/documentation/versioning/title=Versioningclass=dd-item><ahref=/documentation/versioning/>Versioning</a></li><lidata-nav-id=/documentation/reports/title=Reportsclass=dd-item><ahref=/documentation/reports/>Reports</a></li><lidata-nav-id=/documentation/priviles/title=Privilegesclass=dd-item><ahref=/documentation/priviles/>Privileges</a></li></ul></li><lidata-nav-id=/plc/title=PLCclass="dd-item
parent"><ahref=/plc/>PLC</a><ul><lidata-nav-id=/plc/architecture/title=Architectureclass=dd-item><ahref=/plc/architecture/>Architecture</a></li><lidata-nav-id=/plc/example-set-up/title="Example Set-Up"class="dd-item active"><ahref=/plc/example-set-up/>Example Set-Up</a></li></ul></li><lidata-nav-id=/tutorial/title=Tutorialclass=dd-item><ahref=/tutorial/>Tutorial</a><ul><lidata-nav-id=/tutorial/configuration/title=Configurationclass=dd-item><ahref=/tutorial/configuration/>Configuration</a></li><lidata-nav-id=/tutorial/model/title=Modelclass=dd-item><ahref=/tutorial/model/>Model</a></li><lidata-nav-id=/tutorial/crud-book/title="CRUD Book"class=dd-item><ahref=/tutorial/crud-book/>CRUD Book</a></li></ul></li><lidata-nav-id=/download/title=Downloadclass=dd-item><ahref=/download/>Download</a></li><lidata-nav-id=/development/title=Developmentclass=dd-item><ahref=/development/>Development</a></li></ul><sectionid=shortcuts><h3>More</h3><ul><li><aclass=paddinghref=https://strolch.li/tags><iclass="fas fa-tags"></i>Tags</a></li><li><aclass=paddinghref=https://github.com/strolch-li><iclass="fab fa-github"></i>GitHub project</a></li></ul></section><sectionid=footer><p>Built with <ahref=https://github.com/matcornic/hugo-theme-learn><iclass="fas fa-heart"></i></a>from <ahref=https://getgrav.org>Grav</a> and <ahref=https://gohugo.io/>Hugo</a></p></section></div></nav><sectionid=body><divid=overlay></div><divclass="padding highlightable"><div><divid=top-bar><divid=top-github-link><aclass=github-linktitle="Edit this page"href=https://github.com/Pi4J/pi4j.github.io/tree/main/contentplc/example-set-up.mdtarget=blank><iclass="fas fa-code-branch"></i><spanid=top-github-link-text>Edit this page</span></a></div><divid=breadcrumbsitemscopeitemtype=http://data-vocabulary.org/Breadcrumb><spanid=sidebar-toggle-span><ahref=#id=sidebar-toggledata-sidebar-toggle><iclass="fas fa-bars"></i></a></span><spanid=toc-menu><iclass="fas fa-list-alt"></i></span><spanclass=links><ahref=/>Strolch Overview</a> > <ahref=/plc/>PLC</a> > Example Set-Up</span></div><divclass=progress><divclass=wrapper><navid=TableOfContents><ul><li><ahref=#example-set-up>Example Set-Up</a></li><li><ahref=#new-project>New Project</a></li></ul></nav></div></div></div></div><divid=head-tags></div><divid=body-inner><h1>Example Set-Up</h1><h2id=example-set-up>Example Set-Up</h2><p>This example setup describes the movement of containers over conveyors. The
conveyors have motors which can be started and stopped by a GPIO output pin
controlled on a Raspberry Pi and each conveyor has a light barrier to detect the
occupancy of a container and the Raspberry Pi detects this on GPIO input pins.</p><p>Further at each conveyor location is a barcode reader to read the ID of a
container.</p><p>The general idea is that the PLC notifies a Strolch agent of changes, and only
turns conveyors on, when the agent gives the command. Thus the agent handles
business logic and the PLC controls the I/Os.</p><p><imgsrc=/assets/images/Strolch-Plc-Example.pngalt="Strolch PLC Example"></p><h2id=new-project>New Project</h2><ol><li>First create a new Strolch Web project using the Strolch Maven archetype</li><li>Now add the following Maven dependencies:</li></ol><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-xmldata-lang=xml><spanstyle=color:#f92672><project></span>
</code></pre></div><olstart=3><li><p>Add a bower dependency: <code>"strolch-wc-plc": "4treesCH/strolch-wc-plc#^0.3.4"</code>
to <code>src/main/webapp/bower.json</code></p><p>After adding the dependency, run <code>gulp</code> in the webapp directory. Gulp should
have been installed through the instructions from
the <ahref=/development>development page</a>.</p></li><li><p>Now we need to add the PLC web views to our new project. This is added in
the <code>src/main/webapp/app/src/c-app.html</code> file. Add the following:</p></li></ol><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-htmldata-lang=html><spanstyle=color:#75715e><!-- HTML Imports --></span>
</code></pre></div><olstart=5><li>Don’t forget to add the PLC Rest classes to your <code>ResourceConfig</code></li></ol><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-javadata-lang=java><spanstyle=color:#a6e22e>@ApplicationPath</span><spanstyle=color:#f92672>(</span><spanstyle=color:#e6db74>"rest"</span><spanstyle=color:#f92672>)</span>
</code></pre></div><olstart=6><li>Now we need to configure the PLC’s runtime by
modifying <code>runtime/StrolchConfiguration.xml</code> and adding the following:</li></ol><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-xmldata-lang=xml>
</code></pre></div><olstart=7><li>Now we add the custom classes we just declared.</li></ol><p><strong>PlcServiceInitializer</strong></p><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-javadata-lang=java><spanstyle=color:#f92672>import</span> java.util.ArrayList<spanstyle=color:#f92672>;</span>
</code></pre></div><olstart=8><li>In the <code>CustomPlcServiceInitializer</code> we added two PlcServices, for which the
code is missing. The following are simple examples:</li></ol><p><strong>StartupPlcService</strong></p><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-javadata-lang=java><spanstyle=color:#f92672>import</span> li.strolch.persistence.api.StrolchTransaction<spanstyle=color:#f92672>;</span>
<spanstyle=color:#66d9ef>public</span><spanstyle=color:#66d9ef>static</span><spanstyle=color:#66d9ef>final</span> String STARTED <spanstyle=color:#f92672>=</span><spanstyle=color:#e6db74>"Started"</span><spanstyle=color:#f92672>;</span>
<spanstyle=color:#66d9ef>boolean</span> active <spanstyle=color:#f92672>=</span><spanstyle=color:#f92672>(</span><spanstyle=color:#66d9ef>boolean</span><spanstyle=color:#f92672>)</span> value<spanstyle=color:#f92672>;</span>
</code></pre></div><olstart=9><li><p>Now the last part is to add the model, i.e. PlcConnections, PlcAddresses and
PlcTelegrams. To have less configuration files and make it easier to
reconfigure at runtime, this data is stored in normal Strolch <code>Resources</code>.</p><p>In this example we will use simple Raspberry Pi GPIOs. For convenience, and
also when sharing I/O definitions with external partners, it is easier to use
a CSV file to define the I/Os and then use the <code>PlcAddressGenerator</code> to
generate and validate the model.</p><p>For this purpose in this example, we will use one conveyor with 2 inputs and
1 output. The CSV file should have the following content:</p></li></ol><pre><codeclass=language-csvdata-lang=csv>Description,Type,SubType,Device,Pin,Resource,Action1,Action2,Connection,DeviceId
</code></pre><p>The CSV headers are as follows:</p><ul><li>Description → a simple description for this PlcAddress</li><li>Type →<ul><li>Group → Must be the first line and generates a PlcLogicalDevice, all
succeeding lines are grouped to this device. Add additional to group
further devices</li><li>Input → defines a boolean input</li><li>Output → defines a boolean output</li><li>Virtual → defines a virtual address which has no corresponding hardware
connection. Used for internal communication.</li><li>DataLogicScanner → defines an address to read barcodes from a DataLogic
Scanner. The actions must be left empty as the keys Barcode (address), On
and Off (telegrams) will be generated.</li></ul></li><li>SubType →</li><li>For Input and Output types →<ul><li>DevPin, DevPin0 → Generates the address as <code><Connection>.<Device>.<Pin></code>.
DevPin0 decrements the Device and Pin values by one.</li><li>Pin → Generates the address as <code><Connection>.<Pin></code>.</li></ul></li><li>For Virtual types →<ul><li>Boolean</li><li>String</li></ul></li><li>Device → Device number</li><li>Pin → The pin number on the device</li><li>Resource → The resource ID with which to notify the agent</li><li>Action1 → The action ID</li><li>Action2 → The second action ID if required</li><li>Connection → The ID of the PlcConnection with which this I/O is attached</li><li>DeviceId → For type Group: Set the ID of this PlcLogicalDevice being generated</li></ul><p>When you use this file as input for the <code>PlcAddressGenerator</code>, then it will
generate PlcLogicalDevice, PlcAddress and PlcTelegram elements:</p><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-xmldata-lang=xml><spanstyle=color:#f92672><StrolchModel></span>
<spanstyle=color:#f92672><Parameter</span><spanstyle=color:#a6e22e>Id=</span><spanstyle=color:#e6db74>"resource"</span><spanstyle=color:#a6e22e>Name=</span><spanstyle=color:#e6db74>"Resource ID for PlcAddress"</span>
<spanstyle=color:#f92672><Parameter</span><spanstyle=color:#a6e22e>Id=</span><spanstyle=color:#e6db74>"action"</span><spanstyle=color:#a6e22e>Name=</span><spanstyle=color:#e6db74>"Action ID for PlcAddress"</span><spanstyle=color:#a6e22e>Type=</span><spanstyle=color:#e6db74>"String"</span>
<spanstyle=color:#f92672><Parameter</span><spanstyle=color:#a6e22e>Id=</span><spanstyle=color:#e6db74>"resource"</span><spanstyle=color:#a6e22e>Name=</span><spanstyle=color:#e6db74>"Resource ID for PlcAddress"</span>
<spanstyle=color:#f92672><Parameter</span><spanstyle=color:#a6e22e>Id=</span><spanstyle=color:#e6db74>"action"</span><spanstyle=color:#a6e22e>Name=</span><spanstyle=color:#e6db74>"Action ID for PlcAddress"</span><spanstyle=color:#a6e22e>Type=</span><spanstyle=color:#e6db74>"String"</span>
a <code><IncludeFile file="plc-state.xml" /></code> element. Modify the <code>PlcId</code> to be the
same as the one you defined in the <code>StrolchConfiguration.xml</code>.</p></li><li><p>Now that we have a model, the <code>PlcConnections</code> are to be defined. In the
previous example we used a Raspberry Pi’s GPIOs. This needs to be defined as
a <code>PlcConnection</code>:</p></li></ol><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-xmldata-lang=xml>
<spanstyle=color:#f92672><Parameter</span><spanstyle=color:#a6e22e>Id=</span><spanstyle=color:#e6db74>"stateMsg"</span><spanstyle=color:#a6e22e>Name=</span><spanstyle=color:#e6db74>"Connection State Msg"</span><spanstyle=color:#a6e22e>Type=</span><spanstyle=color:#e6db74>"String"</span>
<spanstyle=color:#f92672><Parameter</span><spanstyle=color:#a6e22e>Id=</span><spanstyle=color:#e6db74>"stateMsg"</span><spanstyle=color:#a6e22e>Name=</span><spanstyle=color:#e6db74>"Connection State Msg"</span><spanstyle=color:#a6e22e>Type=</span><spanstyle=color:#e6db74>"String"</span>
</code></pre></div><p>See <ahref=https://github.com/4treesCH/strolch-plc/blob/develop/example/strolch-plc-example-connections.xml>strolch-plc-example-connections.xml</a> for further examples.</p><footerclass=footline></footer></div></div><divid=navigation><aclass="nav nav-prev"href=/plc/architecture/title=Architecture><iclass="fa fa-chevron-left"></i></a><aclass="nav nav-next"href=/tutorial/title=Tutorialstyle=margin-right:0><iclass="fa fa-chevron-right"></i></a></div></section><divstyle=left:-1000px;overflow:scroll;position:absolute;top:-1000px;border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px><divstyle=border:none;box-sizing:content-box;height:200px;margin:0;padding:0;width:200px></div></div><scriptsrc=/js/clipboard.min.js?1626091328></script><scriptsrc=/js/perfect-scrollbar.min.js?1626091328></script><scriptsrc=/js/perfect-scrollbar.jquery.min.js?1626091328></script><scriptsrc=/js/jquery.sticky.js?1626091328></script><scriptsrc=/js/featherlight.min.js?1626091328></script><scriptsrc=/js/highlight.pack.js?1626091328></script><script>hljs.initHighlightingOnLoad();</script><scriptsrc=/js/modernizr.custom-3.6.0.js?1626091328></script><scriptsrc=/js/learn.js?1626091328></script><scriptsrc=/js/hugo-learn.js?1626091328></script><scriptsrc=/mermaid/mermaid.js?1626091328></script><script>mermaid.initialize({startOnLoad:true});</script></body></html>