<!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="Robert von Burg"><linkrel=iconhref=/favicon.icotype=image/ico><title>Example Set-Up - Strolch</title><linkhref=/css/nucleus.css?1678977092rel=stylesheet><linkhref=/css/fontawesome-all.min.css?1678977092rel=stylesheet><linkhref=/css/hybrid.css?1678977092rel=stylesheet><linkhref=/css/featherlight.min.css?1678977092rel=stylesheet><linkhref=/css/perfect-scrollbar.min.css?1678977092rel=stylesheet><linkhref=/css/auto-complete.css?1678977092rel=stylesheet><linkhref=/css/atom-one-dark-reasonable.css?1678977092rel=stylesheet><linkhref=/css/theme.css?1678977092rel=stylesheet><linkhref=/css/hugo-theme.css?1678977092rel=stylesheet><linkhref=/css/theme-green.css?1678977092rel=stylesheet><scriptsrc=/js/jquery-3.3.1.min.js?1678977092></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?1678977092></script><scripttype=text/javascriptsrc=/js/auto-complete.js?1678977092></script><scripttype=text/javascript>varbaseurl="https:\/\/strolch.li\/";</script><scripttype=text/javascriptsrc=/js/search.js?1678977092></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=/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><ul><lidata-nav-id=/development/prerequisites/title=Prerequisitesclass=dd-item><ahref=/development/prerequisites/>Prerequisites</a></li><lidata-nav-id=/development/building/title="Building Strolch"class=dd-item><ahref=/development/building/>Building Strolch</a></li><lidata-nav-id=/development/maven-archetypes/title="Maven Archetypes"class=dd-item><ahref=/development/maven-archetypes/>Maven Archetypes</a></li><lidata-nav-id=/development/web-app/title="Web App"class=dd-item><ahref=/development/web-app/>Web App</a></li><lidata-nav-id=/development/main-class-app/title="Main Class App"class=dd-item><ahref=/development/main-class-app/>Main Class App</a></li><lidata-nav-id=/development/converting-existing/title="Converting Existing App"class=dd-item><ahref=/development/converting-existing/>Converting Existing App</a></li></ul></li><lidata-nav-id=/blog/title=Blogclass=dd-item><ahref=/blog/>Blog</a><ul><lidata-nav-id=/blog/post-00018/title="Strolch PLC 1.2.3 released"class=dd-item><ahref=/blog/post-00018/>Strolch PLC 1.2.3 released</a></li><lidata-nav-id=/blog/post-00017/title="Strolch 1.8.5 and PLC 1.2.2 are out"class=dd-item><ahref=/blog/post-00017/>Strolch 1.8.5 and PLC 1.2.2 are out</a></li><lidata-nav-id=/blog/post-00016/title="Strolch PLC now also on Maven Central"class=dd-item><ahref=/blog/post-00016/>Strolch PLC now also on Maven Central</a></li><lidata-nav-id=/blog/post-00015/title="Release of Strolch 1.6.100"class=dd-item><ahref=/blog/post-00015/>Release of Strolch 1.6.100</a></li><lidata-nav-id=/blog/post-00014/title="Strolch Reports"class=dd-item><ahref=/blog/post-00014/>Strolch Reports</a></li><lidata-nav-id=/blog/post-00013/title="Strolch Searches"class=dd-item><ahref=/blog/post-00013/>Strolch Searches</a></li><lidata-nav-id=/blog/post-00012/title="Wow, the many changes!"class=dd-item><ahref=/blog/post-00012/>Wow, the many changes!</a></li><lidata-nav-id=/blog/post-00011/title="Strolch now on Maven Central"class=dd-item><ahref=/blog/post-00011/>Strolch now on Maven Central</a></li><lidata-nav-id=/blog/post-00010/title="Versioning of objects"class=dd-item><ahref=/blog/post-00010/>Versioning of objects</a></li><lidata-nav-id=/blog/post-00009/title="Release 1.2.0"class=dd-item><ahref=/blog/post-00009/>Release 1.2.0</a></li><lidata-nav-id=/blog/post-00008/title="Strolch Update"class=dd-item><ahref=/blog/post-00008/>Strolch Update</a></li><lidata-nav-id=/blog/post-00007/title="Activities: Beginning of the planning engine"class=dd-item><ahref=/blog/post-00007/>Activities: Beginning of the planning engine</a></li><lidata-nav-id=/blog/post-00006/title="Strolch Documentation"class=dd-item><ahref=/blog/post-00006/>Strolch Documentation</a></li><lidata-nav-id=/blog/post-00005/title="Strolch Release 1.0.0"class=dd-item><ahref=/blog/post-00005/>Strolch Release 1.0.0</a></li><lidata-nav-id=/blog/post-00004/title="DurationParameter and other minor changes: Release 1.0.0-RC4"class=dd-item><ahref=/blog/post-00004/>DurationParameter and other minor changes: Release 1.0.0-RC4</a></li><lidata-nav-id=/blog/post-00003/title="DBInitiali
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><p>Create a new project using the PLC Strolch Maven Archetype:</p><divclass=highlight><prestyle=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><codeclass=language-shelldata-lang=shell>mvn archetype:generate <spanstyle=color:#ae81ff>\
</code></pre></div><p>This will create a multi-module project:</p><ul><li>The <code><my-artifactId>-web</code> module contains the server code, which handles notifications from the PLC, and can send
telegrams to the PLC.</li><li>The <code><my-artifactId>-plc-web</code> module contains the PLC code, which connects to the server and communicates with the
low-level hardware.</li><li>The <code>shared</code> modules contains classes shared by both projects (e.g. constants, etc.).</li></ul><p>This project already contains a default PLC model in <code><my-artifactId>-plc-web/runtime/data/</code>.</p><p>The following sections explains these files:</p><h3id=strolch-plc-example-connectionsxml>strolch-plc-example-connections.xml</h3><p>This file defines the hardware connections. The following connections are implemented:</p><ul><li>li.strolch.plc.core.hw.i2c.RSL366OverHorterI2c</li><li>li.strolch.plc.core.hw.i2c.PCF8574InputConnection</li><li>li.strolch.plc.core.hw.gpio.RaspiBcmGpioInputConnection</li><li>li.strolch.plc.core.hw.gpio.RaspiBcmGpioOutputConnection</li><li>li.strolch.plc.core.hw.i2c.Multi8BitI2cOutputConnection</li><li>li.strolch.plc.core.hw.connections.DataLogicScannerConnection</li><li>li.strolch.plc.core.hw.connections.LoggerOutConnection</li><li>li.strolch.plc.core.hw.connections.RandomStringConnection</li></ul><p>See their respective classes for details.</p><h3id=strolch-plc-examplecsv>strolch-plc-example.csv</h3><p>This file maps I/Os to Resources and Actions and is converted into Strolch <code>Resource</code> objects using
the <code>PlcAddressGenerator</code> class.</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 easier handling, use the following Google Sheet as a starting
point: <ahref="https://docs.google.com/spreadsheets/d/10fgTfR3FZCVbQ5bbh0xB1u8rLIaw2KEyO45VMv7y5ho/edit?usp=sharing">https://docs.google.com/spreadsheets/d/10fgTfR3FZCVbQ5bbh0xB1u8rLIaw2KEyO45VMv7y5ho/edit?usp=sharing</a></p><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 →<ul><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 for zero-indexed addressing.</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><li>Integer</li></ul></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><li>Interted → For boolean inputs or outputs, if true, inverts the value</li><li>Value → A default value, often used for virtual integer addresses</li><li>Remote → if true, then the server will be notified of changes to this address</li></ul><p>When you use this file as input for the <code>PlcAddressGenerator</code>, then it will
generate PlcLogicalDevice, PlcAddress and PlcTelegram elements. See the file <code>strolch-plc-example.xml</code> for an example.</p><p>The <code>PlcLogicalDevice</code> references the <code>PlcAddress</code> and <code>PlcTelegram</code> objects, and is
then used in the UI for grouping.</p><p>The <code>PlcAddress</code> is used to store the current value and defines the keys with
which the agent will be notified</p><p>The <code>PlcTelegram</code> is used to store default values to send, for specific keys. E.g.
is defined in each project depending on the hardware.</p><h3id=running-the-example>Running the example</h3><p>Once you have both the server and PLC instances running, you can login. The default username and password are <code>admin</code>
/ <code>admin</code>.</p><p>After logging in to the PLC you should be greeted with the following
screen:
<imgsrc=/assets/images/plc.pngalt="PLC UI"></p><p>And after logging in to the server you should be greeted with the following
screen:
<imgsrc=/assets/images/plc-server.pngalt="Server UI"></p><p>If the PLC could connect to the server, then the <code>PLC Control</code> icon should be activated. The actions Enable, Disable and
Stop All send telegrams to the PLC, thus showing how the server would communicate with the PLC.</p><h3id=customization>Customization</h3><h4id=plc>PLC</h4><p>Now that the server and PLC are running, we can customize the code. On the PLC side you will want to create
new <code>li.strolch.plc.core.PlcService</code> services by extending the class and then registering the service
in <code>CustomPlcServiceInitializer</code>.</p><p>See the example <code>StartupPlcService</code>.</p><h4id=server>Server</h4><p>On the server side, to register for notifications from the PLC, one would
implement <code>li.strolch.plc.gw.server.PlcGwService</code> services and register them on the <code>PlcHandler</code> in
the <code>PostInitializer</code> class.</p><p>See the example <code>ModePlcSrvService</code>.</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?1678977092></script><scriptsrc=/js/perfect-scrollbar.min.js?1678977092></script><scriptsrc=/js/perfect-scrollbar.jquery.min.js?1678977092></script><scriptsrc=/js/jquery.sticky.js?1678977092></script><scriptsrc=/js/featherlight.min.js?1678977092></script><scriptsrc=/js/highlight.pack.js?1678977092></script><script>hljs.initHighlightingOnLoad();</script><scriptsrc=/js/modernizr.custom-3.6.0.js?1678977092></script><scriptsrc=/js/learn.js?1678977092></script><scriptsrc=/js/hugo-learn.js?1678977092></script><scriptsrc=/mermaid/mermaid.js?1678977092></script><script>mermaid.initialize({startOnLoad:true});</script><scripttype=text/javascript>var_paq=window._paq=window._paq||[];_paq.push(["setDocumentTitle",document.domain+"/"+document.title]);_paq.push(["setCookieDomain","*.strolch.li"]);_paq.push(['trackPageView']);_paq.push(['enableLinkTracking']);(function(){varu="https://piwik.eitchnet.ch/";_paq.push(['setTrackerUrl',u+'matomo.php']);_paq.push(['setSiteId','2']);vard=document,g=d.createElement('script'),s=d.getElementsByTagName('script')[0];g.type='text/javascript';g.async=true;g.src=u+'matomo.js';s.parentNode.insertBefore(g,s);})();</script></body></html>