Perfect Abstractions
  • Home
  • Contact
  • Blog
  • Home
  • Contact
  • Blog

Ignition Project Development Style Guide

Having a consistent style when developing Ignition projects helps keep developers in agreement on how projects should be developed, facilitates communication and makes projects easier to understand and maintain.

This is the style guide used by Perfect Abstractions Ignition project developers. Others are free to adopt this style guide. Suggestions about changes and additions to this guide are welcome.

Python Scripting

project and shared Python modulesproject and shared Python modules
Write short, clear code. Clarity is most important, then conciseness.
Write code clear enough that comments to describe it aren't needed. When that fails write comments.

Generally the DRY (Don't Repeat Yourself) principle applies. Write functions and custom methods to avoid duplicate code.

Use Python script library modules, such as project and shared modules to share data and functionality between Ignition windows and other parts of Ignition.

Avoid creating and using shared Python modules unless the functionality will be shared among multiple projects.

Python scripting and logic that only applies to a particular window should stay in that window. Write custom methods on the root container of a window or other applicable component when the logic only applies to that particular window. Do not create a Python module for code that is used by only one window. The exception to this rule is when code is long and/or complex enough that a Python module would really help.

Module level Python variables should be private. Module level variables are variables created in a Python module outside any function or class. Module variables are also called global variables. Functions and classes can access module variables defined in the same module directly. Any access to module level variables outside the module where they are created should be done via function calls. For example a function call like "project.machine.getMachineInfo(33)" should be used instead of directly accessing the variable like "project.machine.machines[33]", when the code is not in the same script or module where "machines" is created.

Windows that can be opened in multiple points in a project should have their window path defined in a Python module and a function call should be used to retrieve the window path for such a window. This makes a window path defined in one place in a project so that if the window path or name ever changes, the window path used by code would only need to change in one place.

Python packages can be used to group and separate Python functionality and logic. Example: project.machines.nav.openOverview().

Python Function & Variable Names

PicturePython variable and function naming example
Function names should be short but descriptive. If a function name needs to be longer to be descriptive then it should be longer. Same applies to variables but less strictly.

Python variable and function names should be lower camel case. This means each word in a name should start with a capital letter except the first word. Examples: machineName, firstLetterInWord. Letters that are part of an abbreviation can be all uppercase, for example: machineID.

Custom methods on components in windows should be lower camel case.

Custom properties and template parameters on templates and components in Ignition windows should be lower camel case.

Functions defined in Python modules, such as project or shared modules, that are meant to be private (not used outside the module) should have one leading underscore in their names. For example: _myPrivateFunction. Functions meant to be used outside the module they are defined in should have no leading underscore. This convention makes it easy to see which functions in a module are meant to be called outside the module and which are internal to the module.

Classes should be upper camel case, meaning each word in a name should start with a capital letter, including the first word.

Python package and module names should be lowercase.

Project Organization

When many windows exist use folders to group them by subject or functionality. When many templates exist use folders to group them by subject or functionality. When many Python modules exist use packages to group them by subject or functionality. When many components exist in a window use containers to group them by subject or functionality. When many items of some kind exist, group them by subject or functionality.

Give descriptive names to components in a window when it will help make the window easier to understand and work with.

When customizing an Ignition component consider making it a template if it will be used in multiple places.

Database Conventions

Database table names should be all lowercase. Only use underscores in database table name prefixes and only use prefixes when database tables need to be grouped and separated from other database tables. Example: specialstorage_firsttags, specialstorage_users. Database table names should be plural. Column names should be singular. Column names should use upper camel case, and abbreviations can be capitalized, for example: CustomerOrderID.

Avoid using keywords and reserved words in database table and column names.

In database queries SQL syntax/keywords should be in all upper case. Example: SELECT u.FirstName FROM users u WHERE u.ID=20

Use an auto-incrementing integer primary key column named ID for each database table. Foreign keys should have the singular name of their referenced table plus "ID". Example: UserID, MachineID.

SQL queries in Python that can fit easily in a single line can use regular string quotes. Example: query = "SELECT * FROM users"
Long SQL queries in Python should be put in multiple lines and use triple quotes. Example:
query = """
    SELECT
            r.FirstName, r.LastName, r.Age, r.Rank, r.Address, r.Phone, r.Height, r.Weight, r.DateOfBirth, r.School,
            r.WorkLocation, r.Employer, r.FavoriteColor, r.FavoriteMovie
    FROM
            users u
    JOIN
            relatives r ON r.ID=u.RelativeID
    WHERE
            u.ID=?
            """
               
Long SQL queries in SQL bindings and Python code should use multiple lines and be indented for easy reading.

Which Database Functions to Use?

Favor the use of the prepared statement database functions such as "system.db.runPrepQuery", "system.db.runPrepUpdate", "system.db.runScalarPrepQuery". These functions prevent queries from accidentally getting messed up from user input and other sources.

Library Usage

When choosing a library to use for a task, you should first look for a built in "system" library that is built-in to Ignition. If a built-in library doesn't exist for what you need then you should look for a library in Python's standard library or Java's standard library. The order you should look is as follows:
  1. Built-in "system" Ignition library.
  2. Python's standard library or Java's standard library.
  3. External 3rd part Python or Java library or an Ignition module that provides libraries.
Some Ignition modules provide libraries that enable new functionality or make things easier to do. Those should be considered. Here are some of them:
  1. PA Power Scripting Module
  2. Kymera Office Document Module
  3. Time Series Database Cache
  4. PA Office Document Module
  5. Simulation Aids
© Perfect Abstractions LLC