├── .gitignore ├── LICENSE.txt ├── README.md ├── Requirements.txt ├── _config.yml ├── package.json ├── samples ├── Datatypes │ ├── Alarm.py │ ├── PushButton.py │ └── __init__.py ├── L5X.pdf └── lxml.pdf └── src ├── AB ├── Rockwell │ ├── Types.py │ ├── XML │ │ ├── Templates │ │ │ ├── Base_Template.py │ │ │ ├── Controller.py │ │ │ ├── Datatype.py │ │ │ ├── Member.py │ │ │ ├── Program.py │ │ │ ├── Project.py │ │ │ ├── Routine.py │ │ │ ├── Rung.py │ │ │ ├── Tag.py │ │ │ ├── TagComment.py │ │ │ └── __init__.py │ │ ├── Tools.py │ │ └── __init__.py │ └── __init__.py └── __init__.py ├── Description.txt ├── MANIFEST.in ├── Tests ├── L5X_Printable.L5X ├── Sample_UDT.L5X ├── TemplatesTest.py └── pb.csv ├── build └── lib │ └── AB │ ├── Rockwell │ ├── Types.py │ ├── XML │ │ ├── Templates │ │ │ ├── Base_Template.py │ │ │ ├── Controller.py │ │ │ ├── Datatype.py │ │ │ ├── Member.py │ │ │ ├── Program.py │ │ │ ├── Project.py │ │ │ ├── Routine.py │ │ │ ├── Rung.py │ │ │ ├── Tag.py │ │ │ ├── TagComment.py │ │ │ └── __init__.py │ │ ├── Tools.py │ │ └── __init__.py │ └── __init__.py │ └── __init__.py ├── dist ├── allen-bradley-toolkit-1.0a1.post0.tar.gz ├── allen_bradley_toolkit-1.0.0-py3-none-any.whl ├── allen_bradley_toolkit-1.0a1.post0-py3-none-any.whl ├── allen_bradley_toolkit-1.0a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.1a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.2a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.3a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.4a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.5a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.6a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-1.7a1.post1-py3-none-any.whl ├── allen_bradley_toolkit-2.0.0-py3-none-any.whl └── allen_bradley_toolkit-2.0.1-py2-none-any.whl ├── lxml ├── setup.cfg ├── setup.py └── shutil /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Compiled python modules. 3 | *.pyc 4 | 5 | # Setuptools Test folder. 6 | /Tests/ 7 | 8 | # Python egg metadata, regenerated from source files by setuptools. 9 | /*.egg-info 10 | /*/*.egg-info 11 | 12 | # Virtual Environment folder 13 | .venv 14 | 15 | # Visual Studio Code Settings Folder 16 | .vscode 17 | 18 | # Ignore build and distribution directories 19 | /build/ 20 | /dist/ 21 | 22 | #pypirc 23 | *.pypirc 24 | 25 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=plastic)](https://gitter.im/Allen-Bradley-Toolkit/Lobby) [![PyPI](https://img.shields.io/pypi/v/nine.svg?style=plastic)](https://pypi.org/project/allen-bradley-toolkit/) 2 | 3 | # **OVERVIEW** # 4 | 5 | > *"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it."* 6 | > 7 | > Brian W. Kernighan 8 | 9 | ### **What is this repository for?** ### 10 | 11 | * The goal of this project is to generate a python package to wrap the standard lxml python package for easy L5X file manipulation as well as to create usable scripts that implement this package. 12 | 13 | ### **How do I get set up?** ### 14 | 15 | * **Install C++ Build Tools** 16 | * Click this [Link](http://go.microsoft.com/fwlink/?LinkId=691126&__hstc=268264337.20dfe66f0053415ec618cc41e1e5ebee.1519654047676.1519654047676.1519656772032.2&__hssc=268264337.1.1519656772032&__hsfp=2795554280&fixForIE=.exe) to Download Installer 17 | * Run Installer 18 | * You're Done 19 | 20 | * **Get Required Dependencies** 21 | 22 | * Download and Install [Python 2.7.13](https://www.python.org/ftp/python/2.7.13/python-2.7.13.msi) 23 | * Open a **Command Prompt** window as **Aministrator** 24 | * Run `set PATH=%PATH%;C:\python27\;C:\Python27\Scripts\` 25 | * Run `set PATHEXT=%PATHEXT%;.PY` 26 | * You're Done 27 | 28 | 29 | 30 | * **Download and Install Package** 31 | 32 | * Open a **Command Prompt** window as **Aministrator** 33 | * Run `pip install allen-bradley-toolkit` 34 | * All Scripts will now be Available from **Windows Command Prompt** 35 | * You're Done 36 | 37 | 38 | 39 | * **Update Package/ Version Control** 40 | * Open Windows **Command Prompt** as **Administrator** 41 | * Run `pip install allen-bradley-toolkit -U` 42 | * You're Done 43 | 44 | 45 | 46 | 47 | ### **Who do I talk to?** ### 48 | 49 | * **Canaan Seaton - Project Owner** 50 | * *GitHub: [Cmseaton42](https://github.com/cmseaton42)* 51 | 52 | -------------------------------------------------------------------------------- /Requirements.txt: -------------------------------------------------------------------------------- 1 | appdirs==1.4.0 2 | packaging==16.8 3 | pyparsing==2.1.10 4 | six==1.10.0 5 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "allen-bradley-toolkit", 3 | "version": "1.0.0", 4 | "description": "[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=plastic)](https://gitter.im/Allen-Bradley-Toolkit/Lobby) [![PyPI](https://img.shields.io/pypi/v/nine.svg?style=plastic)](https://pypi.python.org/pypi/Preh)", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/cmseaton42/Allen-Bradley-Toolkit.git" 9 | }, 10 | "author": "", 11 | "license": "MIT", 12 | "bugs": { 13 | "url": "https://github.com/cmseaton42/Allen-Bradley-Toolkit/issues" 14 | }, 15 | "scripts": { 16 | "deploy": "cd src && python setup.py bdist_wheel && twine upload dist/* --skip-existing" 17 | }, 18 | "homepage": "https://github.com/cmseaton42/Allen-Bradley-Toolkit#readme" 19 | } 20 | -------------------------------------------------------------------------------- /samples/Datatypes/Alarm.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.Types import CommonType 8 | from AB.Rockwell.XML.Templates import * 9 | 10 | class Alarm(Datatype): 11 | def __init__(self): 12 | Datatype.__init__(self, "ST_Alarms") 13 | self.addMember(Member("Word", CommonType.DINT)) 14 | self.addMember(Member("Compare", CommonType.DINT)) 15 | self.addMember(Member("ONS", CommonType.DINT)) 16 | self.addMember(Member("TMR", CommonType.TIMER)) 17 | self.addMember(Member("CNT", CommonType.COUNTER)) 18 | -------------------------------------------------------------------------------- /samples/Datatypes/PushButton.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.Types import CommonType 8 | from AB.Rockwell.XML.Templates import * 9 | 10 | class PB_OneButton(Datatype): 11 | def __init__(self): 12 | Datatype.__init__(self, "PB_OneButton") 13 | self.bitTarget = "XXXXXXXXXXHost" 14 | self.addMember(Member(self.bitTarget, CommonType.SINT, Hidden = True)) 15 | self.addMember(Member("Push", CommonType.BOOL, Target = self.bitTarget, BitNumber = 0)) 16 | self.addMember(Member("State", CommonType.BOOL, Target = self.bitTarget, BitNumber = 1)) 17 | self.addMember(Member("Visibility", CommonType.BOOL, Target = self.bitTarget, BitNumber = 2)) 18 | self.addMember(Member("Ind", CommonType.BOOL, Target = self.bitTarget, BitNumber = 3)) 19 | self.addMember(Member("Interlock", CommonType.BOOL, Target = self.bitTarget, BitNumber = 4)) 20 | self.addMember(Member("ONS", CommonType.BOOL, Target = self.bitTarget, BitNumber = 5)) 21 | self.addMember(Member("Tmr", CommonType.TIMER)) 22 | 23 | class PB_TwoButton(Datatype): 24 | def __init__(self): 25 | Datatype.__init__(self, "PB_TwoButton") 26 | self.addMember(Member("ButtonA", "PB_OneButton")) 27 | self.addMember(Member("ButtonB", "PB_OneButton")) 28 | -------------------------------------------------------------------------------- /samples/Datatypes/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/samples/Datatypes/__init__.py -------------------------------------------------------------------------------- /samples/L5X.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/samples/L5X.pdf -------------------------------------------------------------------------------- /samples/lxml.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/samples/lxml.pdf -------------------------------------------------------------------------------- /src/AB/Rockwell/Types.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class CommonType: 4 | BOOL = "BOOL" 5 | SINT = "SINT" 6 | INT = "INT" 7 | DINT = "DINT" 8 | REAL = "REAL" 9 | STRING = "STRING" 10 | COUNTER = "COUNTER" 11 | TIMER = "TIMER" 12 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Base_Template.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | import os 8 | from AB.Rockwell.XML.Tools import * 9 | 10 | class Base_Template(): 11 | ''' 12 | Base Template Template: 13 | See L5X Manual for Details, 14 | USED FOR INHERITANCE ONLY 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self): 19 | #Initialize Member Attributes 20 | self.root = None 21 | 22 | def checkIfChild(self, nodeTag): 23 | assert type(nodeTag) == str 24 | for node in self.root: 25 | if node.tag == nodeTag: return True 26 | return False 27 | 28 | def setAttribute(self, kwargs): 29 | for key in kwargs: 30 | if not key in self.root.keys(): 31 | raise KeyError("%s has No Attribute: <%s>" % (self.root.tag, key)) 32 | 33 | for key in kwargs: 34 | self.root.set(key, kwargs[key]) 35 | 36 | def setDescription(self, Description): 37 | assert type(Description) == str 38 | if self.Desc == None: 39 | self.Desc = etree.SubElement(self.root, 'Description') 40 | self.root.append(self.Desc) 41 | self.Desc.text = etree.CDATA(Description) 42 | 43 | def setParent(self, parent): 44 | pass 45 | 46 | def getLocalRoot(self): 47 | return self.root 48 | 49 | def __str__(self): 50 | return etree.tostring(self.root, pretty_print = True, xml_declaration = True, encoding = "UTF-8", standalone = "yes") 51 | 52 | def writeToFile(self, fileName = os.getcwd() + "/L5X_Printable.L5X"): 53 | tree = etree.ElementTree(self.root) 54 | tree.write(fileName, pretty_print = True, xml_declaration = True, encoding = "UTF-8", standalone = "yes") 55 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Controller.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Controller(Base_Template): 11 | ''' 12 | Controller Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a Controller. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Name, Use = "Context", Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(Name) 21 | self.root = etree.Element('Controller') 22 | if Description != "": 23 | self.Desc = etree.SubElement(self.root, 'Description') 24 | self.setDescription(Description) 25 | self.root.append(self.Desc) 26 | 27 | def addDatatype(self, Datatype): 28 | assert etree.iselement(Datatype.getLocalRoot()) and Datatype.getLocalRoot().tag == "Datatype" 29 | if not self.checkIfChild("Datatypes"): 30 | self.Datatypes = etree.SubElement(self.root, "Datatypes") 31 | self.Datatypes.append(Datatype.getLocalRoot()) 32 | 33 | def addModule(self, Module): 34 | assert etree.iselement(Module.getLocalRoot()) and Module.getLocalRoot().tag == "Module" 35 | if not self.checkIfChild("Modules"): 36 | self.Modules = etree.SubElement(self.root, "Modules") 37 | self.Modules.append(Module.getLocalRoot()) 38 | 39 | 40 | def addAddOnInstructionDefinition(self, AddOnInstructionDefinition): 41 | assert etree.iselement(AddOnInstructionDefinition.getLocalRoot()) and AddOnInstructionDefinition.getLocalRoot().tag == "AddOnInstructionDefinition" 42 | if not self.checkIfChild("AddOnInstructionDefinitions"): 43 | self.AddOnInstructionDefinitions = etree.SubElement(self.root, "AddOnInstructionDefinitions") 44 | self.AddOnInstructionDefinitions.append(AddOnInstructionDefinition.getLocalRoot()) 45 | 46 | def addTag(self, Tag): 47 | assert etree.iselement(Tag.getLocalRoot()) and Tag.getLocalRoot().tag == "Tag" 48 | if not self.checkIfChild("Tags"): 49 | self.Tags = etree.SubElement(self.root, "Tags") 50 | self.Tags.append(Tag.getLocalRoot()) 51 | 52 | def addProgram(self, Program): 53 | assert etree.iselement(Program.getLocalRoot()) and Program.getLocalRoot().tag == "Program" 54 | if not self.checkIfChild("Programs"): 55 | self.Programs = etree.SubElement(self.root, "Programs") 56 | self.Programs.append(Program.getLocalRoot()) 57 | 58 | def addTask(self, Task): 59 | assert etree.iselement(Task.getLocalRoot()) and Task.getLocalRoot().tag == "Task" 60 | if not self.checkIfChild("Tasks"): 61 | self.Tasks = etree.SubElement(self.root, "Tasks") 62 | self.Tasks.append(Task.getLocalRoot()) 63 | 64 | def setParent(self, parent): 65 | assert etree.iselement(parent) and parent.tag == "Members" 66 | parent.append(self.getLocalRoot()) 67 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Datatype.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Datatype(Base_Template): 11 | ''' 12 | UDT Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a datatype. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, TypeName, Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(TypeName) 21 | self.root = etree.Element("Datatype") 22 | self.root.set("Name", TypeName) 23 | self.root.set("Family", "NoFamily") 24 | self.root.set("Class", "User") 25 | if Description != "": 26 | self.Desc = etree.SubElement(self.root, 'Description') 27 | self.setDescription(Description) 28 | self.root.append(self.Desc) 29 | 30 | self.Members = etree.SubElement(self.root, "Members") 31 | 32 | def getMembersRoot(self): 33 | return self.Members 34 | 35 | def addMember(self, member): 36 | self.Members.append(member.getLocalRoot()) 37 | 38 | def setParent(self, parent): 39 | assert etree.iselement(parent) and parent.tag == "DatatTypes" 40 | parent.append(self.root) 41 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Member.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Member(Base_Template): 11 | ''' 12 | Member Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a member. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, TagName, DataType, Hidden = False, Description = "", Radix = "Decimal", ArrayLength = 0, Target = "", BitNumber = 0): 19 | #Initialize Member Attributes 20 | assert isValidTag(TagName) 21 | if DataType == "BOOL": DataType = "BIT" 22 | self.root = etree.Element('Member') 23 | self.root.set("Name", TagName) 24 | self.root.set("Datatype", str(DataType)) 25 | self.root.set("Dimension",str(ArrayLength)) 26 | self.root.set("Radix", Radix) 27 | if DataType == "BIT": 28 | #Reference Rockwell Manuals for Bit Overlays for details on the following assertion. 29 | if Target == "": raise ValueError("Data of Type BOOL Must have a Target: eg. target = 'ZZZZZZZZZZSample0'") 30 | self.root.set("Hidden", "false") 31 | self.root.set("Target", Target) 32 | self.root.set("BitNumber", str(BitNumber)) 33 | elif Hidden == True: 34 | self.root.set("Hidden", "true") 35 | else: 36 | self.root.set("Hidden", "false") 37 | self.root.set("ExternalAccess", "Read/Write") 38 | if Description != "": 39 | self.Desc = etree.SubElement(self.root, 'Description') 40 | self.setDescription(Description) 41 | self.root.append(self.Desc) 42 | 43 | def setParent(self, parent): 44 | assert etree.iselement(parent) and parent.tag == "Members" 45 | parent.append(self.getLocalRoot()) 46 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Program.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Program(Base_Template): 11 | ''' 12 | Program Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a program. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Name, Type = "Normal", Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(Name) 21 | self.root = etree.Element("Program") 22 | self.root.set("Name", Name) 23 | self.root.set("Type", Type) 24 | if Description != "": 25 | self.Desc = etree.SubElement(self.root, 'Description') 26 | self.setDescription(Description) 27 | self.root.append(self.Desc) 28 | 29 | def setMainRoutine(self, RoutineName): 30 | assert type(RoutineName) == str 31 | self.root.set("MainRoutineName", RoutineName) 32 | 33 | def addRoutine(self, Routine): 34 | assert etree.iselement(Routine.getLocalRoot()) and Routine.getLocalRoot().tag == "Routine" 35 | if not self.checkIfChild("Routines"): 36 | self.Routines = etree.SubElement(self.root, "Routines") 37 | self.Routines.append(Routine.getLocalRoot()) 38 | 39 | def addTag(self, Tag): 40 | assert etree.iselement(Tag.getLocalRoot()) and Tag.getLocalRoot().tag == "Tag" 41 | if not self.checkIfChild("Tags"): 42 | self.Tags = etree.SubElement(self.root, "Tags") 43 | self.Tags.append(Tag.getLocalRoot()) 44 | 45 | def setParent(self, parent): 46 | assert etree.iselement(parent) and parent.tag == "Programs" 47 | parent.append(self.root) 48 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Project.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Project(Base_Template): 11 | ''' 12 | Project Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a project. 15 | ---------------------------------------------------------- 16 | This class should always serve as the base class. 17 | ---------------------------------------------------------- 18 | For Information on this see the provided L5X Manual from Rockwell 19 | ''' 20 | def __init__(self, SchemaRevision = "1.0", SoftwareRevision = "30.00"): 21 | #Initialize Member Attributes 22 | self.root = etree.Element("RSLogix5000Content") 23 | self.root.set("SchemaRevision", SchemaRevision) 24 | self.root.set("SoftwareRevision", SoftwareRevision) 25 | 26 | def getControllerRoot(self): 27 | return self.Controller 28 | 29 | def setController(self, Controller): 30 | assert etree.iselement(Controller.getLocalRoot()) and Controller.getLocalRoot().tag == "Controller" 31 | self.root.append(Controller.getLocalRoot()) 32 | 33 | def setAttribute(self, kwargs): 34 | for key in kwargs: 35 | self.root.set(key, kwargs[key]) 36 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Routine.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Routine(Base_Template): 11 | ''' 12 | Routine Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a ladder routine. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Name, Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(Name) 21 | self.root = etree.Element("Routine") 22 | self.root.set("Name", Name) 23 | self.root.set("Type", "RLL") 24 | if Description != "": 25 | self.Desc = etree.SubElement(self.root, 'Description') 26 | self.setDescription(Description) 27 | self.root.append(self.Desc) 28 | 29 | def addRung(self, Rung): 30 | assert etree.iselement(Rung.getLocalRoot()) and Rung.getLocalRoot().tag == "Rung" 31 | if not self.checkIfChild("RLLContent"): 32 | self.RLLContent = etree.SubElement(self.root, "RLLContent") 33 | self.RLLContent.append(Rung.getLocalRoot()) 34 | 35 | def setParent(self, parent): 36 | assert etree.iselement(parent) and parent.tag == "Routines" 37 | parent.append(self.root) 38 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Rung.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Rung(Base_Template): 11 | ''' 12 | Rung Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a ladder rung. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Number, Comment = "", Content = "NOP();"): 19 | #Initialize Member Attributes 20 | self.root = etree.Element("Rung") 21 | self.root.set("Number", str(Number)) 22 | self.root.set("Type", "N") 23 | if Comment != "": 24 | self.Comment = etree.SubElement(self.root, 'Comment') 25 | self.setComment(Comment) 26 | self.root.append(self.Comment) 27 | 28 | self.rungContent = etree.SubElement(self.root, "Text") 29 | self.setRungContent(Content) 30 | 31 | def setRungContent(self, Content): 32 | assert type(Content) == str 33 | self.rungContent.text = etree.CDATA(Content) 34 | 35 | def setComment(self, Comment): 36 | assert type(Comment) == str 37 | if self.Comment == None: 38 | self.Comment = etree.SubElement(self.root, 'Comment') 39 | self.root.append(self.Comment) 40 | self.Comment.text = etree.CDATA(Comment) 41 | 42 | def setParent(self, parent): 43 | assert etree.iselement(parent) and parent.tag == "RLLContent" 44 | parent.append(self.root) 45 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/Tag.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Tag(Base_Template): 11 | ''' 12 | Tag Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a Tag. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, TagName, DataType, TagType = "Base", Description = "", UseRadix = True, Radix = "Decimal", Constant = "false", ArrayLength = 0): 19 | #Initialize Member Attributes 20 | assert isValidTag(TagName) 21 | self.root = etree.Element('Tag') 22 | self.root.set("Name", TagName) 23 | self.root.set("TagType", TagType) 24 | self.root.set("Datatype", str(DataType)) 25 | self.root.set("Dimension",str(ArrayLength)) 26 | if UseRadix: self.root.set("Radix", Radix) 27 | self.root.set("ExternalAccess", "Read/Write") 28 | if Description != "": 29 | self.Desc = etree.SubElement(self.root, 'Description') 30 | self.setDescription(Description) 31 | self.root.append(self.Desc) 32 | 33 | def setAsIO(self): 34 | self.root.set("IO","true") 35 | 36 | def addTagComment(self, TagComment): 37 | assert etree.iselement(TagComment.getLocalRoot()) and TagComment.getLocalRoot().tag == "Comment" 38 | if not self.checkIfChild("Comments"): 39 | self.Comments = etree.SubElement(self.root, "Comments") 40 | self.Comments.append(TagComment.getLocalRoot()) 41 | 42 | def setUsage(self, Usage): 43 | assert Usage == "Input" or Usage == "Output" or Usage == "InOut" or Usage == "Public" 44 | self.root.set("Usage", Usage) 45 | 46 | def setAlias(self, TagName): 47 | self.root.set("AliasFor", TagName) 48 | 49 | def setClassAttribute(self, classAttribute): 50 | assert classAttribute == "Standard" or classAttribute == "Safety" 51 | self.root.set("Class", classAttribute) 52 | 53 | def setDescription(self, Description): 54 | assert type(Description) == str 55 | if self.Desc == None: 56 | self.Desc = etree.SubElement(self.root, 'Description') 57 | self.root.append(self.Desc) 58 | self.Desc.text = etree.CDATA(Description) 59 | 60 | def setParent(self, parent): 61 | assert etree.iselement(parent) and parent.tag == "Tags" 62 | parent.append(self.getLocalRoot()) 63 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/TagComment.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class TagComment(Base_Template): 11 | ''' 12 | Tag Comment Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a tag's comment. 15 | ---------------------------------------------------------- 16 | [specifier].[BitNumber] 17 | ---------------------------------------------------------- 18 | For Information on this see the provided L5X Manual from Rockwell 19 | ''' 20 | def __init__(self, Description): 21 | #Initialize Member Attributes 22 | self.root = etree.Element("Comment") 23 | self.root.set("Operand", "Specifier") 24 | setDescription(Description) 25 | self.setDescription(Description) 26 | 27 | def setDescription(self, Description): 28 | assert type(Description) == str 29 | self.root.text = etree.CDATA(Description) 30 | 31 | def setParent(self, parent): 32 | assert etree.iselement(parent) and parent.tag == "Comments" 33 | parent.append(self.getLocalRoot()) 34 | 35 | def getLocalRoot(self): 36 | return self.root 37 | 38 | def __str__(self): 39 | return etree.tostring(self.root, pretty_print = True) 40 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Templates/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["Controller", "Datatype", "Member", "Program", "Project", "Routine", "Rung", "Tag", "TagComment"] 2 | 3 | from Controller import Controller 4 | from Datatype import Datatype 5 | from Member import Member 6 | from Program import Program 7 | from Project import Project 8 | from Routine import Routine 9 | from Rung import Rung 10 | from Tag import Tag 11 | from TagComment import TagComment 12 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/Tools.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | 8 | def setAsTarget(template): 9 | try: 10 | template.root.set("use", "Target") 11 | except: 12 | template.set("use", "Target") 13 | 14 | 15 | def setAsContext(template): 16 | try: 17 | template.root.set("use", "Context") 18 | except: 19 | template.set("use", "Context") 20 | 21 | 22 | def isValidTag(TagName): 23 | strCopy = TagName 24 | if "_" in strCopy: 25 | strCopy = strCopy.replace("_", "") 26 | if strCopy[0].isdigit(): 27 | return False 28 | return strCopy.isalnum() 29 | -------------------------------------------------------------------------------- /src/AB/Rockwell/XML/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["Templates", "Tools"] 2 | -------------------------------------------------------------------------------- /src/AB/Rockwell/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["XML", "Types"] 2 | 3 | from AB.Rockwell.Types import CommonType 4 | -------------------------------------------------------------------------------- /src/AB/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["Rockwell"] 2 | -------------------------------------------------------------------------------- /src/Description.txt: -------------------------------------------------------------------------------- 1 | ToDo: Complete this. 2 | -------------------------------------------------------------------------------- /src/MANIFEST.in: -------------------------------------------------------------------------------- 1 | # Include the license file 2 | include LICENSE.txt 3 | -------------------------------------------------------------------------------- /src/Tests/L5X_Printable.L5X: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/Tests/Sample_UDT.L5X: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Tests/TemplatesTest.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os.path 3 | sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) 4 | 5 | from AB.Rockwell.Types import CommonType 6 | from AB.Rockwell.XML.Templates import * 7 | 8 | import lxml 9 | from lxml import etree 10 | 11 | def MemberTest(): 12 | root = etree.Element('Members') 13 | 14 | desc = "Just a Test Tag" 15 | testMember1 = Member('someTag1', CommonType.INT, Description = desc) 16 | testMember2 = Member('someTag2', CommonType.STRING) 17 | 18 | testMember1.setParent(root) 19 | testMember2.setParent(root) 20 | 21 | print etree.tostring(root, pretty_print = True) 22 | 23 | def DatatypeTest(): 24 | root = etree.Element('Datatypes') 25 | 26 | dt = Datatype('Sample', Description = 'just for fun') 27 | 28 | memList = [] 29 | 30 | memList.append(Member('sint0', CommonType.SINT, Description = 'some random sint')) 31 | memList.append(Member('sint1', CommonType.SINT, Description = 'blah')) 32 | 33 | for mem in memList: 34 | dt.addMember(mem) 35 | 36 | root.append(dt.getLocalRoot()) 37 | 38 | print etree.tostring(root, pretty_print = True) 39 | 40 | def TagTest(): 41 | root = etree.Element('Tags') 42 | 43 | Tag1 = Tag('Hello_World', CommonType.BOOL) 44 | Tag2 = Tag('SomeOtherTag', CommonType.SINT) 45 | 46 | Tag1.setParent(root) 47 | Tag2.setParent(root) 48 | 49 | print etree.tostring(root, pretty_print = True) 50 | 51 | if __name__ == '__main__': 52 | MemberTest() 53 | DatatypeTest() 54 | TagTest() 55 | -------------------------------------------------------------------------------- /src/Tests/pb.csv: -------------------------------------------------------------------------------- 1 | Name, Type, Scope, Description 2 | SomeButton, 1, 0, Does Something 3 | AnotherButton, 2, 1, Dumb Tag 4 | ballinButton, 1, 0, Campell Gets Taller Buttons 5 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/Types.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class CommonType: 4 | BOOL = "BOOL" 5 | SINT = "SINT" 6 | INT = "INT" 7 | DINT = "DINT" 8 | REAL = "REAL" 9 | STRING = "STRING" 10 | COUNTER = "COUNTER" 11 | TIMER = "TIMER" 12 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Base_Template.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | import os 8 | from AB.Rockwell.XML.Tools import * 9 | 10 | class Base_Template(): 11 | ''' 12 | Base Template Template: 13 | See L5X Manual for Details, 14 | USED FOR INHERITANCE ONLY 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self): 19 | #Initialize Member Attributes 20 | self.root = None 21 | 22 | def checkIfChild(self, nodeTag): 23 | assert type(nodeTag) == str 24 | for node in self.root: 25 | if node.tag == nodeTag: return True 26 | return False 27 | 28 | def setAttribute(self, kwargs): 29 | for key in kwargs: 30 | if not key in self.root.keys(): 31 | raise KeyError("%s has No Attribute: <%s>" % (self.root.tag, key)) 32 | 33 | for key in kwargs: 34 | self.root.set(key, kwargs[key]) 35 | 36 | def setDescription(self, Description): 37 | assert type(Description) == str 38 | if self.Desc == None: 39 | self.Desc = etree.SubElement(self.root, 'Description') 40 | self.root.append(self.Desc) 41 | self.Desc.text = etree.CDATA(Description) 42 | 43 | def setParent(self, parent): 44 | pass 45 | 46 | def getLocalRoot(self): 47 | return self.root 48 | 49 | def __str__(self): 50 | return etree.tostring(self.root, pretty_print = True, xml_declaration = True, encoding = "UTF-8", standalone = "yes") 51 | 52 | def writeToFile(self, fileName = os.getcwd() + "/L5X_Printable.L5X"): 53 | tree = etree.ElementTree(self.root) 54 | tree.write(fileName, pretty_print = True, xml_declaration = True, encoding = "UTF-8", standalone = "yes") 55 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Controller.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Controller(Base_Template): 11 | ''' 12 | Controller Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a Controller. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Name, Use = "Context", Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(Name) 21 | self.root = etree.Element('Controller') 22 | if Description != "": 23 | self.Desc = etree.SubElement(self.root, 'Description') 24 | self.setDescription(Description) 25 | self.root.append(self.Desc) 26 | 27 | def addDatatype(self, Datatype): 28 | assert etree.iselement(Datatype.getLocalRoot()) and Datatype.getLocalRoot().tag == "Datatype" 29 | if not self.checkIfChild("Datatypes"): 30 | self.Datatypes = etree.SubElement(self.root, "Datatypes") 31 | self.Datatypes.append(Datatype.getLocalRoot()) 32 | 33 | def addModule(self, Module): 34 | assert etree.iselement(Module.getLocalRoot()) and Module.getLocalRoot().tag == "Module" 35 | if not self.checkIfChild("Modules"): 36 | self.Modules = etree.SubElement(self.root, "Modules") 37 | self.Modules.append(Module.getLocalRoot()) 38 | 39 | 40 | def addAddOnInstructionDefinition(self, AddOnInstructionDefinition): 41 | assert etree.iselement(AddOnInstructionDefinition.getLocalRoot()) and AddOnInstructionDefinition.getLocalRoot().tag == "AddOnInstructionDefinition" 42 | if not self.checkIfChild("AddOnInstructionDefinitions"): 43 | self.AddOnInstructionDefinitions = etree.SubElement(self.root, "AddOnInstructionDefinitions") 44 | self.AddOnInstructionDefinitions.append(AddOnInstructionDefinition.getLocalRoot()) 45 | 46 | def addTag(self, Tag): 47 | assert etree.iselement(Tag.getLocalRoot()) and Tag.getLocalRoot().tag == "Tag" 48 | if not self.checkIfChild("Tags"): 49 | self.Tags = etree.SubElement(self.root, "Tags") 50 | self.Tags.append(Tag.getLocalRoot()) 51 | 52 | def addProgram(self, Program): 53 | assert etree.iselement(Program.getLocalRoot()) and Program.getLocalRoot().tag == "Program" 54 | if not self.checkIfChild("Programs"): 55 | self.Programs = etree.SubElement(self.root, "Programs") 56 | self.Programs.append(Program.getLocalRoot()) 57 | 58 | def addTask(self, Task): 59 | assert etree.iselement(Task.getLocalRoot()) and Task.getLocalRoot().tag == "Task" 60 | if not self.checkIfChild("Tasks"): 61 | self.Tasks = etree.SubElement(self.root, "Tasks") 62 | self.Tasks.append(Task.getLocalRoot()) 63 | 64 | def setParent(self, parent): 65 | assert etree.iselement(parent) and parent.tag == "Members" 66 | parent.append(self.getLocalRoot()) 67 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Datatype.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Datatype(Base_Template): 11 | ''' 12 | UDT Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a datatype. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, TypeName, Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(TypeName) 21 | self.root = etree.Element("Datatype") 22 | self.root.set("Name", TypeName) 23 | self.root.set("Family", "NoFamily") 24 | self.root.set("Class", "User") 25 | if Description != "": 26 | self.Desc = etree.SubElement(self.root, 'Description') 27 | self.setDescription(Description) 28 | self.root.append(self.Desc) 29 | 30 | self.Members = etree.SubElement(self.root, "Members") 31 | 32 | def getMembersRoot(self): 33 | return self.Members 34 | 35 | def addMember(self, member): 36 | self.Members.append(member.getLocalRoot()) 37 | 38 | def setParent(self, parent): 39 | assert etree.iselement(parent) and parent.tag == "DatatTypes" 40 | parent.append(self.root) 41 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Member.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Member(Base_Template): 11 | ''' 12 | Member Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a member. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, TagName, DataType, Hidden = False, Description = "", Radix = "Decimal", ArrayLength = 0, Target = "", BitNumber = 0): 19 | #Initialize Member Attributes 20 | assert isValidTag(TagName) 21 | if DataType == "BOOL": DataType = "BIT" 22 | self.root = etree.Element('Member') 23 | self.root.set("Name", TagName) 24 | self.root.set("Datatype", str(DataType)) 25 | self.root.set("Dimension",str(ArrayLength)) 26 | self.root.set("Radix", Radix) 27 | if DataType == "BIT": 28 | #Reference Rockwell Manuals for Bit Overlays for details on the following assertion. 29 | if Target == "": raise ValueError("Data of Type BOOL Must have a Target: eg. target = 'ZZZZZZZZZZSample0'") 30 | self.root.set("Hidden", "false") 31 | self.root.set("Target", Target) 32 | self.root.set("BitNumber", str(BitNumber)) 33 | elif Hidden == True: 34 | self.root.set("Hidden", "true") 35 | else: 36 | self.root.set("Hidden", "false") 37 | self.root.set("ExternalAccess", "Read/Write") 38 | if Description != "": 39 | self.Desc = etree.SubElement(self.root, 'Description') 40 | self.setDescription(Description) 41 | self.root.append(self.Desc) 42 | 43 | def setParent(self, parent): 44 | assert etree.iselement(parent) and parent.tag == "Members" 45 | parent.append(self.getLocalRoot()) 46 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Program.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Program(Base_Template): 11 | ''' 12 | Program Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a program. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Name, Type = "Normal", Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(Name) 21 | self.root = etree.Element("Program") 22 | self.root.set("Name", Name) 23 | self.root.set("Type", Type) 24 | if Description != "": 25 | self.Desc = etree.SubElement(self.root, 'Description') 26 | self.setDescription(Description) 27 | self.root.append(self.Desc) 28 | 29 | def setMainRoutine(self, RoutineName): 30 | assert type(RoutineName) == str 31 | self.root.set("MainRoutineName", RoutineName) 32 | 33 | def addRoutine(self, Routine): 34 | assert etree.iselement(Routine.getLocalRoot()) and Routine.getLocalRoot().tag == "Routine" 35 | if not self.checkIfChild("Routines"): 36 | self.Routines = etree.SubElement(self.root, "Routines") 37 | self.Routines.append(Routine.getLocalRoot()) 38 | 39 | def addTag(self, Tag): 40 | assert etree.iselement(Tag.getLocalRoot()) and Tag.getLocalRoot().tag == "Tag" 41 | if not self.checkIfChild("Tags"): 42 | self.Tags = etree.SubElement(self.root, "Tags") 43 | self.Tags.append(Tag.getLocalRoot()) 44 | 45 | def setParent(self, parent): 46 | assert etree.iselement(parent) and parent.tag == "Programs" 47 | parent.append(self.root) 48 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Project.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Project(Base_Template): 11 | ''' 12 | Project Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a project. 15 | ---------------------------------------------------------- 16 | This class should always serve as the base class. 17 | ---------------------------------------------------------- 18 | For Information on this see the provided L5X Manual from Rockwell 19 | ''' 20 | def __init__(self, SchemaRevision = "1.0", SoftwareRevision = "30.00"): 21 | #Initialize Member Attributes 22 | self.root = etree.Element("RSLogix5000Content") 23 | self.root.set("SchemaRevision", SchemaRevision) 24 | self.root.set("SoftwareRevision", SoftwareRevision) 25 | 26 | def getControllerRoot(self): 27 | return self.Controller 28 | 29 | def setController(self, Controller): 30 | assert etree.iselement(Controller.getLocalRoot()) and Controller.getLocalRoot().tag == "Controller" 31 | self.root.append(Controller.getLocalRoot()) 32 | 33 | def setAttribute(self, kwargs): 34 | for key in kwargs: 35 | self.root.set(key, kwargs[key]) 36 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Routine.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Routine(Base_Template): 11 | ''' 12 | Routine Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a ladder routine. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Name, Description = ""): 19 | #Initialize Member Attributes 20 | assert isValidTag(Name) 21 | self.root = etree.Element("Routine") 22 | self.root.set("Name", Name) 23 | self.root.set("Type", "RLL") 24 | if Description != "": 25 | self.Desc = etree.SubElement(self.root, 'Description') 26 | self.setDescription(Description) 27 | self.root.append(self.Desc) 28 | 29 | def addRung(self, Rung): 30 | assert etree.iselement(Rung.getLocalRoot()) and Rung.getLocalRoot().tag == "Rung" 31 | if not self.checkIfChild("RLLContent"): 32 | self.RLLContent = etree.SubElement(self.root, "RLLContent") 33 | self.RLLContent.append(Rung.getLocalRoot()) 34 | 35 | def setParent(self, parent): 36 | assert etree.iselement(parent) and parent.tag == "Routines" 37 | parent.append(self.root) 38 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Rung.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Rung(Base_Template): 11 | ''' 12 | Rung Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a ladder rung. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, Number, Comment = "", Content = "NOP();"): 19 | #Initialize Member Attributes 20 | self.root = etree.Element("Rung") 21 | self.root.set("Number", str(Number)) 22 | self.root.set("Type", "N") 23 | if Comment != "": 24 | self.Comment = etree.SubElement(self.root, 'Comment') 25 | self.setComment(Comment) 26 | self.root.append(self.Comment) 27 | 28 | self.rungContent = etree.SubElement(self.root, "Text") 29 | self.setRungContent(Content) 30 | 31 | def setRungContent(self, Content): 32 | assert type(Content) == str 33 | self.rungContent.text = etree.CDATA(Content) 34 | 35 | def setComment(self, Comment): 36 | assert type(Comment) == str 37 | if self.Comment == None: 38 | self.Comment = etree.SubElement(self.root, 'Comment') 39 | self.root.append(self.Comment) 40 | self.Comment.text = etree.CDATA(Comment) 41 | 42 | def setParent(self, parent): 43 | assert etree.iselement(parent) and parent.tag == "RLLContent" 44 | parent.append(self.root) 45 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/Tag.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class Tag(Base_Template): 11 | ''' 12 | Tag Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a Tag. 15 | ---------------------------------------------------------- 16 | For Information on this see the provided L5X Manual from Rockwell 17 | ''' 18 | def __init__(self, TagName, DataType, TagType = "Base", Description = "", UseRadix = True, Radix = "Decimal", Constant = "false", ArrayLength = 0): 19 | #Initialize Member Attributes 20 | assert isValidTag(TagName) 21 | self.root = etree.Element('Tag') 22 | self.root.set("Name", TagName) 23 | self.root.set("TagType", TagType) 24 | self.root.set("Datatype", str(DataType)) 25 | self.root.set("Dimension",str(ArrayLength)) 26 | if UseRadix: self.root.set("Radix", Radix) 27 | self.root.set("ExternalAccess", "Read/Write") 28 | if Description != "": 29 | self.Desc = etree.SubElement(self.root, 'Description') 30 | self.setDescription(Description) 31 | self.root.append(self.Desc) 32 | 33 | def setAsIO(self): 34 | self.root.set("IO","true") 35 | 36 | def addTagComment(self, TagComment): 37 | assert etree.iselement(TagComment.getLocalRoot()) and TagComment.getLocalRoot().tag == "Comment" 38 | if not self.checkIfChild("Comments"): 39 | self.Comments = etree.SubElement(self.root, "Comments") 40 | self.Comments.append(TagComment.getLocalRoot()) 41 | 42 | def setUsage(self, Usage): 43 | assert Usage == "Input" or Usage == "Output" or Usage == "InOut" or Usage == "Public" 44 | self.root.set("Usage", Usage) 45 | 46 | def setAlias(self, TagName): 47 | self.root.set("AliasFor", TagName) 48 | 49 | def setClassAttribute(self, classAttribute): 50 | assert classAttribute == "Standard" or classAttribute == "Safety" 51 | self.root.set("Class", classAttribute) 52 | 53 | def setDescription(self, Description): 54 | assert type(Description) == str 55 | if self.Desc == None: 56 | self.Desc = etree.SubElement(self.root, 'Description') 57 | self.root.append(self.Desc) 58 | self.Desc.text = etree.CDATA(Description) 59 | 60 | def setParent(self, parent): 61 | assert etree.iselement(parent) and parent.tag == "Tags" 62 | parent.append(self.getLocalRoot()) 63 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/TagComment.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | from AB.Rockwell.XML.Tools import * 8 | from Base_Template import Base_Template 9 | 10 | class TagComment(Base_Template): 11 | ''' 12 | Tag Comment Template: 13 | See L5X Manual for Details, 14 | These members are to be used when defining a tag's comment. 15 | ---------------------------------------------------------- 16 | [specifier].[BitNumber] 17 | ---------------------------------------------------------- 18 | For Information on this see the provided L5X Manual from Rockwell 19 | ''' 20 | def __init__(self, Description): 21 | #Initialize Member Attributes 22 | self.root = etree.Element("Comment") 23 | self.root.set("Operand", "Specifier") 24 | setDescription(Description) 25 | self.setDescription(Description) 26 | 27 | def setDescription(self, Description): 28 | assert type(Description) == str 29 | self.root.text = etree.CDATA(Description) 30 | 31 | def setParent(self, parent): 32 | assert etree.iselement(parent) and parent.tag == "Comments" 33 | parent.append(self.getLocalRoot()) 34 | 35 | def getLocalRoot(self): 36 | return self.root 37 | 38 | def __str__(self): 39 | return etree.tostring(self.root, pretty_print = True) 40 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Templates/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["Controller", "Datatype", "Member", "Program", "Project", "Routine", "Rung", "Tag", "TagComment"] 2 | 3 | from Controller import Controller 4 | from Datatype import Datatype 5 | from Member import Member 6 | from Program import Program 7 | from Project import Project 8 | from Routine import Routine 9 | from Rung import Rung 10 | from Tag import Tag 11 | from TagComment import TagComment 12 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/Tools.py: -------------------------------------------------------------------------------- 1 | try: 2 | import lxml 3 | from lxml import etree 4 | except ImportError as e: 5 | print e.message 6 | 7 | 8 | def setAsTarget(template): 9 | try: 10 | template.root.set("use", "Target") 11 | except: 12 | template.set("use", "Target") 13 | 14 | 15 | def setAsContext(template): 16 | try: 17 | template.root.set("use", "Context") 18 | except: 19 | template.set("use", "Context") 20 | 21 | 22 | def isValidTag(TagName): 23 | strCopy = TagName 24 | if "_" in strCopy: 25 | strCopy = strCopy.replace("_", "") 26 | if strCopy[0].isdigit(): 27 | return False 28 | return strCopy.isalnum() 29 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/XML/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["Templates", "Tools"] 2 | -------------------------------------------------------------------------------- /src/build/lib/AB/Rockwell/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["XML", "Types"] 2 | 3 | from AB.Rockwell.Types import CommonType 4 | -------------------------------------------------------------------------------- /src/build/lib/AB/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["Rockwell"] 2 | -------------------------------------------------------------------------------- /src/dist/allen-bradley-toolkit-1.0a1.post0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen-bradley-toolkit-1.0a1.post0.tar.gz -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.0.0-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.0.0-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.0a1.post0-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.0a1.post0-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.0a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.0a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.1a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.1a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.2a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.2a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.3a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.3a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.4a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.4a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.5a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.5a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.6a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.6a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-1.7a1.post1-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-1.7a1.post1-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-2.0.0-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-2.0.0-py3-none-any.whl -------------------------------------------------------------------------------- /src/dist/allen_bradley_toolkit-2.0.1-py2-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmseaton42/Allen-Bradley-Toolkit/bcb974ec627b5cba12f6990fd9c9d9f31740a57d/src/dist/allen_bradley_toolkit-2.0.1-py2-none-any.whl -------------------------------------------------------------------------------- /src/setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | python-tag = py2 3 | # This flag says that the code is written to work on both Python 2 and Python 4 | # 3. If at all possible, it is good practice to do this. If you cannot, you 5 | # will need to generate wheels for each Python version that you support. 6 | -------------------------------------------------------------------------------- /src/setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | A setuptools based setup module. 3 | 4 | See: 5 | https://packaging.python.org/en/latest/distributing.html 6 | https://github.com/pypa/sampleproject 7 | """ 8 | 9 | # Always prefer setuptools over distutils 10 | from setuptools import setup, find_packages 11 | # To use a consistent encoding 12 | from codecs import open 13 | from os import path 14 | 15 | # here = path.abspath(path.dirname(__file__)) 16 | 17 | #To Build run: python setup.py sdist bdist_wheel 18 | #To upload run: twine upload dist/* 19 | 20 | # Get the long description from the README file 21 | # with open(path.join(here, 'Description.txt'), encoding='utf-8') as f: 22 | # long_description = f.read() 23 | 24 | setup( 25 | # Project MetaData 26 | name='allen-bradley-toolkit', 27 | version='2.0.1', 28 | description='Allen-Bradley Python Toolkit', 29 | long_description="TODO: Fill in Later", 30 | url='https://cmseaton42.github.io/Allen-Bradley-Toolkit/', 31 | 32 | # Author Information 33 | author='Canaan Seaton', 34 | author_email='cmseaton42@gmail.com', 35 | 36 | # Licensing 37 | license='MIT', 38 | 39 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 40 | classifiers=[ 41 | 'Development Status :: 3 - Alpha', 42 | 'Intended Audience :: Developers', 43 | 'Topic :: Software Development :: Build Tools', 44 | 'License :: OSI Approved :: MIT License', 45 | 'Programming Language :: Python :: 2.7' 46 | ], 47 | 48 | # Package Specific Data 49 | keywords='PLC Tools XML L5X LXML Rockwell Allen Bradley Allen-Bradley Python Python27', 50 | packages=find_packages(exclude=['Docs', 'tests']), 51 | install_requires=[ 52 | 'lxml>=3.6.0' 53 | ] 54 | ) 55 | --------------------------------------------------------------------------------