Masterproef Code generator voor PLC en SCADA
Studiegebied Industriële wetenschappen en technologie Opleiding Master in de industriële wetenschappen: elektronica-ict Afstudeerrichting Informatie- en communicatietechnologie Academiejaar 2008-2009
Simon Segers Howest – departement PIH, Graaf Karel de Goedelaan 5, 8500 Kortrijk
Voorwoord Deze thesis zie ik als de bekroning en tevens als eindpunt van mijn opleiding als industrieel ingenieur. Ik had het geluk om deze belangrijke opdracht uit te voeren binnen Avalon Automation waar de medewerkers me met raad en daad bijstonden. Langs deze weg wil ik in het bijzonder mijn externe promotor dhr. Kris Heirbaut bedanken voor zijn hulp en nuchtere kijk. Ik vind het namelijk niet vanzelfsprekend dat een bedrijf een heel jaar tijd vrijmaakt voor een student.
Vervolgens had ik graag een dankwoord gegeven aan mijn interne promotor dhr. Filip De Pauw. Hij gaf me voldoende feedback en opmerkingen zodat het eindwerk van een goed niveau was.
Als laatste wil ik mijn ouders bedanken om me de kans te geven een tweede diploma te behalen en om me te steunen tijdens het afwerken van deze thesis.
I
Inhoudsopgave Voorwoord ........................................................................................................................ I Inhoudsopgave ................................................................................................................. II Gebruikte symbolen en afkortingen .................................................................................. V Lijst van figuren ............................................................................................................... VI 1 Inleiding..................................................................................................................... 1 2 Bedrijfsvoorstelling .................................................................................................... 2 2.1 Historiek....................................................................................................................... 2 2.2 Activiteiten................................................................................................................... 3 2.2.1 Marktsector .......................................................................................................... 3 2.2.2 Hardware .............................................................................................................. 4 2.2.3 Software ............................................................................................................... 5 2.3 Projectprocedure ......................................................................................................... 7 3 Studie Rockwell Software........................................................................................... 9 3.1 Inleiding ....................................................................................................................... 9 3.2 Tags en routines .......................................................................................................... 9 3.2.1 Routines................................................................................................................ 9 3.2.2 Program tags ...................................................................................................... 11 3.2.3 Add-on instructions ............................................................................................ 12 3.2.4 Controller tags .................................................................................................... 12 3.3 Import/export ............................................................................................................ 12 3.3.1 L5K ...................................................................................................................... 12 3.3.2 L5X ...................................................................................................................... 13 3.3.3 CSV ...................................................................................................................... 13 3.4 Ladderdiagram code .................................................................................................. 15 3.5 Globale variabelen code ............................................................................................ 16 4 Studie Beckhoff software ......................................................................................... 17 4.1 Inleiding ..................................................................................................................... 17 4.2 Program organization units ....................................................................................... 18 4.2.1 Functions ............................................................................................................ 18 4.2.2 Function block .................................................................................................... 18 4.2.3 Program .............................................................................................................. 18 4.3 Datatypes ................................................................................................................... 19 4.4 Resources................................................................................................................... 20 4.5 Import/ export ........................................................................................................... 22 4.5.1 EXP files .............................................................................................................. 22 4.6 Ladderdiagram code .................................................................................................. 22 4.7 Globale variabelen code ............................................................................................ 25 II
5 Uitwerking: onderzoek ............................................................................................. 26 5.1 Inleiding ..................................................................................................................... 26 5.2 Eigen template generator .......................................................................................... 26 5.3 Codesmith Tools ........................................................................................................ 27 5.3.1 inleiding .............................................................................................................. 27 5.3.2 Properties ........................................................................................................... 28 5.3.3 Templates ........................................................................................................... 28 5.3.4 Code-behind ....................................................................................................... 29 6 Uitwerking: applicatie .............................................................................................. 30 6.1 Opbouw ..................................................................................................................... 30 6.1.1 Schematische voorstelling.................................................................................. 30 6.1.2 Componenten..................................................................................................... 31 6.2 Devicelijst................................................................................................................... 32 6.2.1 Opbouw .............................................................................................................. 32 6.3 Templates .................................................................................................................. 33 6.3.1 Inleiding .............................................................................................................. 33 6.3.2 Beckhoff templates ............................................................................................ 33 6.3.2.1 Ladderdiagram ............................................................................................ 33 6.3.2.2
Globale variabelen ...................................................................................... 35
6.3.3 6.3.3.1
Rockwell templates ............................................................................................ 36 Ladderdiagram code ................................................................................... 36
6.3.3.2
Globale variabelen ...................................................................................... 36
6.4 Main template ........................................................................................................... 37 6.4.1 Inleiding .............................................................................................................. 37 6.4.2 Templates: registraties en instanties aanmaken ............................................... 37 6.4.2.1 Inleiding....................................................................................................... 37 6.4.2.2
Externe bestanden ...................................................................................... 38
6.4.2.3
Mappenstructuur ........................................................................................ 39
6.4.2.4
Registratiefunctie ........................................................................................ 40
6.4.2.5
Registratietemplate .................................................................................... 41
6.4.2.6
Instanties aanmaken ................................................................................... 42
6.4.3 6.4.3.1
Excel uitlezen ...................................................................................................... 45 Inleiding....................................................................................................... 45
6.4.3.2
OLE DB connectie ........................................................................................ 45
6.4.4 6.4.4.1
Devicetemplates opbouwen .............................................................................. 47 Inleiding....................................................................................................... 47
6.4.4.2
Devicelijnen ordenen .................................................................................. 47 III
6.4.4.3
Dictionary uitlezen ...................................................................................... 49
6.4.4.4
Body ............................................................................................................ 49
6.5 Codesmith GUI ........................................................................................................... 55 6.5.1 Inleiding .............................................................................................................. 55 6.5.2 Codesmith GUI instellingen ................................................................................ 55 7 Besluit ..................................................................................................................... 57 8 Literatuurlijst ........................................................................................................... 58 9 Bijlagen.................................................................................................................... 60 Bijlage 1............................................................................................................................. I Bijlage 2............................................................................................................................ II Bijlage 3............................................................................................................................ X Bijlage 4........................................................................................................................ XVII
IV
Gebruikte symbolen en afkortingen ADO.NET
ActiveX Data Objects for .NET
ASCII
American Standard Code for Information Interchange
CSV
Comma Separated Values
FAT
Factory Acceptance Test
FBD
Function Block Diagram
GUI
Graphical User Interface
HMI
Human Machine Interface
LD
Ladder Diagram
ODBC
Open Database Connectivity
OLE DB
Object Linking and Embedding Database
P&ID
Process and Instrumentation Diagram
PLC
Programmable Logic Controller
POU
Program Organization Units
SAT
Site Acceptance Test
SCADA
Supervisory Control and Data Acquisition
SFC
Sequential Function Chart
SFC
Sequential Function Chart
SQL
Structured Query Language
ST
Structured Text
XML
Extensible Markup Language
V
Lijst van figuren Figuur 1: Logo Avalon Automation............................................................................................. 2 Figuur 2: Tankterminals LBC Ertisa te Antwerpen (op de site van Bayer) ................................. 3 Figuur 3: Allen-Bradley PLC-LBC Ertisa Bayer Antwerpen .......................................................... 4 Figuur 4: Mercury 2e HMI .......................................................................................................... 5 Figuur 5: Deel van een P&ID schema ......................................................................................... 7 Figuur 6: Routine in Rockwell RSLogix 5000 ............................................................................ 11 Figuur 7: Deeltje L5X bestand .................................................................................................. 13 Figuur 8: Rockwell: Ladderdiagram blokje en Ladderdiagram codelijnen ............................... 15 Figuur 9: Rockwell: Variabelen datablok.................................................................................. 16 Figuur 10: Programma in Beckhoff TwinCAT PLC control ........................................................ 19 Figuur 11: Globale persistente variabelen in TwinCAT ............................................................ 20 Figuur 12: Header ladderdiagram bestand .............................................................................. 23 Figuur 13: Beckhoff: Ladderdiagram blokje en ladderdiagram codelijnen .............................. 24 Figuur 14: Twincat: Globale variabelen datablok .................................................................... 25 Figuur 15: Codesmith: Tools properties ................................................................................... 28 Figuur 16: Beckhoff: Ladderdiagram template ........................................................................ 33 Figuur 17: Beckhoff: Globale variabelen template .................................................................. 35 Figuur 18: Codesmith: Sub-template registratielijnen ............................................................. 37 Figuur 19: Mappenstructuur templates ................................................................................... 39 Figuur 20: Toevoegen van assemblies en namespaces ........................................................... 41 Figuur 21: Toevoegen van een registratielijn........................................................................... 41 Figuur 22: Dictionary sleutel en waarde toevoegen ................................................................ 44 Figuur 23: Codesmith: GUI ....................................................................................................... 55
VI
1 Inleiding Dit eindwerk wordt uitgevoerd in samenwerking met Avalon Automation. Het bedrijf is gespecialiseerd in automatiseringsprojecten en dit voornamelijk op de markt van tankterminals.
Bij het automatiseren van een tankpark wordt gewerkt met devices (kleppen ,motoren,…) die het mogelijk maken om ladingen te verschepen van tanks naar vrachtwagens, wagons en schepen. Voor het aansturen van deze devices wordt gewerkt met PLC’s. Ieder device moet nu worden geprogrammeerd binnen onder andere Beckhoff TwinCAT of Rockwell RSLogix 5000. Het aantal devices binnen een tankpark kan zeer snel oplopen, bovendien moet bij het programmeren van ieder device een tiental parameters worden ingevoerd. Het is vrij duidelijk dat dit een tijdrovende activiteit is. Het doel van deze masterproef is om een tool te ontwikkelen die dit proces kan automatiseren.
Een eerste doelstelling is om van beide softwarepakketten: Beckhoff TwinCAT en Rockwell RSLogix 5000 een studie te maken om inzicht te krijgen in de verschillende functies.
De tweede doelstelling is om een code generator te ontwikkelen in C# die werkt met templates. Ieder specifiek device moet een template hebben waarin zijn data en parameters staan. Met de code generator moet het mogelijk zijn om twee soorten codefiles te laten genereren vertrekkende van een devicelijst in Excel. Deze twee soorten codefiles zijn ladderdiagram code en globale variabelen code.
De laatste vereiste bestaat erin om deze code generator zo generiek mogelijk op te stellen zodat er in de toekomst devicetemplates kunnen bijkomen en dat de tool ook voor andere PLC- en SCADA-softwarepakketten kan worden gebruikt.
De eerste taak bestaat erin om inzicht te krijgen in de twee softwarepakketten waarvoor de code generator codefiles moet kunnen genereren. Vervolgens moet er onderzocht worden wat de beste ontwikkelprocedure is voor de code generator. Nadat er een gefundeerde keuze is gemaakt kan er worden overgaan tot het ontwerpen van de tool. Een laatste fase is het zorgvuldig testen van de applicatie onder toezicht van de eindgebruikers.
. Code generator voor PLC en SCADA
1
2 Bedrijfsvoorstelling 2.1 Historiek Avalon Automation werd opgericht door Pascal Vande Velde op 4 mei 2004. Het is een jong bedrijf maar heeft mensen aan boord met veel ervaring. In 2005 breidde het bedrijf fors uit met de aanwervingen van een project manager, site manager en software developers. Allemaal hadden ze jaren ervaring in automatiseringsprojecten. Nog in hetzelfde jaar werd de hoofdzetel gevestigd in Ieper. In 2006 werd de onderneming opnieuw versterkt met vier talentvolle ingenieurs.
Avalon Automation werkt nauw samen met hogescholen en universiteiten en het bedrijf mag op 25 oktober 2007 de Innovation Awards in ontvangst nemen. Het afstudeerwerk van Dries Verbrugge (Hogeschool West-Vlaanderen PIH) valt in de prijzen in de categorie economie en organisatie.
Ieder jaar is Avalon Automation uitdrukkelijk aanwezig op StocExpo. Deze beurs is het grootste event voor de tankterminal industrie.
Momenteel is de volledige R&D-afdeling gelegen in Haasdonk. De hoofdzetel in Ieper is de commerciële vestiging van Avalon Automation.
Figuur 1: Logo Avalon Automation
Code generator voor PLC en SCADA
2
2.2 Activiteiten 2.2.1 Marktsector Avalon Automation specialiseert zich in automatiseringsprojecten, voornamelijk voor tankterminals binnen de petrochemie- en voedingsector. Ze verzorgen zowel de hardware als de software. Onder hardware verstaan we de meettoestellen, sensoren en elektrische installaties. De softwarekant bestaat uit het ontwikkelen van controlesoftware voor de aansturing van de devices (kleppen, motoren,… ), maar ook visualisatiesoftware gebaseerd op verkregen input (metingen, waarden van de sensoren). Om een beter zicht te krijgen op een volledig automatiseringsproject bekijken we even de hardware en software van dichterbij.
Figuur 2: Tankterminals LBC Ertisa te Antwerpen (op de site van Bayer)
Code generator voor PLC en SCADA
3
2.2.2 Hardware De hardware kant bestaat uit PLC’s. Dit zijn elektrische apparaten met een microprocessor die via IO modules, ingangen binnenlezen en uitgangen aansturen. PLC’s sturen machines aan en zijn een zeer belangrijk onderdeel in de automatisering. Binnenin de PLC wordt voortdurend een vaste, voorgeprogrammeerde cyclus doorlopen. Aan het begin van de cyclus worden de ingangen ingelezen en aan het einde worden de uitgangen aangestuurd. Nieuwere PLC’s lezen de ingangen in op het moment dat ze die nodig hebben in het programma en sturen daarna meteen de uitgangen aan nadat de logica is uitgewerkt. Deze types wachten dus niet tot de cyclus volledig afgelopen is.
Figuur 3: Allen-Bradley PLC-LBC Ertisa Bayer Antwerpen
Client PC’s behoren ook tot de hardware kant. Deze worden gebruikt om de verschillende devices aan te sturen. Dit gebeurt door middel van controle- en visualisatiesoftware. Servers hebben ook een belangrijke plaats binnen een automatiseringsproject. Vaak wordt er gebruik gemaakt van een server waar IDAS of ALIAS software op geïnstalleerd wordt. Deze softwarepakketten laten toe om order-based vrachtwagens of treinen te beladen. Hierbij krijgt de chauffeur een nummer waar hij een bepaalde lading moet oppikken en ondertussen wordt de factuur en orderpapieren reeds afgedrukt. Het afnemen van ladingen uit de tankterminal naar vrachtwagens of treinen kan ook “manueel” gebeuren. Hierbij wordt van de field-operator verwacht dat hij een aantal parameters opgeeft aan de HMI.
Code generator voor PLC en SCADA
4
Een HMI-systeem bestaat vaak uit een touch screen met ingebouwde processor, geheugen en communicatiekaarten.
Figuur 4: Mercury 2e HMI
Het plaatsen van sensoren behoort ook tot een van de vakgebieden van Avalon Automation. Onder sensoren verstaan we temperatuursensoren, druksensoren, overvulbeveiliging,…
2.2.3 Software De software is de tweede peiler binnen automatisering. Zoals hierboven vermeld zijn ALIAS en IDAS softwarepakketten ontwikkeld om orders volledig automatisch af te handelen. De verschillende devices binnen een automatiseringsproject moeten ook worden geprogrammeerd in Beckhoff software of Rockwell software. Deze pakketten worden later uitvoerig besproken.
De visualisatie- en controlesoftware moet eveneens ontwikkeld worden voor de daadwerkelijke aansturing van de apparaten (kleppen, motoren,…), gebaseerd op de verkregen input (metingen, sensoren). Deze software zorgt voor de automatische aansturing, wat de processen vereenvoudigt, maar tevens voor de alarmering wat garant staat voor een goede veiligheid. Een basisfunctie van deze software is ook het bekijken van historiekgegevens. Code generator voor PLC en SCADA
5
De verzamelnaam voor visualisatie- en controlesoftware heet SCADA en is een afkorting voor het verzamelen, doorsturen, verwerken en visualiseren van meet- en regelsignalen van verschillende machines in grote industriële systemen. Avalon Automation maakt gebruik van verschillende pakketten. Voor Beckhoff PLC’s gebruiken ze het zenOn-pakket van Copa Data. Voor Allen-Bradley PLC’s gebruiken ze FactoryTalk View Site Edition van Rockwell.
Code generator voor PLC en SCADA
6
2.3 Projectprocedure Bij het opstarten van een nieuw project door Avalon Automation wordt een uitgebreide projectprocedure gevolgd. Alles begint bij een procestekening. Binnen het bedrijf wordt dit P&ID genoemd, wat staat voor Process en Instrumentation Diagram. Hieronder vindt u een voorbeeld van een deel van zo’n tekening. Op een procestekening staan alle kleppen, motoren, sensoren, leidingen,….
Figuur 5: Deel van een P&ID schema
Aan de hand van deze P&ID gebeurt de electrical engineering. Er worden schema’s opgesteld die gebruikt worden voor de elektrische borden. Met de P&ID wordt er ook een instrumentenlijst en een I/O lijst opgesteld. De instrumentenlijst bestaat uit een Excellijst die ieder device bevat die op de P&ID tekening staat. De I/O lijst bevat alle input en output lijnen.
Aan de hand van de P&ID tekening wordt er een functionele beschrijving gemaakt door de PLC-programmeur. Nadat de functionele beschrijving goedgekeurd is door de klant worden het PLC-programma en de SCADA-beelden ontwikkeld. De instrumentenlijst is nodig om daaruit de ladderfiles voor de device sturingen aan te maken. De I/O lijst wordt gebruikt voor de I/O configuratie in de PLC. De P&ID is belangrijk bij het ontwikkelen van de SCADAbeelden en tenslotte is de functionele beschrijving nodig voor het PLC-programma. Code generator voor PLC en SCADA
7
Als het PLC-programma en de SCADA-beelden klaar zijn wordt de volledige werking gecontroleerd via simulatie door middel van in-house testen. Hierna wordt de klant uitgenodigd voor een FAT-test, waarbij aan de klant de correcte werking via simulatie wordt getoond. Hier controleert de klant ook of de applicatie voldoet aan alle technische specificaties. Ondertussen zijn op de werf de elektrische werken afgerond. Het volgende wat op de werf gebeurt zijn de I/O testen. Dit zijn testen die de link tussen de hardware en de software controleren. Op de werf gebeurt er ook een SAT, waarbij de correcte werking in realiteit aan de klant wordt aangetoond.
Een van de laatste stappen in de projectprocedure zijn de productietesten, waarbij alle parameters juist worden ingesteld bij een eerste productierun. Daarna kan het systeem effectief in gebruik worden genomen. Deze laatste stap wordt meestal door de klant zelf uitgevoerd.
Code generator voor PLC en SCADA
8
3 Studie Rockwell Software 3.1 Inleiding Binnen Avalon Automation wordt gewerkt met Rockwell-software (RSLogix 5000 en FactoryTalk). Deze software worden aangeboden door Rockwell Automation die marktleider is in productieautomatisering. Ze bieden ontelbare producten aan waaronder PLCs, operator-machine-interfaces, industriële PC’s, sensoren, industriële software,…
Alvorens de code generator te ontwikkelen is het belangrijk om de Rockwell-software van dichterbij te bekijken. De codefiles die later gegenereerd zullen worden moeten immers correct worden geïmporteerd in RSLogix 5000. Een studie van dit softwarepakket was dus zeer belangrijk. Onder studie verstaan we: hoe moet de syntax van de verschillende codefiles eruit zien, hoe gebeurt het importeren en exporteren van RSLogix,…
3.2 Tags en routines Binnen de ontwikkelomgeving van RSLogix 5000 wordt gewerkt met verschillende tags en instructies. We vinden er routines, program tags, add-on instructions, controller tags,…. We bekijken al deze componenten nu even afzonderlijk om een goed beeld te hebben wat er later in de codefiles moeten komen.
3.2.1 Routines Routines bevatten de uitvoerbare code voor het project in een controller. Ieder project heeft een main routine, deze wordt als eerste uitgevoerd en hieruit kunnen ook andere routines worden aangesproken. Bij het toevoegen van een nieuwe routine krijgt de gebruiker de keuze om te kiezen welk type routine hij wenst aan te maken. Deze types zijn ladder diagram, function block diagram, sequential functional chart en structured text. De te ontwikkelen tool dient enkel code te genereren voor het ladder diagram type. •
Ladder Diagram
Ladderdiagram is een programmeertaal waarvan de opbouw lijkt op die van een ladder. Een andere naam voor ladderdiagram code is ladder logic. Ladder logic wordt veel gebruikt voor PLC-programma’s en bestaat uit rungs. Rungs zijn als het ware de “trappen” op de ladder en bestaan uit elektrische schema’s en deviceblokken. Code generator voor PLC en SCADA
9
Deze worden sequentieel uitgevoerd door de PLC, van links naar rechts en van boven naar onder. De syntax van ladder logica van twee fabrikanten kan sterk verschillen, het is dus niet één programmeertaal maar een verzameling van sterk gerelateerde talen. •
Function Block Diagram
Functieblokken zijn een uitbreiding op de ladderdiagrammen. Het is eigenlijk een vorm van modulair programmeren met ladders. Een aantal logisch bij elkaar horende “trappen” van een ladder worden samengevoegd tot een functieblok. Deze functieblokken kunnen op verschillende plaatsen worden gebruikt. •
Sequential Functional Chart
Een andere belangrijke manier van programmeren van PLC’s is het toepassen van sequential function charts. Dit soort diagram geeft stap voor stap aan welke acties op welk tijdstip en onder welke voorwaarden moeten plaatsvinden. SFC’s vormen een heel andere programmeerwijze. Een SFC is meer een standaard toestandsdiagram waar wordt aangegeven welke gebeurtenissen een toestandsverandering veroorzaken. In een SFC wordt aangegeven welke inputs de PLC van toestand doen veranderen. In het “toestandsblok” worden de acties geplaatst die uitgevoerd moeten worden. •
Structured Text
Structured text is een tekst gebaseerde programmeertaal die statements gebruikt om te bepalen wat precies moeten worden uitgevoerd. De syntax van deze programmeertaal gelijkt sterk op die van Pascal. Er kan worden gewerkt met loops, if-then-else structuren,…
Code generator voor PLC en SCADA
10
Figuur 6: Routine in Rockwell RSLogix 5000
3.2.2 Program tags Tags worden binnen de RSLogix 5000 omgeving gebruikt om referenties te leggen naar geheugenplaatsen. Vroeger waren dit fysieke adressen maar deze zijn vervangen door tags met een puur tekst gebaseerd adresschema.
In de RSLogix 5000 studio is het mogelijk om verschillende programma’s te creëren. Program tags zijn geïsoleerd van andere programma’s. Alle tags die aangemaakt worden in program tags hebben een scope die zich beperkt tot het programma waar ze instaan. Ze worden dus gezien als lokale tags. Omdat tags niet gedeeld kunnen worden tussen verschillende programma’s is het mogelijk om dezelfde tag te creëren in meer dan één programma. Dit betekent dat programma’s kunnen gekopieerd en gebruikt worden zonder zich zorgen te maken over tagconflicten tussen programma’s. Een tag bestaat uit een naam, beschrijving, type (wat de tag doet binnen het project), scope en een datatype. Code generator voor PLC en SCADA
11
Een datatype is een definitie van de grootte en lay-out van het geheugen dat gereserveerd wordt voor de gecreëerde tag. Dit datatype bepaalt ook welke waarden de expressie kan aannemen en welke bewerkingen erop uitgevoerd kunnen worden.
3.2.3 Add-on instructions Add-on instructions zijn instructies die de gebruiker zelf kan opstellen. Ze kunnen worden toegevoegd aan het project. Een add-on instructie laat toe om de meest gebruikte logic te bundelen als een set van instructies. Deze verzameling van instructies kunnen dan worden gebruikt binnen het project maar ook binnen andere projecten. Het voordeel hiervan is dat dit minder geheugen verbruikt dan wanneer je het volledig zou uitschrijven.
Een add-on instructie kan gecreëerd worden in standard ladder, function block diagram of structured text.
3.2.4 Controller tags De tags die we onder de controller tags aanmaken zijn ongeveer dezelfde die we onder de program tags terugvinden. Het enige verschil tussen program tags en controller tags is de scope. Zoals eerder vermeld zijn deze onder program tags enkel beschikbaar binnen het programma waarin ze staan. De tags die we onder controller tags terugvinden kunnen worden gebruikt in alle programma’s binnen de RSLogix 5000 studio.
3.3 Import/export Binnen de RSLogix 5000 omgeving is het mogelijk om volledige projecten te importeren en te exporteren. Dit kan gebeuren met drie verschillende soorten formaten: L5K,L5X en CSV.
3.3.1 L5K De L5K extensie is een eerste formaat en laat toe om een volledig RSLogix 5000 project te exporteren of importeren. De opbouw van dit L5K bestand gebeurt in ASCII-formaat. ASCII is de universele norm voor het omzetten van tekst, getallen en leestekens in binaire gegevens.
Code generator voor PLC en SCADA
12
Een klein project dat wordt geëxporteerd naar een L5K bestand kan al snel 25000 lijnen code bevatten. Dit is vrij logisch aangezien alles in het L5K bestand wordt geplaatst: headerinfo, footerinfo, controller tags, program tags, routines, add-on instructions,…
3.3.2 L5X Het L5X formaat laat ons ook toe om een volledig project te exporteren of te importeren maar ook om enkel bepaalde componenten erin te plaatsen zoals add-on instructions, ladderdiagram, routines,..
De opbouw van een L5X bestand gebeurt in XML. XML is een markup-taal die werkt met tags. De tags worden rond de data geplaatst en die geven meer informatie over de data. Door deze tags toe te voegen, creëer je data-containers. De representatie is zowel leesbaar door machines als door de mens.
Figuur 7: Deeltje L5X bestand
3.3.3 CSV Een laatste formaat waarin we kunnen exporteren en importeren is CSV. De vertaling naar het Nederlands van een CSV-bestand is een kommagescheiden bestand. Deze indeling, waarbij gegevens als platte tekst worden opgeslagen wordt vaak gebruikt in rekenbladen of databasesoftware. In een CSV-bestand wordt de data gescheiden door komma’s. Een nieuwe regel wordt aangeduid met het nieuwe-regelteken. De gegevens kunnen in een rekenblad of databaseprogramma worden ingelezen en in een tabel worden gepresenteerd.
Code generator voor PLC en SCADA
13
Enkel de tag definities en de programmadocumentatie kunnen worden geëxporteerd naar een CSV-bestand. Er kan ook worden gekozen voor een TXT bestandstype. Hierbij worden alle komma’s vervangen door tabs.
Code generator voor PLC en SCADA
14
3.4 Ladderdiagram code Er werd reeds meer uitleg gegeven over de ladderdiagram code die we terugvinden onder de routines in de RSLogix 5000. Een routine is een bestand die de blokken met ladderdiagram code bevat van verschillende devices. Omdat de toepassing ladderdiagram codefiles moet kunnen genereren bekijken we deze code van dichterbij.
In de routines kunnen we devices plaatsen die bestaan uit verschillende blokjes. Een device AI1 heeft bijvoorbeeld 6 blokjes: een algemeen blokje, threshblok en 4 alarmblokken. In de figuur hieronder zien we links het algemeen blokje van een AI1 device. In de geëxporteerde codebestanden zien we dat dit blokje overeenkomt met één codelijn. Een deel van zo’n bestand zien we aan de rechtzijde. De parameters die in het blokje staan vinden we ook terug in de codelijn na de devicenaam. Zo’n deviceblokje wordt ook wel een netwerk genoemd. Een device AI1 bestaat dus uit 6 codelijnen (voor ieder blokje een codelijn) en één commentaarlijn die het begin van een nieuw device aangeeft.
Een commentaarlijn wordt voorafgegaan door RC: , terwijl een nieuwe codelijn voor een blokje of netwerk begint met N:.
Figuur 8: Rockwell: Ladderdiagram blokje en Ladderdiagram codelijnen
Het codebestand die we hierboven rechts zien staan heeft ook een header en een footer die als container dient voor de devicelijnen. De header is een lijn die de naam van de routine bevat. Deze tekst wordt gebruikt als bestandsnaam voor de routine binnen RSLogix 5000. De footer bestaat uit “END_ROUTINE”, die aangeeft dat dit het einde van een welbepaalde routine is. Code generator voor PLC en SCADA
15
3.5 Globale variabelen code De globale variabelen zijn de program tags waarover meer werd verteld in puntje 3.2.2 Program tags. Om wat meer inzicht te krijgen in het codebestand van de globale variabelen bekijken we de opbouw van naderbij.
We zien net zoals bij de ladderdiagram code dat ieder device geprogrammeerd wordt met enkele codelijnen. De getallen die op iedere lijn te zien zijn stellen de waarden voor van de parameters. Sommige staan in exponentiële notatie.
Figuur 9: Rockwell: Variabelen datablok
Terug is er een header en footer die het begin en het einde aangeeft van de lijst met globale variabelen.
Code generator voor PLC en SCADA
16
4 Studie Beckhoff software 4.1 Inleiding Beckhoff is net zoals Rockwell een aanbieder van producten voor automatiseringssystemen. Binnen hun productassortiment vinden we onder meer: industriële PC’s, IO- en veldbuscomponenten en automatiseringssoftware.
De automatiseringssoftware die Beckhoff aanbiedt heet TwinCAT. Omdat de generator tool ook voor dit softwarepakket codefiles moet kunnen genereren werd er ook van dit pakket een uitgebreide studie uitgevoerd. De studie handelde over dezelfde zaken die ook voor het Rockwell pakket aan bod kwamen: de verschillende tags,importeren en exporteren van bestanden binnen TwinCAT,…
Het softwarepakket van Beckhoff die we hieronder bespreken heet TwinCAT PLC control. Bij het creëren van een nieuw project worden de volgende objecten toegevoegd: POU’s, datatypes en resources.
Code generator voor PLC en SCADA
17
4.2 Program organization units De Program Organization Units bestaan uit functions, function blocks en programs. Ieder POU bestaat uit een declaratiestuk en een body. De body is geschreven in een van de volgende programmeertalen: Structured Text (ST), Sequential Function Chart (SFC), Function Block Diagram (FBD) of Ladder Diagram (LD).
4.2.1 Functions Een functie is een POU dat precies één data element bevat. Zo’n data-element kan verschillende velden of structuren bevatten. Iedere functie moet een bepaald type hebben zoals integer of string. De functie wordt bovenaan in het declaratiestuk geplaatst en kan in de body worden aangeroepen. Bij veel functies moeten er inputvariabelen worden meegegeven, na de verwerking van de functie krijgen we een return waarde terug.
4.2.2 Function block Een functieblok is eveneens een POU maar kan verschillende elementen bevatten. Het heeft ook geen return waarde die een functie wel heeft. Hier wordt gewerkt met input- en outputvariabelen. Van deze functieblokken kunnen er instanties worden gecreëerd. Iedere instantie heeft zijn eigen instantienaam en datastructuur (deze bevat de input- en outputvariabelen en de interne variabelen). Een functieblok kan enkel worden aangesproken binnen de POU waarin het gedeclareerd is. Dit geldt niet indien de declaratie globaal gebeurt.
4.2.3 Program Programma’s zijn ook POU’s die verschillende waarden teruggeven wanneer deze worden uitgevoerd. Van programma’s kunnen geen instanties worden gemaakt, maar kunnen wel worden aangeroepen. Als er waarden worden veranderd binnen het programma dan wordt bij een volgende aanroep gewerkt met de aangepaste waarden. Voor een function block is dit niet het geval, daar worden de waarden enkel veranderd binnen de instantie die werd aangeroepen. Het is duidelijk dat programma’s binnen TwinCAT dezelfde functie hebben als de routines binnen RSLogix 5000.
Code generator voor PLC en SCADA
18
De codefiles die gegenereerd moeten worden zijn programma’s waar in het declaratiestuk niets moet worden geplaatst. De codefiles moeten bestaan uit ladderdiagrammen van devices die we in de body terugvinden. Een voorbeeld van een programma met ladderdiagram code van een device vindt u hieronder.
Figuur 10: Programma in Beckhoff TwinCAT PLC control
4.3 Datatypes In Twincat zijn er standaard datatypes aanwezig zoals integer,boolean,byte,string,data,…. De gebruiker kan ook zelf datatypes definiëren zoals bijvoorbeeld: enumeration types, arrays,…
Code generator voor PLC en SCADA
19
4.4 Resources Onder resources kunnen we alles configureren en organiseren voor ons project. De volgende items vinden we onder dit object:
•
Global Variables
De global variables map bevat verschillende soorten lijsten met globale variabelen. Globale variabelen zijn variabelen die gebruikt kunnen worden in het volledige project. We hebben globale variabelen en netwerk variabelen die als header beginnen met “VAR_GLOBAL”, er zijn ook configuratie variabelen die “VAR_CONFIG” als header hebben. Er kunnen ook remanent variabelen worden aangemaakt. Er zijn twee types van deze soort namelijk: persisent variabelen en retain variabelen. Deze worden niet aangepast wanneer het systeem wordt afgesloten of heropgestart. De header voor deze twee soorten wordt uitgebreid met “RETAIN” of “PERSISTENT”. De code generator moet lijsten kunnen genereren die globale variabelen bevatten. Een voorbeeld van een lijst met globale variabelen vindt u hieronder.
Figuur 11: Globale persistente variabelen in TwinCAT
•
Alarm Configuration
Hieronder kunnen alarmklassen en alarmgroepen worden geconfigureerd. Dit systeem laat toe om alarmen te ontwerpen die later kunnen worden gebruikt. Deze alarmen moeten worden uitgevoerd indien er zich gevaarlijke situaties voordoen. De alarmafhandeling kan binnen de TwinCAT PLC Control omgeving gebeuren, maar kan ook binnen de PLC zelf.
Code generator voor PLC en SCADA
20
•
Library Manager
De library manager toont alle bibliotheken die geïmporteerd zijn binnen het huidige project. De POU’s, datatypes en globale variabelen die in deze bibliotheken aanwezig zijn, kunnen op dezelfde wijze worden gebruikt als deze die door de gebruiker zelf werden aangemaakt.
•
Log
De log bewaart alle acties chronologisch die worden uitgevoerd wanneer een project gestart is. Het is mogelijk om de logfile weg te schrijven naar een bestand.
•
PLC configuration
De naam zegt het zelf. Onder PLC configuration kunnen alle instellingen gebeuren die betrekking hebben tot de PLC. TwinCAT ondersteunt vier verschillende hardwareplatformen. •
Sampling Trace
Sampling trace maakt het mogelijk om de progressie van variabelenwaarden te bekijken over een bepaald tijdsvenster. •
Task Configuration
Binnen de task configuration kunnen we taken aanmaken die series van programma’s bevatten. Deze taken hebben allemaal een prioriteit en condities. Ze worden aan de hand van deze criteria wel of niet uitgevoerd.
•
Watch- and Receipt Manager
Met behulp van de watch- and receipt manager is het mogelijk om de waarden te bekijken van geselecteerde variabelen. Deze functie kan ook waarden toekennen aan bepaalde variabelen en ze transfereren als een groep naar de PLC (“Write Receipt”). Op dezelfde manier kunnen PLC-waarden worden ingelezen in de watch- and receipt manager(“Read Receipt”). Deze functies zijn hulpvol voor het instellen van controleparameters. Deze functie is gelijkaardig aan het watch-venster binnen de .NET omgeving. •
Workspace
Onder workspace kunnen we verschillende opties instellen die betrekking hebben met de TwinCAT omgeving en projecten. Code generator voor PLC en SCADA
21
4.5 Import/ export Het exporteren of importeren van codefiles binnen Beckhoff TwinCAT is ook mogelijk net zoals bij Rockwell RSLogix 5000. Bij het kiezen om een project te exporteren kunnen we een volledig project exporteren naar een bestand of enkel bepaalde POU’s, resources of libraries. Bij Beckhoff TwinCAT krijgen we niet de keuze om te kiezen in welk formaat we exporteren of importeren. Het importeren of exporteren van projecten of delen van een project moet gebeuren met bestanden die een EXP extensie hebben.
4.5.1 EXP files De objecten die in de EXP bestanden staan zijn geschreven in ASCII-formaat. ASCII is de standaard om tekst en getallen om te zetten in binaire gegevens.
4.6 Ladderdiagram code Nu we de voornaamste componenten van de Beckhoff TwinCAT studio besproken hebben bekijken we de opbouw van een ladderdiagram codefile van dichterbij. De ladderdiagram codefiles vinden we onder de programs in de TwinCAT omgeving. Inzicht krijgen in de opbouw en syntax van deze codefiles is zeer belangrijk om de templates te ontwikkelen en om de applicatie correct te programmeren. De ladderdiagram codefiles van Beckhoff TwinCAT zijn qua opbouw een stuk anders dan die van Rockwell RSLogix 5000. We kunnen ze opdelen in drie blokken: header, device-informatie en een footer.
Code generator voor PLC en SCADA
22
De header bestaat uit de volgende belangrijke parameters: • • • •
@PATH : geeft aan onder welke map het bestand komt indien het wordt geïmporteerd. @SYMFILEFLAGS: deze waarde omvat de grootte die het bestand inneemt in het geheugen. PROGRAM ANALOGE_INGANGEN.EXP: dit wil zeggen dat de bestandsnaam “ANALOGE_INANGEN” zal zijn binnen Beckhoff TwinCAT. _NETWORKS : na deze parameter komt altijd een getal die aangeeft hoeveel netwerken het bestand bevat.
Een netwerk in de ladderdiagram code kunnen we zien als een blokje. Bijvoorbeeld een analoog device AI1 heeft 6 blokjes: een attributenblokje, een threshblok en 4 alarmblokken. Een digitaal device DI1 bestaat uit één blokje. Het is duidelijk dat ieder device een verschillend aantal blokjes kan bevatten.
De applicatie moet dus een functie bevatten die op voorhand bepaald welke devices er precies in de gegenereerde codefile komen te staan. Dit is belangrijk omdat we voor alle devices het aantal netwerken moeten kennen. Deze waarde kan dan worden ingevuld in de header. Indien we een verkeerd aantal netwerken ingeven bovenaan de header zal de gegenereerde codefile simpelweg niet geïmporteerd kunnen worden in Beckhoff TwinCAT.
Figuur 12: Header ladderdiagram bestand
Code generator voor PLC en SCADA
23
Het tweede grote stuk binnen een ladderdiagram codefile is de informatie over het device. Dit stuk bevat de verschillende devices met hun data en parameters. In de figuur hieronder aan de linkerzijde zien we terug een blokje of netwerk van een AI1 device. In vergelijking met de codefile van Rockwell wordt één blokje niet met één codelijn geprogrammeerd. Bij Beckhoff TwinCAT wordt een ladderdiagram blokje in de code opgebouwd door alle parameters onder elkaar te plaatsen. We zien de concrete opbouw aan de rechterkant. Iedere parameter die we aan de linkerkant vinden wordt in de codefile geschreven door een drie- of viertal lijnen.
Figuur 13: Beckhoff: Ladderdiagram blokje en ladderdiagram codelijnen
Het is de bedoeling om in de code generator deze code samen te stellen. De opbouw zou dus moeten gebeuren door de correcte template te kiezen, afhankelijk van het device die we terugvinden in de Excellijst. Daarna moet er data worden uitgelezen uit het Excelbestand en die moet op de correcte plaats komen binnen de template. Na het samenvoegen van de templates en de data moeten de verschillende devices geordend worden.
Het laatste blok van een ladderdiagram codefile is de footer. De footer bij Beckhoff TwinCAT bevat maar één lijntje namelijk: “END_PROGRAM”.
Code generator voor PLC en SCADA
24
4.7 Globale variabelen code De globale variabelen codefile kunnen we onderverdelen in twee grote delen: een tagcontainer en een datablok. De tagcontainer werd uitvoerig beschreven onder het punt “globale variabelen” bij het hoofdstuk 4.4 Resources.
Het datablok bestaat uit tekstlijnen die de devicenaam, soort netwerk en commentaar bevatten. Hieronder ziet u dat een device AI1 wordt weggeschreven in de globale variabelen codefile met 6 tekstlijnen. Voor ieder netwerk (= blokje) komt één programmeerlijn in de codefile.
Figuur 14: Twincat: Globale variabelen datablok
Code generator voor PLC en SCADA
25
5 Uitwerking: onderzoek 5.1 Inleiding Nu de probleemstelling voldoende beschreven is in de vorige hoofdstukken komen we bij de uitwerking van deze thesis. Het onderzoek is een van de belangrijkste stappen bij het ontwikkelen van een applicatie. Samen met de externe promotor werd er bekeken hoe dit project het beste zou worden uitgewerkt. Het was vrij snel duidelijk dat er twee opties waren. Langs de ene kant kon er een volledig nieuwe template generator worden uitgewerkt. De tweede optie was het afspeuren van de markt of er generator tools aanwezig waren. Hieronder worden beide opties uitvoerig besproken met voor- en nadelen.
5.2 Eigen template generator Het zelf ontwerpen van een template generator in .NET had als grootste voordeel dat er geen enkele beperking was hoe de generator eruit zou zien. Met andere woorden de ontwikkelaar kon gebruik maken van de verschillende bibliotheken binnen de .NET omgeving.
Een voorbeeld van zo’n bibliotheek was ADO.NET. Deze wordt gebruikt voor het uitlezen van een Excelbestand. Het is de opvolger van Microsoft ADO. Deze component maak het mogelijk om applicaties te verbinden met verschillende soorten databanken. De bibliotheek zit standaard in het .NET raamwerk en voorziet communicatie naar vier verschillende connectors: Microsoft SQL server, OLE DB, ODBC en Oracle. Om een verbinding op te zetten met een Excelbestand wordt gebruik gemaakt van een OLE DB connectie.
Een van de grootste nadelen is dat er in de syntax van de templates een soort van symbool of speciaal karakter zou bepaald moeten worden. Dit symbool of karakter zou de generator duidelijk moeten maken dat er op deze plaats data moeten worden opgehaald en ingevuld. Het komt erop neer dat iedere template die we wensen te gebruiken zou moeten worden uitgelezen. Lijn per lijn zou moeten worden gelezen om te kijken of het afgesproken karakter of symbool aanwezig is in de gelezen lijn. Iedere lijn van de template zou moeten worden gelezen en met behulp van het vooraf afgesproken symbool of karakter zou de programmacode weten of er iets moet gebeuren of niet. Als het een lijn was zonder karakter of symbool dan zou deze lijn moeten worden weggeschreven. Begint de lijn met het karakter dan moet het Exceldocument worden aangesproken en moet de data worden geplaatst op deze lijn. Code generator voor PLC en SCADA
26
5.3 Codesmith Tools 5.3.1 inleiding Er werd gezocht of er al tools bestonden die werken met templates en die codefiles kunnen genereren. Na heel wat opzoekingwerk kwamen we bij Codesmith Tools. Codesmith Tools is een code generator die werkt met templates en die codefiles kan afleveren in verschillende programmeertalen (C#, Java, VB, PHP, ASP.NET, SQL, etc.). De syntax van Codesmith is bijna gelijkaardig aan die van ASP.NET. De C#, VB.NET of JScript.NET code kan gebruikt worden in de templates om methoden en properties op te roepen.
Het grote voordeel van deze tool is dat het generatorproces al reeds geprogrammeerd is en uitvoerig getest is door andere gebruikers. De Codesmith Tools omgeving wordt constant aangepast en verbeterd om sneller code files te kunnen genereren. Bovendien is er een grote community die templates beschikbaar stelt en waar je de nodige informatie kunt verkrijgen over deze toepassing.
Een nadeel is natuurlijk dat je gebonden bent aan de vaste GUI die Codesmith Tools aanbiedt en dat je geen toegang hebt tot sommige add-ons van het .NET raamwerk.
Code generator voor PLC en SCADA
27
5.3.2 Properties De Codesmith studio voorziet het gebruik van properties zodat de code generator kan worden aangepast aan de noden van de gebruiker. Een property kan ieder .NET object zijn die al aanwezig is in de .NET omgeving. Dit kan bijvoorbeeld een simpele boolean zijn maar ook een dropdownbox, file dialog box of een zelf gecreëerde property.
Figuur 15: Codesmith: Tools properties
5.3.3 Templates Templates binnen de Codesmith studio kunnen eenvoudig worden aangemaakt. Binnen de templates kan de opbouw zelf bepaald worden die later gegenereerd kan worden tot codefiles.
Zoals hierboven vermeld, gebeurt de opbouw van een template in ASP.NET. Een template kun je in grote lijnen onderverdelen in drie stukken. Een eerste stuk vinden we bovenaan. Hier staat de keuze welke programmeertaal we gebruiken voor de code-behind. Ook properties kunnen hier worden gedeclareerd die dan kunnen worden ingevuld door de gebruiker. Eveneens bovenaan te vinden zijn de imports voor assemblies en namespaces.
Een tweede stuk is de templatetekst zelf. Alles die we hier plaatsen wordt letterlijk weggeschreven als we de template renderen. Code generator voor PLC en SCADA
28
We kunnen hier ook zaken plaatsen die data ophalen of methodes oproepen uit de codebehind. Dit gebeurt met de <% %> tags. Tussen deze tags kan dan de methodenaam of de property getter worden aangeroepen.
Een derde en laatste stuk is de code-behind die we onderaan de template vinden. Hier plaatsen we de methodes en properties die nodig zijn voor de opbouw van de template. Een template kan hier ook worden aangesproken en dit gebeurt op dezelfde manier zoals het aanmaken van een object van een klasse.
5.3.4 Code-behind Bij het toevoegen van een nieuwe template kan er een keuze worden gemaakt tussen een C# ,VB,JScript of Blank template. Deze keuze is van belang in welke programmeertaal de code-behind zal worden geschreven.
Het schrijven van de code-behind is quasi hetzelfde zoals in de .NET omgeving. Er kan worden gewerkt met getters en setters, methodes, variabelen,… . De debugger zoals we die kennen binnen .NET kan ook worden gebruikt en is van primordiaal belang bij het controleren van de code. Indien bepaalde assemblies nodig zijn voor speciale datatypes dan kunnen we die snel toevoegen bovenaan de template.
Code generator voor PLC en SCADA
29
6 Uitwerking: applicatie 6.1 Opbouw 6.1.1 Schematische voorstelling
Code generator voor PLC en SCADA
30
6.1.2 Componenten In de schematische voorstelling hierboven ziet u de verschillende componenten van de applicatie. We kunnen deze tekening onderverdelen in vier grote blokken: de devicelijst, het Codesmith project, de gegenereerde codebestanden en de PLC-softwarepakketten.
De devicelijst bevat alle instrumenten die we terugvinden op de process en instrumentation diagram waarvoor we automatisch code willen laten genereren. Het is belangrijk dat in dit bestand alle data aanwezig is voor de correcte opbouw van de codefiles. Dit wil zeggen dat alle informatie in de correcte vorm moet staan en in de juiste kolom.
Een tweede blok binnen de schematische voorstelling van de applicatie is het Codesmith project. Dit project bevat alle templates van alle devices. Voor iedere component zijn er vier verschillende soorten templates aanwezig: een ladderdiagram template voor Rockwell en Beckhoff en een globale variabelen template terug voor Rockwell en Beckhoff. Het project bevat ook nog andere templates die zorgen voor het uitlezen van de devicelijst, het registeren van de sjablonen, de verwerking en het ordenen van de templates. De gebruiker kan in de Codesmith toepassing ook verschillende voorkeuren ingeven die rechtstreeks betrekking hebben hoe de codefiles worden gegenereerd.
De derde component zijn de bestanden die gegenereerd werden door de Codesmith applicatie. De bestanden zijn ofwel ladderdiagram of globale variabelen en dragen de correcte extensie van het PLC-programma waarvoor ze ontwikkeld werden.
De laatste stap binnen de datastroom zijn de PLC-softwarepakketten die de codefiles nu moeten importeren. Het importeren van routines en tags in Beckhoff TwinCAT en Rockwell RSLogix 5000 werd uitvoerig besproken in de vorige hoofdstukken.
Code generator voor PLC en SCADA
31
6.2 Devicelijst 6.2.1 Opbouw De devicelijst is een Exceldocument waarin alle instrumenten staan opgelijst die op de process en instrumentation tekening (P&ID) te vinden zijn. Per device vinden we één lijn in het bestand. Het Excelbestand bevat alle data die we in de gegenereerde bestanden moeten plaatsen. Het is de bedoeling om voor iedere lijn de juiste template aan te spreken, de nodige data in te vullen en de bij elkaar horende devices te ordenen en weg te schrijven naar een bestand. Het gegenereerde bestand kan later worden geïmporteerd in Beckhoff of Rockwell.
De lijst bestaat uit verschillende kolommen: •
TYPE: geeft aan welk type device er in de rij te vinden is. De waarde in deze cel is van groot belang bij het correct aanroepen van de juiste template.
•
TAGNAAM: de tagnaam is de specifieke naam die het device krijgt op de projecttekening.
•
COMMENT: de kolomnaam “COMMENT” bestaat uit de commentaarlijnen van de devices. Deze worden gebruikt bij het opstellen van de bestanden en worden vaak afgebeeld in de SCADA-applicaties.
•
FILECODE: deze parameter bevat een bestandsnaam waarin de gegenereerde code moet geplaatst worden van de ladderdiagram codefiles. Het is duidelijk dat verschillende codeblokken in hetzelfde bestand zullen geplaatst worden. Om dit te kunnen verwezenlijken zullen alle codeblokken van de devices geordend moeten worden aan de hand van deze parameter.
•
FILEROUTINE: fileroutine geeft aan in welke routine het ladderdiagram codeblok moet worden geplaatst. Het kan zijn dat twee codeblokken in hetzelfde bestand komen (=zelfde filecode) maar dat ze in een andere routine geplaatst worden. Er zal terug een ordeningsproces moeten worden doorlopen.
•
FILEVARIABELEN: de kolomnaam “FILEVARIABELEN” bevat alle documentnamen voor de gegenereerde codebestanden wanneer er globale variabelen codefiles worden opgebouwd.
Code generator voor PLC en SCADA
32
6.3 Templates 6.3.1 Inleiding Om de codefiles te kunnen genereren was het de bedoeling om voor ieder device (AI1,DI1,DI2,…) vier verschillende sjablonen aan te maken. Voor Beckhoff TwinCAT een ladderdiagram en globale variabelen template en voor Rockwell RSLogix 5000 terug een ladderdiagram en globale variabelen template. In dit hoofdstuk bekijken we de opbouw van de verschillende sjablonen. De mappenstructuur van de verschillende templates komt later aan bod.
6.3.2 Beckhoff templates In een van de vorige hoofdstukken werd er een studie uitgevoerd hoe de syntax van de Beckhoff software in elkaar stak. Met deze kennis werden de templates ontwikkeld waarvan we nu de opbouw bekijken. Eerst komen de ladderdiagram sjablonen aan bod, daarna bekijken we deze voor de globale variabelen. 6.3.2.1 Ladderdiagram De ladderdiagram code in de Beckhoff TwinCAT omgeving bestaat uit de verschillende netwerken (=blokjes). Deze worden onder elkaar geplaatst.
Figuur 16: Beckhoff: Ladderdiagram template
Code generator voor PLC en SCADA
33
In de vorige figuur ziet u een gedeelte van een ladderdiagram sjabloon voor een AI11 device. Zoals u kunt zien moet er op de plaatsen waar er <% %> staan, data worden ingevuld die afkomstig is uit het Excelbestand. Om deze data op te halen wordt er gebruik gemaakt van een zoekmethode.
Een overeenkomende template wordt geladen aan de hand van de devicenaam die in een bepaalde lijn in het Exceldocument vermeld staat. Daarna wordt er een instantie van de template gemaakt en geven we de volledige datarij uit het Excelbestand mee naar het correcte devicesjabloon. De zoekfunctie doorzoekt deze datarow die uit de devicelijst komt aan de hand van de kolomnaam. Zoals in de vorige figuur te zien is, geeft de zoekfunctie de celwaarde terug die we in de datarow vinden met de kolomnaam “COMMENT”. Daarna wordt tweemaal de correcte waarde gezocht en ingevuld voor de kolomnaam “TAGNAAM”.
//ZOEK EEN WAARDE ADHV KOLOMNAAM IN DE ROW UIT EXCELFILE(string name) public string Zoek(string name) { return Row[name].ToString(); } In het template gedeelte vinden we bovenaan een header en onderaan een footer. Deze kunnen al dan niet worden toegevoegd aan de gegenereerde codefile. Meer uitleg over de header en footer wordt aangehaald in het volgende puntje. De header en footer vinden we terug in alle templates.
In de code-behind van iedere template vinden we nog enkele variabelen en properties. Zo vinden we in ieder devicesjabloon een integer die het aantal netwerken aangeeft. Deze waarde is nodig om het aantal netwerken van alle devices te bereken die in een codefile aanwezig zullen zijn. Deze som wordt bovenaan in de header geplaatst. Andere properties zijn de getters en setters voor het doorgeven van een datarow maar ook voor het wel of niet toevoegen van een header en footer.
Code generator voor PLC en SCADA
34
6.3.2.2 Globale variabelen De templates voor de globale variabelen bestaan terug uit vaste tekst die gekopieerd wordt naar de uiteindelijke codefiles. Tussen de <% %> dient er eveneens data te worden opgehaald uit de datarow.
Figuur 17: Beckhoff: Globale variabelen template
Bovenaan ieder sjabloon vinden we een header die al dan niet kan worden geplaatst in de uiteindelijke codefiles. Op de figuur is te zien dat er gewerkt wordt met een if-then structuur om de header toe te voegen. Hetzelfde wordt bij de footer geplaatst.
In de code-behind vinden we opnieuw de zoekfunctie en de verschillende getters en setters van de properties.
Code generator voor PLC en SCADA
35
6.3.3 Rockwell templates Er werd reeds bestudeerd dat de syntax van de Rockwell-omgeving een stuk verschilt dan die van Beckhoff. Daarom konden we voor het gegeneren van de codefiles geen gebruik maken van een en dezelfde sjablonen voor de devices. Voor de Rockwell software werden opnieuw twee templates ontwikkeld die hieronder uitgebreid aan bod komen.
6.3.3.1 Ladderdiagram code De opbouw van de ladderdiagram sjablonen is wat anders dan deze voor Beckhoff. Er is opnieuw een zoekfunctie die de juiste datawaarden uit de datarow haalt. Er wordt terug gewerkt met een header en footer die we kunnen toevoegen aan de uiteindelijke codebestanden. Een property die het aantal netwerken aangeeft is hier niet aanwezig omdat Rockwell niet verwacht dat we het aantal netwerken meegeven in de header-informatie.
6.3.3.2 Globale variabelen Het enige verschil tussen de templates van Beckhoff en Rockwelll zijn het aantal lijnen die we gebruiken om de globale variabelen voor te stellen. Ook de concrete opbouw van iedere lijn verschilt.
Code generator voor PLC en SCADA
36
6.4 Main template 6.4.1 Inleiding De main template is de belangrijkste klasse van de applicatie. Deze klasse kunnen we zien als de schakel tussen de devicelijst en de te ontwikkelen codefiles. Langs de ene kant zorgt de main template voor het uitlezen van het Excelbestand. Langs de andere kant spreekt deze klasse de correcte templates aan en worden ze opgebouwd. Deze functies worden nu uitvoerig besproken.
6.4.2 Templates: registraties en instanties aanmaken 6.4.2.1 Inleiding De main template bevat een functie “Templates registreren” die als eerste wordt uitgevoerd wanneer de applicatie wordt opgestart. Het registreren van templates dient eerst wat meer verduidelijkt te worden. Het is de bedoeling om in de main template alle devicetemplates te kunnen aanspreken. We kunnen de devicetemplates zien als subtemplates. Om nu binnen het hoofdsjabloon (main template) te werken met de subtemplates moeten deze eerst worden geregistreerd. Deze registratie gebeurt bovenaan en ziet er als volgt uit:
Figuur 18: Codesmith: Sub-template registratielijnen
Een registratielijn binnen de Codesmith omgeving bestaat uit een viertal parameters. De belangrijkste zijn:
•
Name
Het attribuut “Name” specificeert de naam van de subtemplate die kan worden aangesproken in het hoofdsjabloon. De waarde die we hier plaatsen kan gebruikt worden om een instantie te creëren van de subtemplate.
Code generator voor PLC en SCADA
37
•
Template
“Template” geeft aan wat het relatieve pad is van de subtemplate. Een relatief pad beschrijft de locatie van de subtemplate ten opzichte van de hoofdtemplate.
•
MergeProperties
Dit attribuut laat ons toe om properties die aangemaakt werden in de subtemplate te gebruiken in de hoofdtemplate. Een property binnen de Codesmith studio geeft aan de gebruiker de mogelijkheid om instellingen in te geven en voorkeuren te bepalen.
•
ExcludeProperties
Het “ExcludeProperties” attribuut kan een lijst met properties bevatten waarvan we wensen dat deze niet kunnen worden gebruikt in de hoofdtemplate. Verschillende properties kunnen hier worden geplaatst die gescheiden worden met een komma.
Zoals hierboven vermeld moet iedere template die we wensen te gebruiken vooraf geregistreerd worden in het hoofdsjabloon. Indien we op voorhand weten dat er in de toekomst geen nieuwe devices bij zouden komen dan zou dit geen probleem met zich meebrengen. Een van de doelstellingen van deze thesis is dat de tool zo generiek mogelijk moet worden opgesteld, dus bestaat de mogelijkheid dat er in de toekomst nieuwe templates kunnen bijkomen.
Omdat het niet de bedoeling is om de programmeercode telkens aan te passen indien er een nieuw sjabloon wordt toegevoegd werd er een functie ontwikkeld die de templates automatisch registreert.
6.4.2.2 Externe bestanden Alvorens de registratiemethode uitvoerig te bespreken bekijken we even een functie binnen de Codesmith studio die het mogelijk maakt om externe bestanden toe te voegen aan de bestaande templates. Deze externe bestanden kunnen zowel programmeercode, templateregistraties of verwijzingen naar namespaces bevatten. Het toevoegen van een extern bestand doen we aan de hand van volgende regel code:
Code generator voor PLC en SCADA
38
Het is duidelijk dat we deze functie kunnen gebruiken om één bestand te importeren waarin alle registratielijnen staan van de templates.
6.4.2.3 Mappenstructuur Om het registreren van de templates automatisch te laten gebeuren werd er terug gewerkt met de functionaliteiten van Codesmith Tools. De registratiefunctie zorgt ervoor dat binnen de map “templates” de onderliggende mappen worden bekeken en uitgelezen. Het uitlezen van de mappen en bestanden gebeurt op de volgende manier:
1. Mappen van producenten uitlezen onder de hoofdmap “templates”. 2. De onderliggende mappen binnen de producentmap bekijken. De mappen die we hier vinden geven het soort code aan (momenteel enkel ladderdiagram en globale variabelen) 3. Binnen iedere “soort code map” de templates uitlezen.
Figuur 19: Mappenstructuur templates
Indien er nu in de toekomst devices bijkomen dan kunnen deze snel worden toegevoegd door ze in de correcte map te plaatsen. De registratiefunctie zal de template van het nieuwe device in de ladderdiagram of globale variabelen map terugvinden en de registratielijn opbouwen en toevoegen aan het externe bestand.
Code generator voor PLC en SCADA
39
6.4.2.4 Registratiefunctie Het uitlezen van de verschillende producent- en codemappen gebeurt door gebruik te maken van de System.IO namespace die standaard in de .NET omgeving aanwezig is. Deze bibliotheek maakt het mogelijk om te lezen en te schrijven naar bestanden en mappen. Het heeft ook functies om directories uit te lezen en te bewerken.
Om de verschillende producentmappen op te halen worden er enkele for-each lussen genest die achtereenvolgens de productmappen, de codemappen en de templates uitlezen. Voor het uitlezen van de mappen wordt de methode System.IO.Directory.GetDirectories(“path”) gebruikt. Om het uitlezen van bestanden tot stand te brengen wordt de functie System.IO.Directory.GetFiles(“path”) gebruikt.
//alle producentmappen overlopen foreach(string SoortProgrammaMappen in System.IO.Directory.GetDirectories(TemplateFolder)) { //alle soortcodemappen overlopen foreach(string SoortCodeMappen in System.IO.Directory.GetDirectories(SoortProgrammaMappen)) { //alle template bestanden uitlezen foreach (string Templates in System.IO.Directory.GetFiles(SoortCodeMappen)) { //toevoegen van de mapnamen en bestandsnamen TemplateFileNames.Add(System.IO.Path.GetFileNameWithoutExtension(Templates)); TemplateSoortProgrammaMap.Add(System.IO.Path.GetFileName(SoortProgrammaMappen)); TemplateSoortCodeMap.Add(System.IO.Path.GetFileName(SoortCodeMappen)); } }
} Vervolgens worden de verschillende mapnamen en de templatenamen in arraylists gestopt. De waarden binnen de arraylists worden later gebruikt om de registratielijnen op te bouwen.
Code generator voor PLC en SCADA
40
6.4.2.5 Registratietemplate Nu we precies weten welke devicetemplates er aanwezig zijn kunnen de registratielijnen worden opgebouwd. De template die hiervoor zorgt wordt nu toegelicht. Het gegenereerde bestand met de registratielijnen zal later worden geïmporteerd door gebruik te maken van de include methode die reeds werd verduidelijkt.
Om het overzicht te behouden in de main template werd beslist om de importlijnen van de assemblies en de namespaces ook toe te voegen aan het registratiebestand. De opbouw van deze lijnen zien we hieronder in de figuur. Deze programmeercode komt rechtstreeks uit de registratietemplate en overloopt een aangeleverde arraylist en voegt voor ieder item een nieuwe importlijn voor een assembly of namespace toe.
Figuur 20: Toevoegen van assemblies en namespaces
In de inleiding werd reeds uitgelegd dat de registratielijnen opgebouwd worden met een viertal parameters: templatenaam, templatepad en twee parameters die ons toelaten om properties al dan niet te gebruiken in de hoofdtemplate. De functie die deze lijnen opstelt is hieronder te vinden. In de registratiefunctie werden enkele ArrayLists opgevuld met de mapnamen en templatenamen. De ArrayList met de templatenamen wordt nu één voor één uitgelezen en voor iedere waarde wordt een registratielijn samengesteld.
Figuur 21: Toevoegen van een registratielijn
Code generator voor PLC en SCADA
41
6.4.2.6 Instanties aanmaken Indien we in de Codesmith studio een subtemplate willen aanspreken moet er eerst een instantie van de template worden gecreëerd. Daarna kunnen de properties en methodes van de template worden aangeroepen. Het aanmaken van een instantie gebeurt ongeveer op dezelfde manier als het aanmaken van een objectinstantie van een klasse. Hieronder staat een voorbeeld waar we een object aanmaken van een templateklasse Body. De templatenaam die bovenaan ingevuld werd in de registratielijn dient hier te worden gebruikt voor het opstellen van een instantie.
Body Body = this.Create(); Het probleem dat zich stelt bij deze manier van objectinstanties aanmaken is dat we tussen de < > geen stringwaarde kunnen ingeven. Dit wil zeggen dat het niet mogelijk is om de devicenaam die we uit het Excelbestand halen te gebruiken om een instantie op te stellen. Een mogelijkheid bestond erin om een uitgebreide switch-case structuur te programmeren die voor alle devicetemplates een keuze bevat. Een voorbeeld van zo’n switch-case structuur staat hieronder afgebeeld.
switch (Excel_device_naam) { case “AI1”: AI1 ai1 = this.Create
(); break; case “AI2”: AI2 ai2 = this.Create(); goto case 1; case “DI1”: DI1 di1 = this.Create(); goto case 1; default: Main main = this.Create<Main>(); break; } Zoals eerder uitgelegd is een van de voornaamste doelstellingen van deze thesis het zo generiek opzetten van de generator. De bovenstaande structuur voldoet hier totaal niet aan. Indien er een nieuw device wordt toegevoegd moet de code van deze keuzestructuur worden aangepast wat zeker de bedoeling niet is.
Code generator voor PLC en SCADA
42
Om een oplossing te bieden aan dit probleem wordt er gewerkt met een dictionary. Een dictionary in C# is een collectie van data waarin we sleutels en waarden kunnen stockeren. Iedere sleutel komt overeen met een bepaalde waarde binnen het woordenboek. Indien we een bepaalde waarde uit het woordenboek wensen te halen dan geven we simpelweg de sleutel op en we krijgen automatisch de bijhorende waarde terug uit de dictionary.
Het opstellen van deze dictionary gebeurt terug wanneer de applicatie wordt opgestart. We maken gebruik van een template die een C#-bronbestand zal genereren. In dit bestand staat een functie die deze dictionary zal opvullen en een getter en setter bevat zodat we een waarde uit de dictionary kunnen ophalen aan de hand van de sleutel. Om het woordenboek te kunnen gebruiken wordt het bronbestand door middel van de include functie ingevoerd in de main template.
Het genereren van het bestand met extensie .cs gebeurt net na het opstellen van de registratielijnen die uitvoerig werd besproken in vorige hoofdstukken. Hieronder ziet u hoe de template wordt opgeroepen. Hierna wordt de arraylist met alle templatenamen doorgegeven aan de template. Als laatste stap wordt het gegenereerd bestand opgemaakt en opgeslagen in de juiste map.
Templates_Resources Templates_Resources =this.Create(); Templates_Resources.SetProperty("CodeTemplates",TemplateFileNames); Templates_Resources.RenderToFile(TemplateFolder+@"\templates.cs",true);
Code generator voor PLC en SCADA
43
De template die het C#-bronbestand zal genereren bestaat uit twee delen. Een functie met een getter en een setter zodat we waarden kunnen bijvoegen en opvragen aan de dictionary. Deze functie wordt in de template geplaatst als vaste tekst. Dit betekent dat er hier geen samenvoeging van data moet gebeuren of het overlopen van arraylists.
public Dictionary<string,CodeSmith.Engine.CodeTemplate> codeTemplates = new Dictionary<string,CodeSmith.Engine.CodeTemplate>(); [Browsable(false), XmlIgnore] public Dictionary<string,CodeSmith.Engine.CodeTemplate> CodeTemplates { get { return codeTemplates; } set { codeTemplates = value;} } Het tweede deel van de template zal de codelijnen opstellen. Deze lijnen bestaan uit de instanties van de templates samen met een sleutelwaarde. Zoals in de code te zien is wordt een sleutel en waarde toegevoegd aan de dictionary met de add methode. Als sleutel nemen we de naam van de template. Wanneer de applicatie nu wordt opgestart wordt het C#bronbestand gegenereerd en geïmporteerd in de main template. De instanties van alle templates kunnen nu worden aangesproken in het hoofdsjabloon.
Figuur 22: Dictionary sleutel en waarde toevoegen
Het oproepen van een bepaalde template gebeurt nu door middel van de sleutel. Indien een template instantie moet worden opgeroepen dan gebruiken we de sleutelwaarde om deze instantie op te zoeken. Wanneer de instantie correct is opgezocht kunnen alle properties en methoden worden aangesproken.
CodeTemplates[templatenaam+".cst"].SetProperty("Bestandsnaam",BestandsNaam); CodeTemplates[templatenaam+".cst"].Render(this.Response);
Code generator voor PLC en SCADA
44
6.4.3 Excel uitlezen 6.4.3.1 Inleiding De volgende methode die wordt uitgevoerd in de main template is het uitlezen van het Excelbestand. Omdat er data moeten worden uitgewisseld tussen het bestand en de applicatie dient er een connectie te worden opgezet.
6.4.3.2 OLE DB connectie Om de verbinding op te zetten tussen het Excelbestand en de applicatie wordt de JET OLE DB provider gebruikt die we in de ADO.NET bibliotheek terugvinden. Om toegang te krijgen tot het werkblad van het Excelbestand maken we gebruik van een connection string. Een connection string specificeert het volledige pad naar het bestand. In deze programmeerlijn kunnen er ook verschillende properties worden meegegeven zoals bijvoorbeeld: datatype van het bestand, header-kolommen niet/wel aanwezig,…
string ConnectionString =String.Format("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=\"{0}\"; Extended Properties=\"Excel 8.0;HDR=No;IMEX=1;\"",Excelfile); Nadat de connection string correct is opgebouwd wordt er een connectie opgezet tussen de applicatie en het Excelbestand. Om de cellen te selecteren wordt er gewerkt met een OLEDbCommand die SQL verwacht als input. De gebruiker kan in het beginscherm van de applicatie invullen uit welk werkblad er gegevens moeten worden gehaald. Aan de hand van de naam van het werkblad wordt het SQL-commando vervolledigd . Alvorens het OLEDbCommand wordt geïnitialiseerd werd een Adapter-object aangemaakt die het SQLcommando zal uitvoeren.
OleDbConnection Connection = new OleDbConnection(ConnectionString); OleDbDataAdapter Adapter = new OleDbDataAdapter(); OleDbCommand Command = new OleDbCommand("SELECT * FROM ["+NaamWerkblad+"$]", Connection); DataSet DS = new DataSet("Table"); Adapter.SelectCommand = Command; Adapter.Fill(DS);
Code generator voor PLC en SCADA
45
De rijen en kolommen die met het SQL-commando geselecteerd werden worden vervolgens door het OLEDbDataAdapter-object geplaatst in een dataset. Een dataset is een collectie van data die vergeleken kan worden met een tabel. De representatie van de rijen en de kolommen gebeurt in het geheugen. Een dataset bestaat uit rijen en kolommen, net zoals we in het Excelbestand terugvinden.
Om gebruik te kunnen maken van de informatie die in de dataset aanwezig is dient er een bepaalde tabel te worden gekozen. Omdat er maar één tabel aanwezig is in de dataset kiezen we voor index 0 van de tabellen. Zoals u kunt zien wordt er een datatable-object aangemaakt waarin we de data uit de eerste tabel van de dataset instoppen. Een dataset kan bestaan uit verschillende datatables.
Het volgende wat gebeurt in de functie die de verbinding met het Exceldocument verzorgt is het uitlezen van de kolomnamen. De kolomnamen zijn van primordiaal belang bij het opzoeken van data uit het bestand. In het hoofdstuk van de templates werd er gebruik gemaakt van een zoekfunctie om aan de hand van een kolomnaam de correcte celwaarde op te zoeken. Omdat deze functie op de juiste plaats waarden zou ophalen worden alle kolomnamen uitgelezen en aan de datatable toegevoegd.
ExcelData = DS.Tables[0]; int aantalkolommen = ExcelData.Columns.Count; for (int i = 0; i
Code generator voor PLC en SCADA
46
6.4.4 Devicetemplates opbouwen 6.4.4.1 Inleiding Na al het voorbereidend werk zoals het registreren van de templates en de verbinding opzetten met het Excelbestand wordt de methode voor het opbouwen van de devicetemplates besproken. Eerst bekijken we de procedure voor het genereren van ladderdiagram codefiles, daarna komen de codefiles voor de globale variabelen aan bod.
Wanneer de applicatie wordt opgestart krijgt de gebruiker de keuze welk soort codefiles hij wil genereren. Dit kunnen ladderdiagrammen of globale variabelen zijn. In de methode voor het opbouwen van de codebestanden wordt deze keuze eerst ingelezen. Dit is nodig omdat de procedure van beide wat van elkaar verschilt.
6.4.4.2 Devicelijnen ordenen Zoals in de uiteenzetting van de devicelijst te lezen was wordt er gewerkt met bestandsnamen die gegeven worden aan de ladderdiagram en globale variabelen codefiles. Het eerste wat moet gebeuren na het correct verkrijgen van de data is het ordenen. Iedere devicelijn in het Excelbestand moet worden weggeschreven in het bestand met de bestandsnaam die terug te vinden is in deze lijn.
Voor het ordenen maken we terug gebruik van een dictionary. Data wordt erin opgeslagen door te werken met een sleutel en een waarde. Deze waarde kan veel verschillende soorten datatypes omvatten. We kunnen werken met strings,integers of arraylists.
Wat er in principe gebeurt is het overlopen van alle rijen. Daarin wordt de bestandsnaam opgezocht en worden de devicelijnen met dezelfde bestandsnamen bij elkaar geplaatst. Nadat de bestandsnaam van de lijn gelezen is wordt in de dictionary opgezocht of deze een sleutelwaarde bevat met deze bestandsnaam. Indien deze sleutel reeds aanwezig is in de dictionary wordt de overeenkomende waarde (een arraylist) opgehaald en voegen we de devicelijn toe aan de arraylist. Wanneer de bestandsnaam nog niet aanwezig is in de dictionary wordt een nieuwe arraylist aangemaakt waarin de devicelijn wordt geplaatst. De nieuwe arraylist wordt op zijn beurt toegevoegd aan het woordenboek met als sleutel de bestandsnaam. Dit principe herhaalt zich voor iedere lijn.
Code generator voor PLC en SCADA
47
for (int i = 1; i < Aantalrijen; i++) { string filenaam =""; if(this.Soortcode.ToString()=="Code") { filenaam = ExcelData.Rows[i]["FILECODE"].ToString(); } else if(this.Soortcode.ToString()=="Variabelen") { filenaam = ExcelData.Rows[i]["FILEVARIABELEN"].ToString(); } if(Filenames.ContainsKey(filenaam)) { Filenames[filenaam].Add(ExcelData.Rows[i]); } else { ArrayList NieuweArrayList = new ArrayList(); NieuweArrayList.Add(ExcelData.Rows[i]); Filenames.Add(filenaam,NieuweArrayList); } } Hieronder wordt de dictionary visueel voorgesteld. Het woordenboek wordt opgevuld door de bestandsnamen en de arraylists die de Excellijnen bevatten.
Code generator voor PLC en SCADA
48
6.4.4.3 Dictionary uitlezen Nadat alle Excellijnen geordend zijn in de arraylists die in het woordenboek geplaatst zijn, worden alle sleutels één voor één overlopen. Voor iedere sleutel in de dictionary wordt een instantie gecreëerd van de body template. Er worden verschillende properties meegegeven met de template. Zoals onder andere de arraylist met de Excellijnen, de bestandsnaam, welke soort code de gebruiker wenst te genereren. De opbouw en het aanspreken van de juiste devicetemplates gebeurt in de body template. Nadat de methodes in dit sjabloon utigevoerd zijn wordt de gegenereerde codefile weggeschreven naar het pad die de gebruiker opgaf. De naam van het bestand bestaat uit de sleutelwaarde die in het woordenboek geplaatst werd.
int AantalFileNaamRijen = Filenames.Count; List<string> keys = new List<string>(Filenames.Keys); for (int i = 0; i < keys.Count; i++) { ArrayList FileNaamArray = Filenames[keys[i]]; Body Body = this.Create(); Body.Data(FileNaamArray); Body.SetProperty("Bestandsnaam",keys[i]); Body.SetProperty("Soortcode",this.Soortcode.ToString()); Body.SetProperty("Soortprogramma",this.Soortprogramma.ToString()); Body.RenderToFile(Outputfolder+@"\"+keys[i]+".exp",true); } 6.4.4.4 Body De body zal nu effectief één voor één de correcte devicetemplates aanspreken en invullen met de correcte data uit de datarows die in de arraylist te vinden zijn. Het eerste wat in de body gebeurt is bekijken wat voor code er moet gegenereerd worden. Dit kan ladderdiagram of globale variabelen code zijn.
Code generator voor PLC en SCADA
49
Wenst de gebuiker codebestanden te genereren die globale variabelen bevatten dan wordt de correcte naam van de devicetemplate opgebouwd en in een string gestopt.
templatenaam = DataRow["TYPE"].ToString()+"_"+Soortprogramma+"_Variabelen"; De sjabloonnaam bestaat uit drie delen: ten eerste wordt het type van het device in de datarow opgezocht. Dit gebeurt terug door de rij te doorzoeken naar de celwaarde met de kolomnaam “type”. Een tweede stuk is het soort programma waarvoor we codebestanden genereren. Dit kan Beckhoff of Rockwell zijn. Het laatste stuk is “_Variabelen”. Stel dat de gebruiker codebestanden wenst te genereren voor Beckhoff en dat we een AI1 devicetype in de datarow zitten hebben dan wordt de stringwaarde: AI1_Beckhoff_Variabelen.
Na het opstellen van de templatenaam wordt een methode aangesproken die de template zal renderen. De stringwaarde, datarow en welke rij er wordt verwerkt worden met de methode meegegeven. De functies die hier worden besproken worden meerdere malen uitgevoerd, voor iedere lijn in de arraylist.
TemplateRenderen(templatenaam,DataRow,rijnummer); In de methode om het sjabloon te renderen wordt eerst de bestandsnaam doorgegeven aan de template. Daarna roepen we een getter op die de datarow zal opvangen. Ten derde wordt een nieuwe methode aangesproken die het toevoegen van de header en footer zal uitvoeren.
public void TemplateRenderen(string templatenaam,DataRow r,int tel) { CodeTemplates[templatenaam+".cst"].SetProperty("Bestandsnaam",BestandsNaam); CodeTemplates[templatenaam+".cst"].SetProperty("Row",r); HeaderFooterToevoegen(tel,templatenaam,FileNaamArray.Count); CodeTemplates[templatenaam+".cst"].Render(this.Response); CodeTemplates[templatenaam+".cst"].SetProperty("Headertoevoegen","neen"); CodeTemplates[templatenaam+".cst"].SetProperty("Footertoevoegen","neen"); }
Code generator voor PLC en SCADA
50
Zoals in de templates te zien was, werd in ieder sjabloon een header en footer bijgeplaatst. Deze konden wel of niet worden toegevoegd. De methode die hieronder te zien is zal aangeven of de header of footer al dan niet wordt toegevoegd. Het komt erop neer dat enkel de eerste aangesproken template die we in een codefile plaatsen een header zal bevatten. Hetzelfde geldt voor de footer. Enkel de laatste template in een gegenereerde codebestand zal de footer toevoegen. De methode zal dus tellen welke positie het sjabloon heeft ten opzichte van de volledige arraylist die moet worden uitgelezen. Indien het om de eerste en de laatste gaat dan worden respectievelijk de header en footer toegevoegd.
public void HeaderFooterToevoegen(int rijnummer,string templatenaam,int AantalElementen) { if(rijnummer==0||AantalElementen==1) { CodeTemplates[templatenaam+".cst"].SetProperty("Headertoevoegen","ja"); } if(rijnummer ==AantalElementen-1||FileNaamArray.Count==1) { CodeTemplates[templatenaam+".cst"].SetProperty("Footertoevoegen","ja"); } if(rijnummer!=AantalElementen-1&& rijnummer!=0) { CodeTemplates[templatenaam+".cst"].SetProperty("Headertoevoegen","neen"); CodeTemplates[templatenaam+".cst"].SetProperty("Footertoevoegen","neen"); } } Na het toevoegen van header en footer wordt de rest van de methode voor het renderen afgewerkt. De programmeerlijn na het toevoegen van kop- en voettekst zal effectief de templatetekst kopiëren naar het hoofdsjabloon (main template). De twee laatste lijnen zetten de properties voor de header en footer terug op “neen”.
Code generator voor PLC en SCADA
51
Nu de verschillende stappen besproken werden voor de globale variabelen kijken we even naar de opbouw van de ladderdiagram codebestanden. Deze zijn iets ingewikkelder dan deze voor de globale variabelen. Indien we codebestanden wensen te maken voor Beckhoff dan komen de volgende methodes aan bod.
if(Soortprogramma=="Beckhoff") { NetwerkenTellen(); templatenaam = DataRow["TYPE"].ToString()+"_"+Soortprogramma+"_Code"; CodeTemplates[templatenaam+".cst"].SetProperty("Aantalnetwerken",AantalNetwerken); TemplateRenderen(templatenaam,DataRow,rijnummer); }
Het eerste wat moet gebeuren is het tellen van het aantal netwerken die het bestand zal bevatten. Het precieze aantal is van belang omdat dit in de header moet worden geplaatst zodat het gegenereerde bestand correct kan worden geïmporteerd in Beckhoff TwinCAT. Iedere template in de arraylist wordt overlopen en de getter van het aantal netwerken wordt aangeroepen.
public void NetwerkenTellen() { for(int rijnummer=0;j
Vervolgens bouwt de applicatie de templatenaam op en wordt het aantal netwerken doorgegeven aan het sjabloon. Tenslotte renderen we de template door terug de rendermethode aan te roepen.
Code generator voor PLC en SCADA
52
Indien de gebruiker code wil genereren voor Rockwell dan ziet de procedure er wat anders uit. In de devicelijst staat er een kolom “routine”, deze bevat terug een bepaalde waarde. Een van de doelstellingen van de toepassing is namelijk dat het mogelijk moet zijn om verschillende ladderdiagram codebestanden te maken die verschillende routines kunnen bevatten. Een routine binnen zo’n bestand kan bestaan uit verschillende devicelijnen.
Het principe waarin gebruik wordt gemaakt van een dictionary met sleutels en waarden komt hier terug aan bod. Om de Excellijnen te ordenen volgens hun routinenaam wordt er terug gewerkt met een woordenboek. De methodiek is dezelfde zoals het vorige gebruik van de dictionary. Indien er reeds een sleutel aanwezig is in het woordenboek, dan wordt deze opgehaald samen met de arraylist. De huidige datarow wordt eraan toegevoegd. Indien er nog geen sleutel aanwezig is dan wordt een nieuwe arraylist ontworpen en aan het woordenboek toegevoegd. Na het overlopen van alle lijnen komen we toe aan het renderen van de templates.
else if (Soortprogramma=="Rockwell") { routinenaam = DataRow["ROUTINE"].ToString(); if(Routines.ContainsKey(routinenaam)) { Routines[routinenaam].Add(FileNaamArray[rijnummer]); } else { ArrayList NieuweArrayList = new ArrayList(); NieuweArrayList.Add(FileNaamArray[rijnummer]); Routines.Add(routinenaam,NieuweArrayList); } if(rijnummer==FileNaamArray.Count-1) { TemplateRenderenRockwell(); } }
Code generator voor PLC en SCADA
53
Het renderen van de templates gebeurt door alle sleutels in het woordenboek te overlopen en de arraylists die overeenkomen met de sleutels uit te lezen. Daarna wordt ongeveer dezelfde procedure gevolgd zoals bij het renderen van de vorige templates. De toepassing bouwt de templatenaam op, datarows worden meegegeven, header en footer toegevoegd en tenslotte worden de templates gerenderd naar het hoofdsjabloon.
public void TemplateRenderenRockwell() { List<string> keys = new List<string>(Routines.Keys); string templatenaam =""; for (int routinenummer = 0; routinenummer < Routines.Count; routinenummer ++) { ArrayList ArrayRoutines = Routines[keys[routinenummer]]; for(int rijnummer =0; rijnummer
Code generator voor PLC en SCADA
54
6.5 Codesmith GUI 6.5.1 Inleiding Een applicatie die ontwikkeld wordt in de Codesmith studio heeft een standaard gebruikersinterface waarin de gebruiker bepaalde voorkeuren kan instellen. Hieronder worden de verschillende parameters besproken.
6.5.2 Codesmith GUI instellingen Omdat de gebruiker bepaalde instellingen moet kunnen configureren zijn er bepaalde keuzemogelijkheden voorzien.
Figuur 23: Codesmith: GUI
De verschillende keuzemogelijkheden worden opgebouwd door gebruik te maken van tekstvakken, comboboxen en dialoogvensters. Iedere parameter wordt nu afzonderlijk besproken hoe hij precies is opgebouwd en wat zijn functie is binnen de toepassing.
Code generator voor PLC en SCADA
55
•
Excel file: deze parameter kan worden ingevuld door een document te kiezen wanneer het dialoogvenster wordt geopend. Deze keuze bepaalt met welk Exceldocument er wordt gewerkt.
•
Naam werkblad: de tweede keuze die de gebruiker kan maken is het opgeven van de naam van het werkblad die zal ingelezen worden.
•
Output folder: de exacte locatie waar de gegenereerde bestanden in de toekomst worden opgeslagen kan de gebruiker instellen door een map te kiezen. Het kiezen gebeurt door middel van een dialoogvenster dat verschijnt.
•
Soort code: deze parameter maakt aan de toepassing duidelijk welke soort codebestanden er gegenereerd moeten worden. De keuze bestaat uit ladderdiagram of globale variabelen.
•
Soort programma: omdat de generator codebestanden kan genereren voor twee verschillende softwarepakketten moet de gebruiker een keuze kunnen maken voor welk pakket hij daadwerkelijk bestanden wil samenstellen.
•
Template folder: met deze instelling duidt de gebruiker aan waar de templates precies te vinden zijn. Deze functie is handig omdat er bijvoorbeeld kan gewerkt worden met andere templates die op een ander medium aanwezig zijn.
Code generator voor PLC en SCADA
56
7 Besluit De realisatie van de code generator werd tot een goed einde gebracht. De voldoening van deze thesis is erg groot omdat de uitgewerkte oplossing daadwerkelijk gebruikt zal worden binnen Avalon Automation. Het gebruik ervan zal aanzienlijke tijdswinst opleveren. Niet alleen zal het aanmaken van de code sneller gebeuren door het gebruik van deze tool, maar de kans op fouten bij manueel kopiëren is volledig verdwenen. Hierdoor zal de tijd voor het testen verkort worden.
Een eindwerk uitvoeren samen met een bedrijf leverde heel wat positieve ervaringen op. Het autonoom uitwerken van een reëel probleem, bedrijfsvergaderingen bijwonen en het uitwerken van prototypes zijn er enkele van. Omdat Avalon Automation automatiseringsprojecten uitwerkt was het een leerrijke ervaring om kennis op te doen binnen een ongekende sector.
Voor de uitwerking werd gebruik gemaakt van Codesmith Tools. Deze tool bewees echt zijn nut tijdens de ontwikkeling. Het is een erg gebruiksvriendelijke ontwikkelomgeving om een applicatie op te bouwen. Bovendien werkt het generatorproces zonder fouten en dit met een meer dan behoorlijke snelheid.
De doelstellingen die vooropgesteld werden zijn gehaald. De ontwikkelde applicatie is opgebouwd in C# en er wordt gewerkt met templates. Het zo generiek mogelijk opstellen van de applicatie kan in de toekomst nog verder worden uitgewerkt. Indien de tool ook voor andere PLC-softwarepakketten codefiles moet kunnen genereren kan het voorkomen dat er in de programmeercode aanpassen dienen te gebeuren. Dit werd met de informatie die nu voorhanden is tot het minimum beperkt. Er werd ondermeer voor gezorgd dat de templates automatisch worden geregistreerd en dat er templates kunnen worden bijgeplaatst zonder iets te wijzigen aan de programmacode.
Code generator voor PLC en SCADA
57
8 Literatuurlijst Avery, J. (2005). Visual studio hacks. Sebastopol: O’Reilly.
(Beckhoff TwinCAT). Verdeler: Beckhoff, Verl, Duitsland (computerprogramma).
Codesmith community. http://community.codesmithtools.com/. Geraadpleegd op februari,maart,april 2009.
Codesmith API http://www.codesmithtools.com/help/Default.aspx##CodeSmith.chm/Welcome_to_CodeS mith.html. Geraadpleegd februari,maart,april 2009.
De Wandel, M. (2006). ASP.NET. Cursus, Hogeschool west-vlaanderen, Departement PIH.
Lewis, R. W. (1998). Programming industrial control systems using IEC 1131-3. IET.
MSDN NET Framework Developer Center. http://msdn.microsoft.com/enus/library/xfhwa508(VS.80).aspx. Geraadpleegd op april 2009.
Pollefiet, L. (2009). Een eindwerk schrijven – do ‘s & don’ts. Gent: Academia Press.
(Rockwell RSLogix 5000 versie 16). Verdeler: Rockwell Automation, Strombeek-Bever, België (computerprogramma).
Rohner, P. (1996). PLC: automation with programmable logic controllers: a textbook for engineers and technicians. Syndey: USNW Press.
Smith E. J. (Codesmith Tools versie 5.0.5.6362). (2009). Verdeler: CodeSmith Tools LCC, Dallas, TX 75252, USA (computerprogramma).
Code generator voor PLC en SCADA
58
Viaene, I. (2007). Office Automation: C#. Cursus, Hogeschool west-vlaanderen, Departement PIH.
Vlummens, F., Gaillez, M. & De Preester, D. (2005). Basisconcepten van C#. Cursus, Hogeschool west-vlaanderen, Departement PIH.
Code generator voor PLC en SCADA
59
9 Bijlagen Bijlage 1
Devicelijst
Bijlage 2
Voorbeeld van een AI1 template
Bijlage 3
Een gegenereerd codebestand
Bijlage 4
Screenshot van een ladderdiagram blok in Beckhoff
Code generator voor PLC en SCADA
60
Bijlage 1 De devicelijst bestaat uit een Excelwerkblad waar alle devicelijnen op terug te vinden zijn. In de verschillende kolommen staat er data die we moeten invullen in de templates.
Code generator voor PLC en SCADA
I
Bijlage 2 De templates worden opgebouwd in Codesmith Tools en bestaan uit een template gedeelte en een stuk voor de code-behind. In deze bijlage wordt een A1 template afgebeeld.
Code generator voor PLC en SCADA
II
Code generator voor PLC en SCADA
III
Code generator voor PLC en SCADA
IV
Code generator voor PLC en SCADA
V
Code generator voor PLC en SCADA
VI
Code generator voor PLC en SCADA
VII
Code generator voor PLC en SCADA
VIII
Code generator voor PLC en SCADA
IX
Bijlage 3 De concrete opbouw van een ladderdiagram codebestand voor Beckhoff bestaat uit enkele pagina’s met parameterlijnen.
(* @PATH := '\/PROGRAMS' *) (* @SYMFILEFLAGS := '4096'*) PROGRAM AI1bestand.EXP VAR END_VAR (* @END_DECLARATION := '0'*) _LD_BODY _NETWORKS : 6 _NETWORK _COMMENT Example AI1: Handling an analog input signal with delay on broken wire; IN=integer _END_COMMENT _LD_ASSIGN _EMPTY _EXPRESSION _POSITIV
ENABLELIST : 1 _ASSIGN _FUNCTIONBLOCK Z_AI1 _BOX_EXPR : 25 _ENABLED _OPERAND _EXPRESSION _POSITIV Z_AI1_IN _OPERAND _EXPRESSION _POSITIV Z_AI1_STATE.0 _OPERAND _EXPRESSION _NEGATIV Z_SLAVE10.ON _OPERAND _EXPRESSION _POSITIV 0 _OPERAND _EXPRESSION _POSITIV 32767 _OPERAND _EXPRESSION _POSITIV 0 _OPERAND _EXPRESSION _POSITIV 100 _OPERAND _EXPRESSION _POSITIV Z_RST _OPERAND
Code generator voor PLC en SCADA
X
_EXPRESSION _POSITIV Z_AI1_TH.HH _OPERAND _EXPRESSION _POSITIV Z_AI1_TH.H _OPERAND _EXPRESSION _POSITIV Z_AI1_TH.L _OPERAND _EXPRESSION _POSITIV Z_AI1_TH.LL _OPERAND _EXPRESSION _POSITIV Z_AI1_HH.AL _OPERAND _EXPRESSION _POSITIV Z_AI1_H.AL _OPERAND _EXPRESSION _POSITIV Z_AI1_L.AL _OPERAND _EXPRESSION _POSITIV Z_AI1_LL.AL _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV Z_AI1_HH.ALARM_B _OPERAND _EXPRESSION _POSITIV Z_AI1_H.ALARM_B _OPERAND _EXPRESSION _POSITIV Z_AI1_L.ALARM_B _OPERAND _EXPRESSION _POSITIV Z_AI1_LL.ALARM_B _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV T#0s _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV Z_INFO _EXPRESSION _POSITIV AI1
Code generator voor PLC en SCADA
XI
_OUTPUTS : 0 _EXPRESSION _POSITIV _OUTPUTS : 1 _OUTPUT _POSITIV _NO_SET DUMMYBOOL ENABLELIST_END _OUTPUTS : 0 _NETWORK _COMMENT _END_COMMENT _LD_ASSIGN _EMPTY _EXPRESSION _POSITIV
ENABLELIST : 1 _ASSIGN _FUNCTIONBLOCK Z_AI1_TH _BOX_EXPR : 6 _ENABLED _OPERAND _EXPRESSION _POSITIV Z_AI1.EU _OPERAND _EXPRESSION _POSITIV _EMPTY _OPERAND _EXPRESSION _POSITIV _EMPTY _OPERAND _EXPRESSION _POSITIV _EMPTY _OPERAND _EXPRESSION _POSITIV _EMPTY _OPERAND _EXPRESSION _POSITIV _EMPTY _EXPRESSION _POSITIV THRESH4 _OUTPUTS : 0 _EXPRESSION _POSITIV _OUTPUTS : 1 _OUTPUT _POSITIV _NO_SET DUMMYBOOL ENABLELIST_END _OUTPUTS : 0 _NETWORK _COMMENT
Code generator voor PLC en SCADA
XII
_END_COMMENT _LD_ASSIGN _EMPTY _EXPRESSION _POSITIV
ENABLELIST : 1 _ASSIGN _FUNCTIONBLOCK Z_AI1_HH _BOX_EXPR : 6 _ENABLED _OPERAND _EXPRESSION _POSITIV Z_AI1_TH.HH _OPERAND _EXPRESSION _POSITIV TRUE _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV Z_RST _OPERAND _EXPRESSION _POSITIV T#0s _OPERAND _EXPRESSION _POSITIV Z_INFO _EXPRESSION _POSITIV ALARM1 _OUTPUTS : 0 _EXPRESSION _POSITIV _OUTPUTS : 1 _OUTPUT _POSITIV _NO_SET DUMMYBOOL ENABLELIST_END _OUTPUTS : 0 _NETWORK _COMMENT _END_COMMENT _LD_ASSIGN _EMPTY _EXPRESSION _POSITIV
ENABLELIST : 1 _ASSIGN _FUNCTIONBLOCK Z_AI1_H _BOX_EXPR : 6 _ENABLED _OPERAND _EXPRESSION
Code generator voor PLC en SCADA
XIII
_POSITIV Z_AI1_TH.H _OPERAND _EXPRESSION _POSITIV TRUE _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV Z_RST _OPERAND _EXPRESSION _POSITIV T#0s _OPERAND _EXPRESSION _POSITIV Z_INFO _EXPRESSION _POSITIV ALARM1 _OUTPUTS : 0 _EXPRESSION _POSITIV _OUTPUTS : 1 _OUTPUT _POSITIV _NO_SET DUMMYBOOL ENABLELIST_END _OUTPUTS : 0 _NETWORK _COMMENT _END_COMMENT _LD_ASSIGN _EMPTY _EXPRESSION _POSITIV
ENABLELIST : 1 _ASSIGN _FUNCTIONBLOCK Z_AI1_L _BOX_EXPR : 6 _ENABLED _OPERAND _EXPRESSION _POSITIV Z_AI1_TH.L _OPERAND _EXPRESSION _POSITIV TRUE _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV Z_RST _OPERAND
Code generator voor PLC en SCADA
XIV
_EXPRESSION _POSITIV T#0s _OPERAND _EXPRESSION _POSITIV Z_INFO _EXPRESSION _POSITIV ALARM1 _OUTPUTS : 0 _EXPRESSION _POSITIV _OUTPUTS : 1 _OUTPUT _POSITIV _NO_SET DUMMYBOOL ENABLELIST_END _OUTPUTS : 0 _NETWORK _COMMENT _END_COMMENT _LD_ASSIGN _EMPTY _EXPRESSION _POSITIV
ENABLELIST : 1 _ASSIGN _FUNCTIONBLOCK Z_AI1_LL _BOX_EXPR : 6 _ENABLED _OPERAND _EXPRESSION _POSITIV Z_AI1_TH.LL _OPERAND _EXPRESSION _POSITIV TRUE _OPERAND _EXPRESSION _POSITIV FALSE _OPERAND _EXPRESSION _POSITIV Z_RST _OPERAND _EXPRESSION _POSITIV T#0s _OPERAND _EXPRESSION _POSITIV Z_INFO _EXPRESSION _POSITIV ALARM1 _OUTPUTS : 0 _EXPRESSION _POSITIV _OUTPUTS : 1 _OUTPUT
Code generator voor PLC en SCADA
XV
_POSITIV _NO_SET DUMMYBOOL ENABLELIST_END _OUTPUTS : 0 END_PROGRAM
Code generator voor PLC en SCADA
XVI
Bijlage 4 Hieronder is een screenshot te vinden van een ladderdiagram blokje die aan de hand van een gegenereerd codebestand werd geïmporteerd in Beckhoff.
Code generator voor PLC en SCADA
XVII