<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ignition Archives | DMC, Inc.</title>
	<atom:link href="https://static.dmcinfo.com/blog/tag/ignition/feed/index.xml" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Fri, 04 Sep 2026 18:38:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://static.dmcinfo.com/wp-content/uploads/2025/04/site-icon-150x150.png</url>
	<title>ignition Archives | DMC, Inc.</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Ignition Tricks: Improving Exception Handling and Error Logging</title>
		<link>https://static.dmcinfo.com/blog/44984/ignition-exception-handling/</link>
		
		<dc:creator><![CDATA[Isabelle Chan]]></dc:creator>
		<pubDate>Mon, 15 Jun 2026 11:00:00 +0000</pubDate>
				<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[ignition]]></category>
		<category><![CDATA[Ignition 8.3]]></category>
		<category><![CDATA[Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=44984</guid>

					<description><![CDATA[<p>What Are Exceptions in Ignition and Why Should I Care? Exceptions are unexpected events that a program cannot take care of on its own, and stop the program from executing. Exceptions can be caused by a wide range of factors, leaving the user wondering why the system isn’t working when improperly managed. When an exception [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/44984/ignition-exception-handling/">Ignition Tricks: Improving Exception Handling and Error Logging</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="h-what-are-exceptions-in-ignition-and-why-should-i-care">What Are Exceptions in Ignition and Why Should I Care?</h2>



<p class="wp-block-paragraph">Exceptions are unexpected events that a program cannot take care of on its own, and stop the program from executing. Exceptions can be caused by a wide range of factors, leaving the user wondering why the system isn’t working when improperly managed.</p>



<p class="wp-block-paragraph">When an exception occurs, the event details are laid out in an exception object, which can be used to better handle the event. By learning to use these details and handle exceptions, developers can write more robust functions, provide useful error messages when things go wrong, and flag conditions that could cause problems downstream.</p>



<h2 class="wp-block-heading">How to Approach Exception Handling</h2>



<p class="wp-block-paragraph">When handling exceptions, DMC encourages engineers and programmers to stick by these three guidelines:</p>



<ol class="wp-block-list">
<li>Let the code fail but rewrite the error message so that it is more helpful.</li>



<li>Use the DMC pop-up library to display exceptions as errors to the users.</li>



<li>Set up the code so that the system handles known and unknown errors consistently.</li>
</ol>



<h2 class="wp-block-heading" id="h-handling-exceptions">Handling Exceptions</h2>



<p class="wp-block-paragraph">Exceptions are handled by wrapping error-prone code in a <code>try/except</code> block. There are several types of except statements that can accomplish different things.</p>



<p class="wp-block-paragraph">Because Ignition uses Jython, a Java implementation of Python, it is also important to handle Java <code>exception</code> types where applicable.</p>



<h3 class="wp-block-heading">Understanding Python Syntax for Exception Handling</h3>



<p class="wp-block-paragraph">In Python, there are four main keywords for handling exceptions:</p>



<ul class="wp-block-list">
<li><strong>Try: </strong>contains error-prone code</li>



<li><strong>Except: </strong>catches and handles errors if they occur</li>



<li><strong>Else: </strong>runs if the try block completes successfully</li>



<li><strong>Finally:</strong> always runs, regardless of what occurs earlier</li>
</ul>



<p class="wp-block-paragraph">The core of exception handling occurs in the <code>try</code> and <code>except</code> statements, so we will focus on those in the following examples.</p>



<h3 class="wp-block-heading">Basic Exception</h3>



<p class="wp-block-paragraph">This example uses the most basic implementation of a <code>try/except</code> statement. You know that an error occurred, but you don’t know anything about the error. Not very useful.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Python</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>try:
  output = dividend / divisor
  success = True
except:
  success = False
  errorMessage = 'An error occurred while dividing'</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  output = dividend / divisor</span></span>
<span class="line"><span style="color: #D4D4D4">  success = </span><span style="color: #569CD6">True</span></span>
<span class="line"><span style="color: #C586C0">except</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  success = </span><span style="color: #569CD6">False</span></span>
<span class="line"><span style="color: #D4D4D4">  errorMessage = </span><span style="color: #CE9178">&apos;An error occurred while dividing&apos;</span></span></code></pre></div>



<h3 class="wp-block-heading">Catch Python Exceptions</h3>



<p class="wp-block-paragraph">You can include the base exception type in the syntax to get the error message or filter for specific error types. It is best practice to look out for specific exception types. In the example below, we catch the <code>ZeroDivisionError</code> type and rewrite the error message so it is more human-readable. Notice how you can include multiple <code>except</code> statements! This way, you can filter for known exceptions and still catch others that may occur during execution of the code.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Python</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>try:
  output = dividend / divisor
except ZeroDivisionError as e:
  errorMessage = 'Cannot divide by zero: {}'.format(e.message)
except Exception as e:
  errorMessage = 'Division error: {}'.format(e.message)</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  output = dividend / divisor</span></span>
<span class="line"><span style="color: #C586C0">except</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ZeroDivisionError</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> e:</span></span>
<span class="line"><span style="color: #D4D4D4">  errorMessage = </span><span style="color: #CE9178">&apos;Cannot divide by zero: </span><span style="color: #569CD6">{}</span><span style="color: #CE9178">&apos;</span><span style="color: #D4D4D4">.format(e.message)</span></span>
<span class="line"><span style="color: #C586C0">except</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Exception</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> e:</span></span>
<span class="line"><span style="color: #D4D4D4">  errorMessage = </span><span style="color: #CE9178">&apos;Division error: </span><span style="color: #569CD6">{}</span><span style="color: #CE9178">&apos;</span><span style="color: #D4D4D4">.format(e.message)</span></span></code></pre></div>



<h3 class="wp-block-heading">Catch Python and Java Exceptions</h3>



<p class="wp-block-paragraph">Because Ignition uses Jython, a Java implementation of Python, we should also handle Java exception types that might occur during queries, casting, or other scenarios.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Python</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>import java.lang.Exception as JavaException

try:
  output = dividend / divisor
except (Exception, JavaException) as e:
  errorMessage = 'Division error: {}'.format(e.message)  </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> java.lang.Exception </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> JavaException</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  output = dividend / divisor</span></span>
<span class="line"><span style="color: #C586C0">except</span><span style="color: #D4D4D4"> (</span><span style="color: #4EC9B0">Exception</span><span style="color: #D4D4D4">, JavaException) </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> e:</span></span>
<span class="line"><span style="color: #D4D4D4">  errorMessage = </span><span style="color: #CE9178">&apos;Division error: </span><span style="color: #569CD6">{}</span><span style="color: #CE9178">&apos;</span><span style="color: #D4D4D4">.format(e.message)  </span></span></code></pre></div>



<h2 class="wp-block-heading">Displaying and Logging Exceptions</h2>



<h3 class="wp-block-heading">Displaying</h3>



<p class="wp-block-paragraph">DMC’s pop-up library includes functions for automatically displaying exception message pop-ups in Perspective without requiring the declaration of a specific exception type. The pop-ups in this library can display simplified and detailed versions of the error, providing both user-friendly and developer-friendly messages.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Python</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>import traceback
logger = system.util.getLogger('Test Function')

try:
  myFunction(inputA,inputB,inputC)
except Exception as e:
  logger.error(traceback.format_exc(e))
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> traceback</span></span>
<span class="line"><span style="color: #D4D4D4">logger = system.util.getLogger(</span><span style="color: #CE9178">&apos;Test Function&apos;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  myFunction(inputA,inputB,inputC)</span></span>
<span class="line"><span style="color: #C586C0">except</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Exception</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> e:</span></span>
<span class="line"><span style="color: #D4D4D4">  logger.error(traceback.format_exc(e))</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Logging</h3>



<p class="wp-block-paragraph">In addition to displaying the exception to users, exceptions should also be logged to the gateway to maintain a record of such events. Without logging, a user can close the exception pop-up, and all information associated with the event will be lost.</p>



<p class="wp-block-paragraph">Logging with <code>traceback.format_exc(e)</code> creates a well-formatted message with error type, message, and traceback, giving engineers the information they need to debug issues effectively.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Python</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from traceback import format_exc

try:
    1/0
except Exception as e:
    print type(e).__name__
    print ''
    print e.message
    print ''
    print format_exc(e)
    
>>> 
ZeroDivisionError

integer division or modulo by zero

Traceback (most recent call last):
  File "&lt;input>", line 4, in &lt;module>
ZeroDivisionError: integer division or modulo by zero

>>> </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">from</span><span style="color: #D4D4D4"> traceback </span><span style="color: #C586C0">import</span><span style="color: #D4D4D4"> format_exc</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">/</span><span style="color: #B5CEA8">0</span></span>
<span class="line"><span style="color: #C586C0">except</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Exception</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> e:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">type</span><span style="color: #D4D4D4">(e).</span><span style="color: #9CDCFE">__name__</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&apos;&apos;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4"> e.message</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&apos;&apos;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">print</span><span style="color: #D4D4D4"> format_exc(e)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span></span>
<span class="line"><span style="color: #D4D4D4">&gt;&gt;&gt; </span></span>
<span class="line"><span style="color: #4EC9B0">ZeroDivisionError</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">integer division </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> modulo by zero</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">Traceback (most recent call last):</span></span>
<span class="line"><span style="color: #D4D4D4">  File </span><span style="color: #CE9178">&quot;&lt;input&gt;&quot;</span><span style="color: #D4D4D4">, line </span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">in</span><span style="color: #D4D4D4"> &lt;module&gt;</span></span>
<span class="line"><span style="color: #4EC9B0">ZeroDivisionError</span><span style="color: #D4D4D4">: integer division </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> modulo by zero</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">&gt;&gt;&gt; </span></span></code></pre></div>



<h2 class="wp-block-heading">Other Exceptions</h2>



<p class="wp-block-paragraph">You can raise your own Exceptions to catch errors that might not violate Python syntax by themselves. This is useful for sanitizing inputs or generally checking statuses before they cause errors later in program execution. You can also reraise within an Except block to add more context to an error message.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">Python</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>def divideNumbers(dividend, divisor):
  if divisor == 0:
    raise ValueError('Cannot divide by 0')
    
  try:
    output = dividend / divisor
  except Exception as e:
    raise Exception('Division error: {}'.format(e.message))
    
  return output</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">def</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">divideNumbers</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">dividend</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">divisor</span><span style="color: #D4D4D4">):</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> divisor == </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">raise</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ValueError</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&apos;Cannot divide by 0&apos;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">    </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">try</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    output = dividend / divisor</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">except</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Exception</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">as</span><span style="color: #D4D4D4"> e:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">raise</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Exception</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&apos;Division error: </span><span style="color: #569CD6">{}</span><span style="color: #CE9178">&apos;</span><span style="color: #D4D4D4">.format(e.message))</span></span>
<span class="line"><span style="color: #D4D4D4">    </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">return</span><span style="color: #D4D4D4"> output</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Exceptions</h3>



<p class="wp-block-paragraph">When considering SQL exceptions, we first want to examine the query method. Where possible, we want to use named queries instead of prep queries because named queries provide much better error messages.</p>



<h3 class="wp-block-heading">Custom Exception Classes</h3>



<p class="wp-block-paragraph">Creating custom exception classes is incredibly easy to accomplish in Python. You might want to create separate exception types for user input errors and system errors.</p>



<h2 class="wp-block-heading" id="h-conclusion">Conclusion</h2>



<p class="wp-block-paragraph">By moving beyond basic <code>try/except</code> usage and adopting a more structured approach, like catching specific exception types, handling both Python and Java errors in Ignition, and logging details, you can turn unexpected errors into actionable insights.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--50)">At DMC, we always apply these best practices across our automation and software projects to deliver systems that are robust, user-friendly, and scalable. Whether you’re building a new Ignition application or improving existing systems, stronger exception handling helps ensure greater dependability and performance.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Kicking off an automation project? DMC can help you take the next step!</strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Discover more about <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming/">Ignition solutions</a> and <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming/">HMI Programming services</a> with DMC and contact an expert today.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/44984/ignition-exception-handling/">Ignition Tricks: Improving Exception Handling and Error Logging</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Setting Up Symbolic Links for Shared Project Libraries Across Ignition 8.3 Gateways</title>
		<link>https://static.dmcinfo.com/blog/44390/symbolic-links-shared-ignition-project-libraries/</link>
		
		<dc:creator><![CDATA[Wenjing Deng]]></dc:creator>
		<pubDate>Fri, 15 May 2026 11:00:00 +0000</pubDate>
				<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[GIT]]></category>
		<category><![CDATA[ignition]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[Workflows]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=44390</guid>

					<description><![CDATA[<p>Ignition 8.3’s file-based project structure makes it practical to treat gateway resources as standard source-controlled assets, allowing teams to track changes in Git, review diffs, and modify certain files directly outside of the Designer when needed. This level of transparency and control significantly improves the development workflow. In a recent Ignition 8.3 project, we had [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/44390/symbolic-links-shared-ignition-project-libraries/">Setting Up Symbolic Links for Shared Project Libraries Across Ignition 8.3 Gateways</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Ignition 8.3’s file-based project structure makes it practical to treat gateway resources as standard source-controlled assets, allowing teams to track changes in Git, review diffs, and modify certain files directly outside of the Designer when needed. This level of transparency and control significantly improves the development workflow.</p>



<p class="wp-block-paragraph">In a recent Ignition 8.3 project, we had two gateways in a single Git repository that needed to share library elements. While 8.3 enables a more Git-centric workflow, it does not provide a built-in mechanism to keep shared resources synchronized across multiple gateways. Without an automatic way to manage this, shared libraries can quickly drift and become difficult to maintain.</p>



<p class="wp-block-paragraph">We addressed this by creating symbolic links from each gateway’s library folders to a shared “source of truth” directory. A <strong>symbolic link</strong> (symlink) is a special file that points to another file or folder—like a shortcut at the filesystem level. When you access it, the system transparently redirects you to the target location. This approach allows both gateways to reference the same underlying files while still fitting cleanly into a Git-based workflow, making it a simple, low-friction way to keep shared resources consistent.</p>



<p class="wp-block-paragraph">This blog walks through how to set up shared libraries between two Ignition gateways in a single Git repository using symlinks on Windows, helping you avoid duplication and keep shared code synchronized in one place.</p>



<p class="wp-block-paragraph">With this setup, any time a symlinked file is modified in a Designer and saved, it’s immediately overwritten in the shared “source of truth” location. After changes are made and tested in one gateway project’s Designer, the files can be committed and pushed to the repo as usual.</p>



<p class="wp-block-paragraph">We’ll walk through setting up a shared script library folder as an example. You can use the same pattern to share views, styles, and additional files as needed for your project.</p>



<h2 class="wp-block-heading" id="h-what-are-symbolic-links">What are Symbolic Links?</h2>



<p class="wp-block-paragraph">A symbolic link, often referred to as a <strong>symlink</strong>, is a reference point in a filesystem that points one file or folder to another location. Instead of duplicating the files, a symlink acts as a pointer. When an application accesses the symlinked path, the operating system (OS) redirects it to the target destination.</p>



<p class="wp-block-paragraph">In Ignition 8.3, a symlinked folder behaves exactly like a project directory. Associated scripts, views, and resources load as one would expect; however, the actual files live somewhere else in the filesystem.</p>



<h2 class="wp-block-heading" id="h-sample-repository-structure">Sample Repository Structure</h2>



<p class="wp-block-paragraph">Here is a visual representation of what the structure would look like after the symlinks are set up. The file structure for <strong>gateway1</strong> and <strong>gateway2</strong> down to script-python is default to ignition. You will have to create the “shared” folder location and structure manually in your repo, and you can organize it anyway you want.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--50)"><strong>repo/<br>└── gateways/<br>&nbsp; &nbsp;├── shared/<br>&nbsp; &nbsp;│ &nbsp; └── script-python/<br>&nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; └── library/ (real files live here for this example)<br>&nbsp; &nbsp;│<br>&nbsp; &nbsp;├── gateway1/<br>&nbsp; &nbsp;│ &nbsp; └── projects/<br>&nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; └── project1/<br>&nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; └── ignition/<br>&nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; └── script-python/<br>&nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; └── library/ -&gt; symlink to ../../../../../shared/script-python/library<br>&nbsp; &nbsp;│<br>&nbsp; &nbsp;└── gateway2/<br>&nbsp; &nbsp; &nbsp; &nbsp;└── projects/<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;└── project2/<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;└── ignition/<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;└── script-python/<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;└── library/ -&gt; symlink to ../../../../../shared/script-python/library</strong></p>



<h2 class="wp-block-heading" id="h-setup-steps-for-windows">Setup Steps for Windows</h2>



<p class="wp-block-paragraph">Before creating any symbolic links, complete the following one-time setup steps. <strong>Every developer working with this repository must perform these steps on their local machine</strong>. Skipping them can result in broken links when the repo is cloned or checked out.</p>



<h3 class="wp-block-heading" id="h-prerequisites">Prerequisites</h3>



<p class="wp-block-paragraph"><strong>1. Enable Git symlink support</strong></p>



<p class="wp-block-paragraph">By default, Git on Windows may treat symlinks as plain text files. This setting ensures symlinks are created and checked out correctly.</p>



<p class="wp-block-paragraph">Run the following command in <strong>Git Bash</strong>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>git config --global core.symlinks true</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">git config --global core.symlinks </span><span style="color: #569CD6">true</span></span></code></pre></div>



<figure class="wp-block-image aligncenter size-full has-custom-border"><img fetchpriority="high" decoding="async" width="1082" height="209" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-1.png" alt="Open command window with Git command to enable the use of symbolic links across all repositories on a machine." class="wp-image-44460" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-1.png 1082w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-1-300x58.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-1-1024x198.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-1-768x148.png 768w" sizes="(max-width: 1082px) 100vw, 1082px" /></figure>



<p class="wp-block-paragraph"><strong>2. Enable Windows Developer Mode</strong></p>



<p class="wp-block-paragraph">Developer Mode<strong> </strong>allows non-admin users to create symbolic links without permission-related issues.</p>



<p class="wp-block-paragraph"><strong>Settings &gt; Privacy &amp; Security &gt; For Developers &gt; Developer Mode</strong></p>



<p class="wp-block-paragraph">Turn Developer Mode <strong>on</strong>.</p>



<p class="wp-block-paragraph"><strong>3. Restart your computer</strong></p>



<p class="wp-block-paragraph">Restarting your computer ensures Developer Mode is fully applied before creating symlinks.</p>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="624" height="387" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-2.png" alt="Advanced system settings in Windows, specifically highlighting options for developers and terminal management." class="wp-image-44414" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:1.6124476361460203;width:624px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-2.png 624w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-2-300x186.png 300w" sizes="(max-width: 624px) 100vw, 624px" /></figure>



<h2 class="wp-block-heading" id="h-initial-creation-of-symbolic-links">Initial Creation of Symbolic Links</h2>



<p class="wp-block-paragraph">Follow the steps below to set up the initial symlinks for the <code>script-python</code> library folder in our example. The same approach can be used for other shared resources.</p>



<h3 class="wp-block-heading" id="h-gateway-1"><strong>Gateway 1:</strong></h3>



<p class="wp-block-paragraph"><strong>1. Open Command Prompt as an Administrator</strong></p>



<p class="wp-block-paragraph"><strong>2. Navigate to the target directory for your symbolic links</strong></p>



<p class="wp-block-paragraph" style="padding-top:0;padding-bottom:var(--wp--preset--spacing--40)">Move to the directory where the symlink will live in <strong>Gateway 1</strong>: <em><strong>cd gateways\gateway1\projects\project1\ignition\script-python</strong></em></p>



<figure class="wp-block-image aligncenter size-large is-resized has-custom-border" style="margin-top:0;margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="1024" height="129" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-3-1024x129.png" alt="Administrator: Command Prompt window active in a specific directory path." class="wp-image-44417" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:7.9392168322618355;object-fit:cover;width:691px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-3-1024x129.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-3-300x38.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-3-768x97.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-3.png 1444w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph" style="padding-top:0;padding-bottom:var(--wp--preset--spacing--40)"><strong>3. Move any existing library files:</strong></p>



<p class="wp-block-paragraph" style="padding-top:0;padding-bottom:var(--wp--preset--spacing--40)">If you already have files in the library folder and/or the library folder exists, move the entire library folder to the shared directory<span style="box-sizing: border-box; margin: 0px; padding: 0px;">&nbsp;at&nbsp;<em><strong>gateways/shared/script-python</strong></em></span>. If not, skip this step.</p>



<p class="wp-block-paragraph" style="padding-top:0;padding-bottom:var(--wp--preset--spacing--40)">If you leave the library folder here: <em><strong>\gateways\gateway1\projects\project1\ignition\script-python</strong>. </em>The following error will occur because Windows cannot create a link where a directory already exists:</p>



<figure class="wp-block-image aligncenter size-full has-custom-border" style="margin-top:0;margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="2306" height="161" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4.png" alt="The error message &quot;Cannot create a file when that file already exists&quot; indicates that a symbolic link or file named library already exists in the destination directory." class="wp-image-44419" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:14.424507658643327" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4.png 2306w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4-300x21.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4-1024x71.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4-768x54.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4-1536x107.png 1536w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-4-2048x143.png 2048w" sizes="(max-width: 2306px) 100vw, 2306px" /></figure>



<p class="wp-block-paragraph" style="padding-top:0;padding-bottom:var(--wp--preset--spacing--40)"><strong>4. Create the symbolic link</strong></p>



<p class="wp-block-paragraph" style="padding-top:0;padding-bottom:0">Run the command below to create the symlink linked to the actual files in the shared location:</p>



<p class="wp-block-paragraph"><em><strong>mklink /D library &#8230;&#8230;&#8230;.\shared\script-python\library</strong></em></p>



<figure class="wp-block-image aligncenter size-full has-custom-border" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="2325" height="293" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5.png" alt="GIT command used to successfully create a symbolic link to a folder." class="wp-image-44421" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5.png 2325w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5-300x38.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5-1024x129.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5-768x97.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5-1536x194.png 1536w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-5-2048x258.png 2048w" sizes="(max-width: 2325px) 100vw, 2325px" /></figure>



<p class="wp-block-paragraph"><strong>5. Verify the symlink was created successfully</strong></p>



<p class="wp-block-paragraph">Verify the link has been created by running the command <em>dir</em> at the symlink location in the command prompt. If the symlink was created correctly, then you should see it in your output.</p>



<figure class="wp-block-image aligncenter size-full has-custom-border" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="1950" height="499" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-6-1-e1778267616906.png" alt="A [dir] command output shows a directory listing in a Windows Command Prompt, highlighting a symbolic link." class="wp-image-44422" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-6-1-e1778267616906.png 1950w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-6-1-e1778267616906-300x77.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-6-1-e1778267616906-1024x262.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-6-1-e1778267616906-768x197.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-6-1-e1778267616906-1536x393.png 1536w" sizes="(max-width: 1950px) 100vw, 1950px" /></figure>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--40)">In addition, you can visually verify that the folder was created correctly in File Explorer by looking for the arrow icon in the bottom left. When you double-click into this symlinked folder, it will take you to the location it is linked to.</p>



<figure class="wp-block-image aligncenter size-full has-custom-border" style="margin-top:var(--wp--preset--spacing--30);margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="650" height="271" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/Picture12.png" alt="Windows 11 File Explorer window for a directory named script-python." class="wp-image-44431" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/Picture12.png 650w, https://static.dmcinfo.com/wp-content/uploads/2026/05/Picture12-300x125.png 300w" sizes="(max-width: 650px) 100vw, 650px" /></figure>



<h3 class="wp-block-heading" id="h-gateway-2">Gateway 2</h3>



<p class="wp-block-paragraph">Repeat the same steps for <strong>Gateway 2</strong>, adjusting the path as needed:</p>



<p class="wp-block-paragraph"><em><strong>cd gateways\gateway2\projects\project2\ignition\script-python</strong></em></p>



<p class="wp-block-paragraph">Create the symlink pointing to the same library location.</p>



<p class="wp-block-paragraph">Once both gateways are linked, the shared library folder is ready for use. Any changes made through one gateway’s <strong>Ignition Designer</strong> will be written directly to the shared directory and can be committed to Git as usual.</p>



<h2 class="wp-block-heading" id="h-ignition-designer-gateway-refresh-and-test">Ignition Designer/Gateway Refresh and Test</h2>



<p class="wp-block-paragraph">After creating the symbolic links, the final step is to confirm that Ignition detects and uses the shared files properly. Because Ignition doesn’t automatically reload filesystem changes, users must manually initiate file and project scans to update each gateway.</p>



<p class="wp-block-paragraph"><strong>1. Close all open Ignition Designer sessions</strong></p>



<p class="wp-block-paragraph">Closing active sessions of Designer resolves any potential validation interference caused by cached projects.</p>



<p class="wp-block-paragraph"><strong>2. Trigger file and project scans on both Gateways</strong></p>



<p class="wp-block-paragraph">On each gateway, run the following:</p>



<ul class="wp-block-list">
<li>Platform → Overview →<strong> Scan File System</strong></li>



<li>Platform → System → Projects → <strong>Scan Projects</strong></li>
</ul>



<p class="wp-block-paragraph"><strong>3. Open Ignition Designer for Gateway 1</strong></p>



<ul class="wp-block-list">
<li>Create a new script or modify an existing script in the share library.</li>



<li>Save the changes.</li>
</ul>



<p class="wp-block-paragraph"><strong>4. Refresh Gateway 2</strong></p>



<ul class="wp-block-list">
<li style="padding-bottom:var(--wp--preset--spacing--40)">From the <strong>Gateway 2</strong> web UI, trigger both the file system scan and project scan again.</li>
</ul>



<p class="wp-block-paragraph"><strong>5. Open Ignition Developer for Gateway 2</strong></p>



<ul class="wp-block-list">
<li style="padding-bottom:var(--wp--preset--spacing--40)">Open Ignition Developer for the second Gateway and verify that the adjustments are present.</li>
</ul>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="1124" height="218" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-8.png" alt="Platform File Scan button in Ignition 8.3" class="has-border-color has-custom-light-gray-neutral-2-border-color wp-image-44424" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;width:1200px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-8.png 1124w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-8-300x58.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-8-1024x199.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-8-768x149.png 768w" sizes="(max-width: 1124px) 100vw, 1124px" /><figcaption class="wp-element-caption">Platform File Scan Button</figcaption></figure>



<figure class="wp-block-image aligncenter size-full is-resized has-custom-border"><img decoding="async" width="1128" height="265" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-9.png" alt="Project File Scan button in Ignition 8.3" class="has-border-color has-custom-light-gray-neutral-2-border-color wp-image-44426" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;width:1200px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-9.png 1128w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-9-300x70.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-9-1024x241.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/ignition-8.3-symlinks-image-9-768x180.png 768w" sizes="(max-width: 1128px) 100vw, 1128px" /><figcaption class="wp-element-caption">Project File Scan Button</figcaption></figure>



<p class="wp-block-paragraph">Now the library symlinks are set up and ready for use. If the changes appear as expected, the symbolic link configuration is working correctly, and both gateways are pulling from the same shared source of truth. Once validated, follow your project&#8217;s specific git workflow to push these changes to your repository.</p>



<h2 class="wp-block-heading" id="h-final-thoughts-and-best-practices">Final Thoughts and Best Practices</h2>



<p class="wp-block-paragraph">It&#8217;s important to keep in mind that whenever a file in the gateway filesystem is changed, the gateway doesn’t automatically update to reflect those changes. You will need to perform two file scans for the latest changes to be reflected. The screenshots below show where to trigger these scans.</p>



<p class="wp-block-paragraph">At some point during testing, you may need to view/test a library file in both gateways. In this scenario, it is important to regularly perform the above file and project scans, as changes are being made and saved. Below is an example of a possible order of operations:</p>



<ol class="wp-block-list">
<li>Make changes to library file in <strong>Gateway 1</strong> project designer.</li>



<li>Save changes to library file in <strong>Gateway 1</strong> project designer.</li>



<li>Open <strong>Gateway 2</strong> webpage UI.</li>



<li>Press <strong>Scan File System</strong> on both <strong>Platform</strong> <strong>&gt; Overview</strong> page and <strong>Platform &gt; System &gt; Projects</strong> page for <strong>Gateway 2</strong>.</li>



<li>Open a fresh designer session of <strong>Gateway 2’s</strong> project to view latest changes.</li>
</ol>



<p class="wp-block-paragraph">Keep in mind that if changes are made in both gateways to the same library object, the last place it was saved will be the effective, latest state of the file. In the above example, if a change is made in <strong>Gateway 2’s</strong> project designer session and saved there, <strong>Gateway 1</strong> would have stale library files internally, requiring file scans to refresh them.</p>



<p class="wp-block-paragraph">To avoid accidentally overwriting changes, the best practice is to separate work into separate commits and modify a given shared file from only one gateway at a time.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--40)">Finally, make sure the other developers run through the setup steps on their machines to avoid accidentally breaking any symbolic links during initial setup.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step">Planning your next automation project? DMC can help you take the next step.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Get expert <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/">Automation</a> engineering and <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming/">Ignition Programming</a> solutions from DMC. Talk with an Ignition expert today.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/44390/symbolic-links-shared-ignition-project-libraries/">Setting Up Symbolic Links for Shared Project Libraries Across Ignition 8.3 Gateways</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Getting Started with the Paintable Canvas in Ignition Vision</title>
		<link>https://static.dmcinfo.com/blog/16140/getting-started-with-the-paintable-canvas-in-ignition-vision/</link>
		
		<dc:creator><![CDATA[Natalie Pippolo]]></dc:creator>
		<pubDate>Mon, 15 Jul 2024 15:01:02 +0000</pubDate>
				<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[ignition]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/16140/getting-started-with-the-paintable-canvas-in-ignition-vision/</guid>

					<description><![CDATA[<p>Inductive Automation’s Ignition is a reliable, proven HMI/SCADA platform with powerful scripting capabilities. Ignition’s most well-known Vision visualization module has been used in plant floor HMIs and desktop screens for over 10 years. One of the most customizable components in Vision’s palette is the Paintable Canvas. While the Paintable Canvas’s heavy reliance on scripting might [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/16140/getting-started-with-the-paintable-canvas-in-ignition-vision/">Getting Started with the Paintable Canvas in Ignition Vision</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Inductive Automation’s <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming">Ignition</a> is a reliable, proven HMI/SCADA platform with powerful scripting capabilities. Ignition’s most well-known Vision visualization module has been used in plant floor HMIs and desktop screens for over 10 years. One of the most customizable components in Vision’s palette is the Paintable Canvas.</p>



<p class="wp-block-paragraph">While the Paintable Canvas’s heavy reliance on scripting might be intimidating for a new Ignition developer, this short tutorial will put you on track to create complex dynamic displays in no time!</p>



<h2 id="h-paintable-canvas-overview" class="wp-block-heading">Paintable Canvas Overview</h2>



<p class="wp-block-paragraph">The Paintable canvas makes use of the <a href="https://docs.oracle.com/javase/tutorial/2d/index.html" target="_blank">Java2D graphics library</a>, which allows you to create complex shapes, load and edit images, add text, and more.</p>



<p class="wp-block-paragraph">To add a paintable canvas to your Vision project, simply drag the Paintable Canvas component anywhere on your window. You’ll notice that this component comes with an example script that renders a simple pump graphic. Turn on preview mode to see your paintable canvas area filled with the pump image below. Notice that you can resize the canvas window to any shape or size and the pump will automatically stretch to fill the new area. This is because Java2D is a vector drawing library, allowing components to scale with ease.</p>



<p class="wp-block-paragraph">&nbsp;</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Now, let&#8217;s take a look into how this graphic is being created. Open up the script editor by right-clicking on your paintable canvas component in the project browser.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas4.png" alt="Graphical user interface, applicationDescription automatically generated"/></figure>



<p class="wp-block-paragraph">Here&nbsp;you will see that the repaint&nbsp;script is prepopulated with the script that creates our static pump icon. You’ll notice that this script is split up into two sections. The first part defines the <a href="https://docs.oracle.com/javase/7/docs/api/java/awt/geom/package-summary.html" target="_blank">Java2D shapes</a> that make up our pump, based on a 100&#215;100 pixel area. Then, the second half scales the shapes to the size of the canvas and renders them using <a href="https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html" target="_blank">Java graphics</a>.</p>



<p class="wp-block-paragraph">Notice that the order in which the objects are painted is significant. I recommend you take some time to play around with this script, editing some values to see how the pump graphic changes. See if you can change the shape of the pump from a circle to a square&nbsp;or rotate it upside down.</p>



<p class="wp-block-paragraph">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>



<h2 id="h-updating-the-canvas-from-a-dynamic-property" class="wp-block-heading">Updating the Canvas from a Dynamic Property</h2>



<p class="wp-block-paragraph">Now, let&#8217;s&nbsp;see how we can dynamically update the pump at runtime. First, let&#8217;s add a custom property to our Paintable Canvas by right-clicking on the Paintable Canvas component in the Project Browser and selecting “Customizers &gt; Custom Properties.&#8221;&nbsp;</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas6.png" alt=""/></figure>



<p class="wp-block-paragraph">Then, we will add a toggle button to our window and bind its value to this property. Now we can test pressing our toggle button and verify that our new paintable canvas property changes.<br>
</p>



<p class="wp-block-paragraph">Now it’s time to bring this property into our paintable canvas by editing the “repaint” script below, adding a simple if statement to change the color and text of the status icon based on our new dynamic property.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas8.png" alt=""/></figure>



<p class="wp-block-paragraph">Now you should be able to change your pump mode at runtime by pressing the toggle button. This works because the repaint script for a Paintable Canvas runs any time a property of the canvas changes, including our custom bAuto property.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas9.png" alt=""/></figure>



<h2 id="h-updating-dynamic-properties-from-the-canvas" class="wp-block-heading">Updating Dynamic Properties from the Canvas</h2>



<p class="wp-block-paragraph">Now that we know how to update graphics in the paintable canvas from dynamic properties, let&#8217;s take a look at writing to properties from within the paintable canvas tool. To do this, we will open back up the component scripting tool and navigate to the mouseClicked&nbsp;event. Let&#8217;s say we want to change our mode only when the mode indicator circle is clicked. We can do this very easily by using the x and y&nbsp;properties of our mouseClicked event object.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas10.png" alt=""/></figure>



<p class="wp-block-paragraph">Here, we create a Point2D object with the coordinates of our mouseClicked point (event.x and event.y) and scale it to match the 0-100 scaling of our initial ellipse definition. We can then use the ‘contains’ method of Ellipse2D to determine whether our point lies within the Ellipse. In this case, if the user clicks within the ellipse, we update our mode property.</p>



<p class="wp-block-paragraph">Now you can click the status ellipse on the pump icon to update the mode, rather than needing a separate toggle button.</p>



<h2 id="h-dynamically-resize-and-reorient-objects" class="wp-block-heading">Dynamically Resize and Reorient Objects</h2>



<p class="wp-block-paragraph">Now, let&#8217;s return to our original pump display&nbsp;and let&#8217;s try updating our canvas to display a dynamic number of pumps. We will again start by adding a custom property to our Paintable Canvas&nbsp;and connect it to a numeric text field on our main window. This will be our user input for number of pumps. Then we will make a few small edits to our repaint script below.</p>



<p class="wp-block-paragraph">Define a new variable numPumps and link it to your new custom property.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas11.png" alt=""/></figure>



<p class="wp-block-paragraph">Scale your pump graphic in the X-direction so that each pump takes up 1/numPumps of the screen. The vector-oriented nature of Java2D makes it so easy to resize an entire object all at once, rather than adding a scale factor to each shape within the pump.</p>



<p class="wp-block-paragraph">Next, add a for loop around the ‘Paint Shapes’ portion of the script to paint each pump one at a time. At the end of the for loop, we will need to ensure any relevant properties (in my case the font size) are reset to the values they are at the start of the loop&nbsp;and then translate our origin to the right by one pump width.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas12.png" alt=""/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/PaintableCanvas13.png" alt=""/></figure>



<p class="wp-block-paragraph">Now try changing your new user input at runtime and see your Paintable Canvas update!</p>



<p class="wp-block-paragraph">&nbsp;</p>



<p class="wp-block-paragraph">Now you have the tools you need to create simple dynamic objects using the Paintable Canvas tool. With the powerful Java graphics library at your disposal, your creativity is your only limit with what objects you can create!</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Create Dynamic Ignition Vision Graphics with Java2D</strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Explore our <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/" data-type="page" data-id="420">Automation</a> expertise in <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming/" data-type="page" data-id="509">Ignition Vision</a> for building scalable, interactive HMI graphics with the Paintable Canvas and Java2D scripting.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/16140/getting-started-with-the-paintable-canvas-in-ignition-vision/">Getting Started with the Paintable Canvas in Ignition Vision</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Integrating Mitsubishi GX Works3 with Ignition Using the Ignition Mitsubishi TCP Driver</title>
		<link>https://static.dmcinfo.com/blog/16599/integrating-mitsubishi-gx-works3-with-ignition-using-the-ignition-mitsubishi-tcp-driver/</link>
		
		<dc:creator><![CDATA[Wenjing Deng]]></dc:creator>
		<pubDate>Tue, 13 Feb 2024 09:22:48 +0000</pubDate>
				<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[PLC]]></category>
		<category><![CDATA[ignition]]></category>
		<category><![CDATA[Mitsubishi GX Works3]]></category>
		<category><![CDATA[Mitsubishi PLC]]></category>
		<category><![CDATA[Mitsubishi TCP Driver]]></category>
		<category><![CDATA[SCADA System]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/16599/integrating-mitsubishi-gx-works3-with-ignition-using-the-ignition-mitsubishi-tcp-driver/</guid>

					<description><![CDATA[<p>Mitsubishi GX Works3 is a platform for programming Mitsubishi PLCs,&#160;and it is possible to directly integrate the PLC&#8217;s tags into Ignition with the recent release of the Ignition Mitsubishi driver. Ignition offers native support for Mitsubishi devices through its new Mitsubishi TCP Driver, allowing direct communication between the PLC and the SCADA system. Ignition has [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/16599/integrating-mitsubishi-gx-works3-with-ignition-using-the-ignition-mitsubishi-tcp-driver/">Integrating Mitsubishi GX Works3 with Ignition Using the Ignition Mitsubishi TCP Driver</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Mitsubishi GX Works3 is a platform for programming Mitsubishi PLCs,&nbsp;and it is possible to directly integrate the PLC&#8217;s tags into Ignition with the recent release of the Ignition Mitsubishi driver.</p>



<p class="wp-block-paragraph">Ignition offers native support for Mitsubishi devices through its new Mitsubishi TCP Driver, allowing direct communication between the PLC and the SCADA system. Ignition has a <a href="https://docs.inductiveautomation.com/docs/8.1/ignition-modules/opc-ua/opc-ua-drivers/mitsubishi-tcp-driver" target="_blank">published guide</a> for setting up connection from the Ignition side.&nbsp;</p>



<p class="wp-block-paragraph">In this blog we will focus on the configuration of a Mitsubishi PLC project in Gx Works3 to connect to an Ignition server as well as some basic troubleshooting tips. Additionally, we will go over the concept of a useful tool DMC developed DMC&nbsp;to quickly convert assigned labels within global label lists to Ignition addresses in a .csv file and that can be directly imported into the Ignition Gateway.&nbsp;</p>



<h2 id="h-configuring-a-mitsubishi-plc-for-connecting-with-ignition" class="wp-block-heading">Configuring a Mitsubishi PLC for Connecting With Ignition:</h2>



<p class="wp-block-paragraph">After you’ve added your PLC to a Gx Works3 project, navigate to the Module Parameter of your PLC.&nbsp;</p>



<p class="wp-block-paragraph"><p style="text-align: center;"></p></p>



<p class="wp-block-paragraph">In the “Own Node Settings,”&nbsp;first make sure your PLC is on the same network as your Ignition Gateway, and then make the following changes:</p>



<ol class="wp-block-list">
<li>Enable/Disable Online Change &gt; Enable All (SLMP)</li>



<li>Communication Data Code &gt; Binary</li>
</ol>



<p class="wp-block-paragraph">Then press “Apply” at the bottom right corner.&nbsp;</p>



<figure class="wp-block-image"><img decoding="async" alt="Own Node Settings Enable All Binary" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/own-node-settings-enable-all-binary-2.png" width="900px" /></figure>



<p class="wp-block-paragraph">Next, double click on the “&lt;Detailed Settings&gt;.”</p>



<figure class="wp-block-image"><img decoding="async" alt="Own Node Settings Detailed Settings " src="https://static.dmcinfo.com/wp-content/uploads/2025/05/own-node-settings-detailed-settings-3.png" width="900px" /></figure>



<p class="wp-block-paragraph">A new window will pop-up labeled “Ethernet Configuration.”&nbsp;Navigate to the right of the window and click on “Ethernet Device (General).”&nbsp;Next, click and drag a “SLMP Connection Module” to the table portion of the window. A new SLMP Connection Module will be added.&nbsp;</p>



<figure class="wp-block-image"><img decoding="async" alt="Ethernet Configuration Built-in Ethernet Port" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/ethernet-configuration-built-in-ethernet-port-4.png" width="900px" /></figure>



<p class="wp-block-paragraph">Set the Protocol to “TCP” and then set the Port Number to the same port number that was chosen in the Ignition Mitsubishi Driver.&nbsp;</p>



<p class="wp-block-paragraph">Press “Close with Reflecting the Setting” at tool bar located at the top of the window. Finally, write the new configuration changes to the PLC and do a power cycle.</p>



<h2 id="h-troubleshooting-connection-issues-nbsp" class="wp-block-heading">Troubleshooting Connection Issues:&nbsp;</h2>



<p class="wp-block-paragraph">In the tool bar at the top, navigate to “Diagnostics” &gt; “Ethernet Diagnostics” to troubleshoot any connection issues. Here you can see any error codes or statuses. You need to be connected to the PLC to use this.&nbsp;</p>



<figure class="wp-block-image"><img decoding="async" alt="Module Parameter Ethernet Diagnostics" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/module-parameter-ethernet-diagnostics-5.png" width="900px" /></figure>



<h2 id="h-converting-gx-works3-global-label-lists-to-ignition-addresses-nbsp" class="wp-block-heading">Converting Gx Works3 Global Label Lists to Ignition Addresses:&nbsp;</h2>



<p class="wp-block-paragraph">Quick reminder that, for your tags to be seen by your Ignition project, they need to have device assignments. Here is an example where the labels are assigned to D devices:&nbsp;</p>



<figure class="wp-block-image"><img decoding="async" alt="Assign Device Label" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/assign-device-lable-6-sanitized.png" width="900px" /></figure>



<p class="wp-block-paragraph">For the Ignition side, you can find the formatting for these addresses in the “Determining Addresses” section in the Ignition document linked at the top of this blog.</p>



<figure class="wp-block-image"><img decoding="async" alt="Determining Addresses Section in the Ignition document " src="https://static.dmcinfo.com/wp-content/uploads/2025/05/determining-addresses-8.png" width="900px" /></figure>



<p class="wp-block-paragraph">If your project has a lot of tags, it can be worthwhile&nbsp;to create an automated script/program to convert the label list exports from Gx Works3 to Ignition addresses and compile them into one .csv file to import into the Mitsubishi driver on the Ignition gateway. This will be much faster than manually adding in one tag at a time.&nbsp;</p>



<figure class="wp-block-image"><img decoding="async" alt="Device Connections/Mitsubishi PLC Load Configuration" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/device-connections-mitsubishi-plc-load-configuration-7-sanitized.png" width="900px" /></figure>



<p class="wp-block-paragraph">You can choose to use one .csv file to keep track of all your PLC tags or append new .csv files each time you add new tags.&nbsp;</p>



<p class="wp-block-paragraph">On a recent DMC project, we designed a <a href="/services/application-development/pc-application-development/python-development-services">Python</a> tool to help us automate this task. Our Python tool would read the exported .xml files from Gx Works3, pull out the tag names, data types, and assigned device numbers, and then use that information to construct the Ignition addresses.&nbsp;</p>



<p class="wp-block-paragraph">Our tool was&nbsp;custom made for a particular&nbsp;project, but here is the overall workflow for our tool for guidance&nbsp;if you are looking to create your own:</p>



<ol class="wp-block-list">
<li>Right click on HMI tag lists from Gx Works3 project and export as XML.</li>
</ol>



<p class="wp-block-paragraph"><p style="text-align: center;" width="657px"></p></p>



<p class="wp-block-paragraph"><p style="margin-left: 40px;">2 . Move them into the designated folder where our Python script is accessing unprocessed tag lists.</p></p>



<p class="wp-block-paragraph"><p style="margin-left: 40px;">3. Run Python script.</p></p>



<p class="wp-block-paragraph"><p style="margin-left: 40px;">4. Grab converted .csv file and import (without appending) into Mitsubishi Driver in Ignition gateway.</p></p>



<p class="wp-block-paragraph"><p style="margin-left: 40px;">5. Repeat process if new tags/lists were added to the unprocessed tag folder.</p></p>



<p class="wp-block-paragraph">In this project, we changed the mapping for our tags often during development due to changing scope/issues we were encountering. It was beneficial for us to re-run our Python conversion script on all the .xml HMI tag list files and import a new converted .csv file each time instead of appending an additional file. It was easier to keep track of changes and to update any tag mappings that might have changed as we just needed to export and overwrite the same tag list in the unprocessed tag list folder.&nbsp;</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Connect Mitsubishi PLCs Directly to Ignition</strong>.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Explore our <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/" data-type="page" data-id="420">Automation</a> expertise in Mitsubishi GX Works3, Ignition SCADA and TCP driver configuration. Learn more about our capabilities with <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/" data-type="page" data-id="441">PLC programming</a>.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/16599/integrating-mitsubishi-gx-works3-with-ignition-using-the-ignition-mitsubishi-tcp-driver/">Integrating Mitsubishi GX Works3 with Ignition Using the Ignition Mitsubishi TCP Driver</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Programming a PLC to be a Game Console</title>
		<link>https://static.dmcinfo.com/blog/16605/programming-a-plc-to-be-a-game-console/</link>
		
		<dc:creator><![CDATA[Finnbar Norman]]></dc:creator>
		<pubDate>Thu, 08 Feb 2024 12:48:45 +0000</pubDate>
				<category><![CDATA[Allen Bradley PLC]]></category>
		<category><![CDATA[Denver]]></category>
		<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[PLC]]></category>
		<category><![CDATA[Siemens PLC]]></category>
		<category><![CDATA[ignition]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/16605/programming-a-plc-to-be-a-game-console/</guid>

					<description><![CDATA[<p>PLC Code This past week, I took on the challenge of turning one of our IO demo kits connected to a Siemens PLC into a working game system. I chose to program the classic games Bop It and Simon Says as they would be easy to understand while still presenting their own challenges in both [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/16605/programming-a-plc-to-be-a-game-console/">Programming a PLC to be a Game Console</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 id="h-plc-code" class="wp-block-heading"><strong>PLC Code</strong></h2>



<p class="wp-block-paragraph">This past week, I took on the challenge of turning one of our IO demo kits connected to a <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/siemens-s7-plc-programming" target="_blank">Siemens PLC</a> into a working game system. I chose to program the classic games Bop It and Simon Says as they would be easy to understand while still presenting their own challenges in both programming and playing.</p>



<p class="wp-block-paragraph">I first created a simple infrastructure that would allow users to select which game they would like to play using one of the two colored push buttons on the IO kit. I associated each game with a different LED flash sequence to indicate which game had been selected.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/LabHardware.jpg" alt="Physical IO trainer used for BopIt game"/></figure>



<p class="wp-block-paragraph">The first game I decided to tackle was Bop It. In place of the original game’s “Twist it,” “Pull it,” etc., I used the IO kit’s toggle switches and push buttons. &nbsp;I wrote a simple logic sequence that would randomly illuminate one of the four colored LEDs and wait for the user to press/toggle the corresponding button/switch. Like the original game, if the user waited too long or selected the wrong button or switch, they would lose the game and the program would play a failure LED sequence and return to the game selection sequence. After enough correct button pushing and switch flipping, the program would display a winning LED sequence and return to game selection.</p>



<p class="wp-block-paragraph">Simon Says used similar code but with a few differences. These changes were needed due to the game’s sequence, stored using an array, which would be flashed by the LEDs then input by the user. The LED flash was accomplished using a counter up to the current length of the sequence, reading the index of the array at the current count and flashing the corresponding LED. The user input used similar logic, comparing the user’s selection to the array after each button push or switch flip. After successfully repeating a sequence of 10 LED flashes the program displays the winning sequence and returns to the game selection.</p>



<h2 id="h-user-interface" class="wp-block-heading"><strong>User Interface</strong></h2>



<p class="wp-block-paragraph">I created a project in Ignition to graphically display the state of the game and monitor some key statistics. This endeavor added some useful functionality to the PLC code through the powerful tools provided by <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming" target="_blank">Ignition Perspective</a>.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/IgnitionBopIt.png" alt="Main Ignition screen for Bop It game"/></figure>



<p class="wp-block-paragraph">The perspective session has three main views: an overview screen and two screens for the games. It is set up so that additional games can be added easily. The overview screen offers navigation to both games, as well as a leaderboard and a popup that explains the games. Each game screen displays a brief description of the game, the status of each digital output, and the player’s current progress. Additionally, a timer shows the player how much time is remaining to make a move, a feature that is not available on the physical kit. Each game screen displays the current high score for that game. This data is pulled from a PostgreSQL database of player initials, scores, and dates. This database is also used to populate the leaderboard.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Leaderboard.png" alt="Leaderboard used to show Bop It and Simon Says high scores"/></figure>



<p class="wp-block-paragraph">This project utilizes several of Ignition’s powerful features. Perspective can pull data from the PLC with OPC tags. These tags are then used with both built-in and custom graphics, in combination with Ignition scripting to display the status of the game. Ignition also connects to the database to create the leaderboard and high score features, through additional scripting and SQL queries. Additionally, popups are used in combination with scripts and event handlers to provide a seamless navigation experience for the user. This project uses one PLC, one database, and six windows, but these features can easily be applied to much larger automation applications.</p>



<p class="wp-block-paragraph">Currently, the Perspective session only reads data from the PLC. An interesting next step could be to use Ignition to write to the plc, maybe with inputs more realistic to Bop It (i.e. twisting and pulling). This project takes advantage of some of the functionality of Ignition, but there are numerous other features that could be utilized for additional functionality.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Turn a Siemens PLC into a Game Console</strong>.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Explore our <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/" data-type="page" data-id="420">Automation</a> expertise in <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/siemens-s7-plc-programming/" data-type="page" data-id="444">Siemens PLC</a> programming, Ignition Perspective, and database integration through unique applications.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/16605/programming-a-plc-to-be-a-game-console/">Programming a PLC to be a Game Console</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Migrating Tag History in Ignition&#8217;s Tag Historian</title>
		<link>https://static.dmcinfo.com/blog/18050/migrating-tag-history-in-ignitions-tag-historian/</link>
		
		<dc:creator><![CDATA[Isabelle Chan]]></dc:creator>
		<pubDate>Wed, 23 Nov 2022 15:12:12 +0000</pubDate>
				<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[ignition]]></category>
		<category><![CDATA[Tag Historian]]></category>
		<category><![CDATA[Tag History]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/18050/migrating-tag-history-in-ignitions-tag-historian/</guid>

					<description><![CDATA[<p>The Ignition Tag Historian module is a powerful tool that efficiently stores tag history in designated SQL tables. This data can be accessed through scripting, reporting, and historical bindings and has built-in features such as automatic purging and partitioning to avoid overloading the database. The module also allows for easy viewing of tag trends by [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/18050/migrating-tag-history-in-ignitions-tag-historian/">Migrating Tag History in Ignition&#8217;s Tag Historian</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">The Ignition Tag Historian module is a powerful tool that efficiently stores tag history in designated SQL tables. This data can be accessed through scripting, reporting, and historical bindings and has built-in features such as automatic purging and partitioning to avoid overloading the database. The module also allows for easy viewing of tag trends by allowing users to drag and drop tags on Vision&apos;s Easy Chart and Perspective&apos;s Power Chart components.</p>

<p class="wp-block-paragraph">Despite the great capabilities of the Tag Historian, the format in which data is stored can complicate the process of directly querying&nbsp;these tables. As a result, migrating tag history from one tag to another after say, renaming or moving a tag, may prove challenging. These types of migrations may need to be performed after reorganizing the tag structure of a project or replacing a sensor while maintaining continuous tag history data.</p>

<h2 class="wp-block-heading">The Example</h2>

<p class="wp-block-paragraph">For simplicity&apos;s sake, we will go over an example in which a new tag is added to a project under these conditions:</p>

<ol class="wp-block-list" type="1">
 <li value="1">The old and new tags are standalone tags not found in any UDTs.</li>
 <li>The tag group of the tags did not change.</li>
 <li>Neither the gateway nor the gateway name changed.</li>
 <li>Only one gateway is used.</li>
</ol>

<p class="wp-block-paragraph">It&apos;s worth noting that&nbsp;tag history can still be migrated when some or none of the above conditions apply! There are several nuances each of the conditions requires that one must consider when performing migration. Knowledge of all Ignition built-in historian tables is key to ensuring a successful migration for more complex conditions. Due to the simplicity of the example used, we will only focus on two tables.</p>

<p class="wp-block-paragraph">Let&apos;s start off with a single tag called &quot;<strong>TagX</strong>&quot;. We want to transfer the history of this tag to a new tag, &quot;<strong>TagY</strong>&quot;, that we&apos;ll introduce later. According to this Power Chart image, <strong>TagX</strong> has been active since at least 12:40PM and has been holding at a steady value of 2.</p>

<figure class="wp-block-image"><img decoding="async" alt="Power Chart displaying history for TagX" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/powerchart_TagX.png"  /></figure>

<h2 class="wp-block-heading">Tag Historian Tables</h2>

<p class="wp-block-paragraph">We can find this tag in one of Ignition&apos;s historian tables, <strong>sqlth_te</strong>. This contains all of the non-data information about a tag. The information in this table is a great starting point to understanding the other tables created by the historian. The most important columns are:</p>

<ul class="wp-block-list" type="disc">
 <li><strong>id</strong>: A&nbsp;unique identifier for a tag</li>
 <li><strong>tagpath</strong>: The tag path (without the provider), all lowercase</li>
 <li><strong>scid</strong>: id of the tag group that tag is in</li>
 <li><strong>created</strong>: An epoch timestamp of when the tag began storing tag history</li>
 <li><strong>retired</strong>: An epoch timestamp of when the tag stopped storing tag history or was deleted</li>
</ul>

<figure class="wp-block-image"><img decoding="async" alt="Database query browser displaying sqlth_te table" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/sqlth_te-TagX_1.png"  /></figure>

<p class="wp-block-paragraph">We also have the tables in which the history is actually stored. If monthly partitioning is set up, the name of the table will look something like <strong>sqlt_data_A_B_C</strong> where A is the driver id or gateway identifier, B is the year, and C is the month. In this example, our data table is <strong>sqlt_data_1_2022_11</strong>, so we know that this data was taken in November of 2022. The columns here log the actual values of the tags storing history. The columns in this table are:</p>

<ul class="wp-block-list" type="disc">
 <li><strong>tagid</strong>: The id from the sqlth_te table</li>
 <li><strong>___value</strong>: The value recorded for the tag</li>
 <li><strong>dataintegrity</strong>: The quality code of the value recorded</li>
 <li><strong>t_stamp</strong>: The epoch timestamp at which the value was recorded</li>
</ul>

<p class="wp-block-paragraph">We can also see <strong>TagX</strong>, which has a <strong>tagid</strong> of 5, started at a value of 0, and then transitioned to a value of 2 at 12:40PM.</p>

<figure class="wp-block-image"><img decoding="async" alt="Database query browser displaying data table" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/sqlth_data-TagX.png"  /></figure>

<h2 class="wp-block-heading">Adding TagY</h2>

<p class="wp-block-paragraph">Next, we introduce a new tag called &quot;<strong>TagY</strong>&quot;, assigned a <strong>tagid </strong>of 6 by Ignition, that begins collecting information at 12:52.</p>

<figure class="wp-block-image"><img decoding="async" alt="Database query browser displaying the sqlth_te table with TagX and TagY" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/sqlth_te-TagXY.png"  /></figure>

<p class="wp-block-paragraph">From 12:52 to about 12:53, both tags are reading a value of 2. The sensor for <strong>TagX</strong> goes offline just before 12:53, leaving only <strong>TagY</strong> online. At about 12:58, <strong>TagY</strong> then drops down to 1.</p>

<figure class="wp-block-image"><img decoding="async" alt="Power Chart displaying history for TagX and TagY" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/powerchart_TagXY.png"  /></figure>

<figure class="wp-block-image"><img decoding="async" alt="Database query browser displaying the data table for both TagX and TagY" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/sqlth_data-TagXY.png"  /></figure>

<h2 class="wp-block-heading">Performing the History Migration</h2>

<p class="wp-block-paragraph">To transfer the history of <strong>TagX</strong> to <strong>TagY</strong>, all we have to do is run a simple update query to replace the tagpath of <strong>TagX</strong> with the tagpath of <strong>TagY</strong>. The following script examples use Ignition&apos;s script console to query the database. Because these scripts are only querying the database, one may use whatever query tool they prefer.</p>

<figure class="wp-block-image"><img decoding="async" alt="Script console running a query " src="https://static.dmcinfo.com/wp-content/uploads/2025/05/query.png"  /></figure>

<p class="wp-block-paragraph">The <strong>sqlth_te</strong> table now looks like this.</p>

<figure class="wp-block-image"><img decoding="async" alt="Database query browser displaying the sqlth_te table for TagY" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/sqlth_te-TagY.png"  /></figure>

<p class="wp-block-paragraph">While <strong>sql_data_1_2022_11</strong> will still look the same, the tag history of <strong>TagX </strong>has transferred over to <strong>TagY</strong>. The history for <strong>TagY </strong>now goes beyond 12:52PM, its start time and <strong>TagX </strong>is no longer in the tag browser for the Power Chart component. We can also see that Ignition continues to collect and store history for <strong>TagY </strong>when the value rises to 3 at 1:11PM.</p>

<figure class="wp-block-image"><img decoding="async" alt="Power Chart displaying that TagX's history has been transferred over to TagY" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/powerchart_TagY3.png"  /></figure>

<p class="wp-block-paragraph"><strong>Learn more about DMC&apos;s&nbsp;<a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming">Ignition expertise</a>, and&nbsp;<a href="https://static.dmcinfo.com/contact">contact us</a>&nbsp;to get started on your next&nbsp;<a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming">HMI</a>,&nbsp;<a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming">SCADA</a>, or&nbsp;<a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/manufacturing-execution-systems-services">MES&nbsp;</a>project!</strong></p>
<p>The post <a href="https://static.dmcinfo.com/blog/18050/migrating-tag-history-in-ignitions-tag-historian/">Migrating Tag History in Ignition&#8217;s Tag Historian</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dynamically Creating Stations and Tags in Ignition</title>
		<link>https://static.dmcinfo.com/blog/18380/dynamically-creating-stations-and-tags-in-ignition/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Fri, 05 Aug 2022 21:39:17 +0000</pubDate>
				<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[ignition]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/18380/dynamically-creating-stations-and-tags-in-ignition/</guid>

					<description><![CDATA[<p>Some of the main benefits of using Ignition as a SCADA/HMI platform are its powerful scripting capabilities as well as its ability to allow users to create complex UDTs. By combining these features, users can almost instantaneously set up stations or discrete groups and add any number of tags; using&#160;this method, development time can be [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/18380/dynamically-creating-stations-and-tags-in-ignition/">Dynamically Creating Stations and Tags in Ignition</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Some of the main benefits of using Ignition as a SCADA/HMI platform are its powerful scripting capabilities as well as its ability to allow users to create complex UDTs. By combining these features, users can almost instantaneously set up stations or discrete groups and add any number of tags; using&nbsp;this method, development time can be drastically reduced.</p>



<p class="wp-block-paragraph">In the following example, we will create a window in Ignition that can dynamically create station groups&nbsp;as well as set up device UDT tag instances for those stations. It is important to note that, to effectively streamline the tag instantiation process, you must create all device UDTs with that goal in mind.</p>



<p class="wp-block-paragraph">One way of doing this is by creating your UDTs to utilize the same parameters. As an example, I’ve created some simple example device UDTs that all have the string parameters: PLC, PLCTagPath, and Path. All the device tags have the same structure in this example, but, in real use cases, they can be different as long as they all have the same parameters.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">We will be using several datasets to hold information about the other tags we want to create. The first dataset tag we must create is for storing our station information. Set up <strong>dsAvailableStations </strong>as a Memory tag and Dataset data type and add two columns: <strong>Value </strong>and <strong>Label</strong>. Value will be the index of the station, and Label will be the station folder’s name.</p>



<p class="wp-block-paragraph"><p align="center"></p></p>



<p class="wp-block-paragraph">With this done, we can begin setting up a window that the user can interact with to create stations and add device tags. Start by creating a new window and adding a power table at the top, along with two buttons that will be used to add and delete rows from the table.</p>



<p class="wp-block-paragraph">Link the <strong>Data </strong>property of the power table to the <strong>dsAvailableStations </strong>dataset tag. In this example, this tag has been placed in a configuration folder, which has been put in a system folder for organizational purposes. Next, add a script to the <strong>Add Row</strong> button’s <strong>actionPerformed </strong>event handler that will add a row to the <strong>dsAvailableStations </strong>tag.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-5.png" alt="Ignition interface - power table tagging"/></figure>



<p class="wp-block-paragraph">We can use Ignition’s built-in system.dataset.addRow function for the <strong>Add Row </strong>button. In the example code below, the path to our dsAvailableStations is input at the top. A try/except block is used to first make sure that a dataset tag exists that we can add to.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-6.png" alt="Ignition interface - component scripting "/></figure>



<p class="wp-block-paragraph">Add a script to the delete row button that can delete the currently selected row from the power table. The example script for this step will be slightly more complicated because we will also set up this button to delete the station folder tags that were created from the data contained in the row that is being deleted. We can use Ignition’s system.dataset.deleteRow() and system.tag.deleteTags() functions to do this.</p>



<p class="wp-block-paragraph"><p style="margin-left:1.25in;"></p></p>



<p class="wp-block-paragraph">Before we set up scripting on the power table itself, we will need to write scripts to create the station folders and the tags contained within. The example script for this purpose is shown below.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-8.png" alt="Ignition dynamicProjectBuild script"/></figure>



<p class="wp-block-paragraph">The section outlined in green uses system.dataset.toPyDataSet() to change the <strong>Ignition </strong>dataset (which is not easily able to be iterated through) into a <strong>Python </strong>dataset. We can iterate through the dataset and create a list of the stations listed in the table.</p>



<p class="wp-block-paragraph">The <strong>blue </strong>section goes through the tags in the default browser and checks if the stations in the station list have already had tags created for them. If they have, they are removed from the list. Finally, the <strong>red </strong>section moves through the station list and sets up the configurations for the tags you would like to create for each station.</p>



<p class="wp-block-paragraph">The configurations in this section can be changed to fit the tags you will need in your specific project. For the purposes of this example, we will create a folder for the station itself and add an <strong>IO </strong>and a <strong>Devices </strong>folder to go inside. To the IO folder, we will add a <strong>DigitalInputs </strong>and <strong>DigitalOutputs </strong>folder.</p>



<p class="wp-block-paragraph">Finally, we will configure a dataset tag that will have a column for <strong>DeviceID </strong>and the <strong>UDT </strong>of each device. We will add to this dataset later. This will be critical to actually instantiating our device tags.</p>



<p class="wp-block-paragraph">Next, we simply need to add a call to the createStations() script we just created whenever a cell of the power table is edited. This will create new station folders with all appropriate tags when they are added to the table. With that, the portion of our window that deals with creating our stations is complete.</p>



<p class="wp-block-paragraph"><p align="center"></p></p>



<p class="wp-block-paragraph">We then move on to setting up device UDT instantiation on the window. We will add a dropdown component to select which station we want to add device tags to.</p>



<p class="wp-block-paragraph"><p align="center"></p></p>



<p class="wp-block-paragraph">Add an<strong> Indirect Tag</strong> property binding to the data property of the dropdown and link it to the <strong>dsAvailableStations </strong>tag. This will list the stations that were created with the station table.</p>



<p class="wp-block-paragraph">Next, add another power table and a copy of the <strong>Add Row</strong> and <strong>Delete Row </strong>buttons.</p>



<p class="wp-block-paragraph"><p align="center"></p></p>



<p class="wp-block-paragraph">Modify the <strong>Add Row</strong> button script to use the station dropdown to modify the <strong>dsDevices </strong>dataset at the selected station.</p>



<p class="wp-block-paragraph"><p align="center"></p></p>



<p class="wp-block-paragraph">Modify the <strong>Delete Row</strong> button script to use the selected station to delete the selected row/device tag from the <strong>dsDevices </strong>dataset. Also, use system.tag.browse() to search through the tags and delete the device instance.</p>



<p class="wp-block-paragraph">We now move on to adding the table that will instantiate device tags in the station folders by adding a dropdown component to select which station we want to add device tags to. Add an <strong>Indirect Tag</strong> property binding to the data property of the dropdown and link it to the <strong>dsAvailableStations </strong>tag. This will list the stations that were created with the station table.</p>



<p class="wp-block-paragraph"><p align="center"></p></p>



<p class="wp-block-paragraph">Before we work on the power table, we need to set up a script to create a list of all of the devices UDTs to select from in the power table. This will make setting up the device tags faster because each UDT will not need to be typed in; they can simply be selected from a dropdown in the table.</p>



<p class="wp-block-paragraph">This script will once again use system.tag.browse() to search through the tags (specifically for this example, the UDTs within the<strong> _types_/devices</strong> folder). It then takes the names of those UDTs and adds them to a list that we can connect to a cell in the device power table.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-14.png" alt="ignition script"/></figure>



<p class="wp-block-paragraph">Next, we will make the script that instantiates the device tags. This script goes through the <strong>dsDevices </strong>dataset for the selected station and uses the deviceID and UDT columns to set up the device tag configuration. <strong>System.tag.configure()</strong> is then used to create the tag at the station input into the function.</p>



<p class="wp-block-paragraph">To make sure that the device tag configuration is updated if a tag of the same deviceID has already been made, we need to delete the old version of the tag before recreating it.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-15.png" alt="ignition interface"/></figure>



<p class="wp-block-paragraph">Back on the device creation window, use an indirect tag binding on the device power table’s <strong>Data </strong>property to connect it the <strong>dsDevices </strong>tag for the station selected from the dropdown.</p>



<p class="wp-block-paragraph"><p align="center">&nbsp;</p></p>



<p class="wp-block-paragraph">Add a <strong>configureEditor </strong>script on to the device creation power table and use the <strong>deviceUDTlookup() </strong>script to setup the UDT column of our power table to use a dropdown list of the device UDTs.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-17.png" alt="Ignition device creation window"/></figure>



<p class="wp-block-paragraph">Finally, add an <strong>onCellEdited </strong>script that calls the <strong>createDevices()</strong> script to instantiate our device UDTs whenever the power table is changed.</p>



<figure class="wp-block-image"><img decoding="async" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Dynamic-UDT-Instances-tutorial-18_1.png" alt="Ignition onCellEdited script"/></figure>



<p class="wp-block-paragraph">Now our window is completely set up to quickly add station folders and instantiate device UDT tags. This window makes tag creation in Ignition much simpler and faster. In this screenshot, we can see Station1 was created and a few devices with the correct parameter configuration were added.</p>



<p class="wp-block-paragraph">If this project were connected to a matching tag source, we would expect these tags to show good quality and be working as intended. This window and all associated scripts can be copied between multiple projects and, as long as the UDTs were set up in a similar fashion to each other, allow you to begin dynamically creating tags in a snap.</p>



<p class="wp-block-paragraph"><strong>Learn more about DMC&#8217;s&nbsp;<a href="/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming">Ignition expertise</a>&nbsp;and&nbsp;<a href="/contact">contact us</a>&nbsp;for your next&nbsp;<a href="/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming">HMI or SCADA</a>&nbsp;project.</strong></p>



<p class="wp-block-paragraph">&nbsp;</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/18380/dynamically-creating-stations-and-tags-in-ignition/">Dynamically Creating Stations and Tags in Ignition</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Resolving “Connection Refused SSL” Error in Ignition</title>
		<link>https://static.dmcinfo.com/blog/18665/resolving-connection-refused-ssl-error-in-ignition/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Mon, 21 Mar 2022 12:46:45 +0000</pubDate>
				<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[ignition]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/18665/resolving-connection-refused-ssl-error-in-ignition/</guid>

					<description><![CDATA[<p>I recently restored a backup of an Ignition project onto my computer to make changes locally. I was able to open the gateway without issue but ran into problems when I tried to launch the Vision Designer.&#160; No matter what I tried, I could not get the Vision Designer or the Client to connect to [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/18665/resolving-connection-refused-ssl-error-in-ignition/">Resolving “Connection Refused SSL” Error in Ignition</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">I recently restored a backup of an Ignition project onto my computer to make changes locally. I was able to open the gateway without issue but ran into problems when I tried to launch the Vision Designer.&nbsp;</p>

<p class="wp-block-paragraph">No matter what I tried, I could not get the Vision Designer or the Client to connect to the gateway, even though the gateway showed up when adding through the &lsquo;Add Designer&rsquo; button and displayed as a valid connection.&nbsp;</p>

<p class="wp-block-paragraph">After a considerable amount of time, I resolved this issue. In this article, my goal is to&nbsp;help others avoid my frustrations by walking through my solution.</p>

<h2 class="wp-block-heading">The Problem</h2>

<p class="wp-block-paragraph">The error that came up was &ldquo;Error launching application: ConnectException: Connection refused: connect.&rdquo;</p>

<figure class="wp-block-image"><img decoding="async" alt="Ignition Error Message" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Ignition-Error-Message.png"  /></figure>

<p class="wp-block-paragraph">I noticed a setting called &ldquo;Force Secure Redirect&rdquo; was automatically commanding the designer to use SSL. This setting is located in Config&gt;Networking&gt;Web Server&gt;HTTPS Settings (see image below). In this instance, SSL was set up on the client environment, but it not my local one.&nbsp;</p>

<p class="wp-block-paragraph">The HTTPS settings are not accessible if SSL is not set up, so there was no way for me to uncheck the Force Secure Redirect from within the gateway UI.</p>

<figure class="wp-block-image"><img decoding="async" alt="Ignition HTTPS Settings" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Ignition-HTTPS-Settings.png"  /></figure>

<h2 class="wp-block-heading">The Solution</h2>

<p class="wp-block-paragraph">To get this box unchecked, I went into the &lsquo;gateway.xml&rsquo; file (located at C:\Program Files\Inductive Automation\Ignition\data on my computer) and manually changed the value (see image below). I also deleted the backup file titled &lsquo;gateway.xml.bak,&rsquo;&nbsp;which was automatically created.&nbsp;</p>

<p class="wp-block-paragraph"><br />
<figure class="wp-block-image"><img decoding="async" alt="Ignition code" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/Ignition-code.png"  /></figure></p>

<p class="wp-block-paragraph">Once this was complete, I restarted the gateway by navigating to the &lsquo;gwcmd.bat&rsquo; file location within a command window (located at C:\Program Files\Inductive Automation\Ignition on my computer) and used command: gwcmd -r to restart the gateway.&nbsp;</p>

<p class="wp-block-paragraph">After these steps were completed, I was able to access the gateway and open the project within the Ignition Designer. &nbsp;</p>

<h2 class="wp-block-heading">Helpful Tips</h2>

<p class="wp-block-paragraph">Here are some helpful clues and additional steps that helped me resolve this issue:</p>

<ul class="wp-block-list">
 <li>I verified firewall permissions.</li>
 <li>I verified that my current version of Java was up to date.</li>
 <li>I verified that the project version matched the version I had installed on my computer.</li>
 <li>I increased the logging from INFO to DEBUG.</li>
 <li>I found the launch error logs on my computer at C:\Users\oliverr\.ignition
 <ul class="wp-block-list">
  <li>This was the biggest help.</li>
  <li>I saw the following lines in the log and understood that the system was trying to connect to the http<strong>s</strong> address instead of the http address: &nbsp;</li>
 </ul>
 </li>
</ul>

<p class="wp-block-paragraph" style="margin-left: 40px;"><em>Downloading &quot;https://static.dmcinfo.com/system/jar/m/active-query-builder-8.1.15.jar&quot; (timeout=60000)&#8230;<br />
Download attempt #0 for file active-query-builder-8.1.15.jar failed.<br />
java.net.ConnectException: Connection refused: connect</em></p>

<p class="wp-block-paragraph"><strong>DMC is an <a href="https://inductiveautomation.com/integrators/results/24231" target="_blank">Ignition Premier Integrator</a>. Learn more about our <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-programming">Ignition programming </a>expertise and <a href="https://static.dmcinfo.com/contact">contact us</a> for your next project.&nbsp;</strong></p>
<p>The post <a href="https://static.dmcinfo.com/blog/18665/resolving-connection-refused-ssl-error-in-ignition/">Resolving “Connection Refused SSL” Error in Ignition</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Creating Dynamic Ignition Perspective Projects, Part 4: Parameters, Indirect Bindings, and Flex Repeaters</title>
		<link>https://static.dmcinfo.com/blog/19090/creating-dynamic-ignition-perspective-projects-part-4-parameters-indirect-bindings-and-flex-repeaters/</link>
		
		<dc:creator><![CDATA[Casimir Smith]]></dc:creator>
		<pubDate>Fri, 27 Aug 2021 12:27:37 +0000</pubDate>
				<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[MES]]></category>
		<category><![CDATA[flex repeater]]></category>
		<category><![CDATA[ignition]]></category>
		<category><![CDATA[indirect]]></category>
		<category><![CDATA[parameter]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/19090/creating-dynamic-ignition-perspective-projects-part-4-parameters-indirect-bindings-and-flex-repeaters/</guid>

					<description><![CDATA[<p>One of the fastest-growing SCADA/HMI platforms today is Inductive Automation&apos;s Ignition. In addition to the well-known Vision visualization module, Ignition&#160;contains Perspective, a web-friendly visualization module&#160;which&#160;works in any web browser&#8212;even on mobile! Although most Ignition functions work the same across Perspective or Vision, there are some necessary adjustments to work better in a web-friendly environment. This [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/19090/creating-dynamic-ignition-perspective-projects-part-4-parameters-indirect-bindings-and-flex-repeaters/">Creating Dynamic Ignition Perspective Projects, Part 4: Parameters, Indirect Bindings, and Flex Repeaters</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">One of the fastest-growing SCADA/HMI platforms today is Inductive Automation&apos;s <a href="https://inductiveautomation.com/ignition/" target="_blank">Ignition</a>. In addition to the well-known <a href="https://inductiveautomation.com/ignition/modules/vision" target="_blank">Vision visualization module</a>, Ignition&nbsp;contains<a href="https://inductiveautomation.com/ignition/modules/perspective" target="_blank"> Perspective</a>, a web-friendly visualization module&nbsp;which&nbsp;works in any web browser&mdash;even on mobile!</p>

<p class="wp-block-paragraph">Although most Ignition functions work the same across Perspective or Vision, there are some necessary adjustments to work better in a web-friendly environment. This multi-part blog will serve as a guide to setting up dynamic Perspective screens that take full advantage of the powerful&nbsp;new features.</p>

<p class="wp-block-paragraph">In&nbsp;<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10252/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers">part&nbsp;3</a>, we created a template view that controls an enable property and shows a numeric&nbsp;tag. In this part, we will go over how to add parameters to your embedded view, then use those parameters to drive indirect tag bindings. We can then use our parametrized template in a flex repeater to maximize our layout efficiency.</p>

<h2 class="wp-block-heading">Adding View Parameters</h2>

<p class="wp-block-paragraph">First, we will cover how to add a parameter to a view and change the tag binding based on that parameter. My example project has the following tag structure, where each TemperatureZone folder has an Enable tag and OutputTemp tag. We want the parameter to change which temperature zone&nbsp;the view displays.</p>

<figure class="wp-block-image"><img decoding="async" alt="We want our template to look at one of these tag folders" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/2_tag_folders.png"  /></figure>

<p class="wp-block-paragraph">First, open the flex container template view we created in&nbsp;<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10252/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers">part 3</a>. Select the view in the project browser, which will open the view properties in the property editor. Press the blue &quot;Add View Parameter&quot; button to create a new param. Change the param name to &quot;TempZone&quot; and set the value to 1.</p>

<figure class="wp-block-image"><img decoding="async" alt="Create a parameter in the view property editor" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/4_create_view_param.png"  /></figure>

<p class="wp-block-paragraph">Next, we are going to adjust the button text to display the name of the current zone. Select the button and add an expression binding to the &quot;text&quot; property. Add the following expression, which will display the parameter value with the Zone prefix:</p>

<div style="background:#eee;border:1px solid #ccc;padding:5px 10px;">&apos;Zone &apos; + {view.params.TempZone}</div>

<figure class="wp-block-image"><img decoding="async" alt="Add a binding to the button text to show name" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/4b_add_name_binding.png"  /></figure>

<h2 class="wp-block-heading">Indirect Tag Bindings</h2>

<p class="wp-block-paragraph">Next, we will change our temperature tag binding to an indirect tag binding. If you are creating an indirect binding from scratch&nbsp;the method is the same. Select the temperature label and change the tag binding type from Direct to Indirect. Next, delete the &quot;1&quot; index from the tag path (or whatever index distinguishes your tag folders or UDTs).</p>

<figure class="wp-block-image"><img decoding="async" alt="Change the tag binding to an indirect binding" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/5_select_indirect_binding.png"  /></figure>

<p class="wp-block-paragraph">Place your cursor where you wish to add the indirect reference (where the 1 used to be), then press the property reference button to the right of the tag path entry box. Find the TempZone parameter in the tree and press Ok to insert the TempZone param. The reference is now shown in both the tag path and the reference list. You will know that you&apos;ve configured the binding correctly when the Binding Preview shows the tag value, not an error.</p>

<figure class="wp-block-image"><img decoding="async" alt="Create an indirect reference in your binding" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/7_indirect_reference.png"  /></figure>

<p class="wp-block-paragraph">(Note: Previous guides did not explicitly cover binding the &quot;enable&quot; custom property to the enable tag. This can be accomplished with an&nbsp;indirect tag binding on the custom property. Don&apos;t forget to set the bidirectional checkbox so the property can write back to the tag!)</p>

<h2 class="wp-block-heading">Configuring Embedded View Parameters and Flex Repeaters</h2>

<p class="wp-block-paragraph">Once you have added a parameter to a view, you can add a value to that parameter on any embedded view instances. Select the embedded view, then find &quot;params&quot; in the property editor. Click &quot;Add Object Member&quot;, then find TempZone (input) in the parameters list. Once you add that parameter, it will appear in the parameters list and you can edit the value. Try changing the TempZone param to different values to see how the template reacts.</p>

<figure class="wp-block-image"><img decoding="async" alt="Add a parameter to the embedded view object" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/8_add_parameter_1.png"  /></figure>

<p class="wp-block-paragraph">One of the most common ways to embed templates is the flex repeater. This object works like a flex container, but it creates multiple instances of a single specified view. Drag a flex repeater from the toolbox to the main view.</p>

<figure class="wp-block-image"><img decoding="async" alt="Add a flex repeater to your view" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/9_add_flex_repeater.png"  /></figure>

<p class="wp-block-paragraph">Next, select the flex repeater and change its path property to the path of the template view. Under instances, click &quot;Add Array Element&quot; and add three instances of the template.</p>

<figure class="wp-block-image"><img decoding="async" alt="Add instances to your flex repeater" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/10_add_flex_instance.png"  /></figure>

<p class="wp-block-paragraph">The three instances will appear as array objects under the instances property. Each instance has an instanceStyle and instancePosition, but you will need to add the TempZone parameter. Click the grey plus button by the instance number and add TempZone (input) as a parameter.</p>

<figure class="wp-block-image"><img decoding="async" alt="Add parameters to your flex repeater instances" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/11_add_parameters.png"  /></figure>

<p class="wp-block-paragraph">Change each TempZone parameter to a different index. The objects inside the template will use that parameter value for display (Zone 1, Zone 2, Zone 3) and for their indirect tag bindings&nbsp;(note the different temperature values).</p>

<figure class="wp-block-image"><img decoding="async" alt="Flex repeater result" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/12_final_result_1.png"  /></figure>

<p class="wp-block-paragraph">In this guide, we&apos;ve learned how to create view parameters, use them to drive indirect bindings, and how to use flex repeaters to efficiently copy embedded views. In the next guide, we&apos;ll cover a more advanced flex repeater technique to allow for a variable number of instances.</p>

<p class="wp-block-paragraph"><strong>Learn more about DMC&apos;s&nbsp;<a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-designer-programming">Ignition expertise</a>.&nbsp;&nbsp;<a href="https://static.dmcinfo.com/contact">Contact us</a>&nbsp;to get started on your next <a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming">HMI, SCADA</a>, or MES project.<br />
<br />
See other blogs in this series:&nbsp;</strong>Creating Dynamic Ignition Perspective Projects<br />
<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10250/creating-dynamic-ignition-perspective-projects-part-one-bindings-and-transforms">Part 1: Bindings and Transforms</a><br />
<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10251/creating-dynamic-ignition-perspective-projects-part-2-button-event-actions">Part 2: Button Event Actions</a><br />
<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10252/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers">Part 3: Embedded Views and Flex Containers</a><br />
Part 4: View Parameters, Indirect Bindings, and Flex Repeaters<br />
Part 5: Flex Repeaters with Variable Number of Instances (coming soon)<br />
Part 6: Changing Colors and Other Properties (coming soon)</p>
<p>The post <a href="https://static.dmcinfo.com/blog/19090/creating-dynamic-ignition-perspective-projects-part-4-parameters-indirect-bindings-and-flex-repeaters/">Creating Dynamic Ignition Perspective Projects, Part 4: Parameters, Indirect Bindings, and Flex Repeaters</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Creating Dynamic Ignition Perspective Projects, Part 3: Embedded Views and Flex Containers</title>
		<link>https://static.dmcinfo.com/blog/19104/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers/</link>
		
		<dc:creator><![CDATA[Casimir Smith]]></dc:creator>
		<pubDate>Fri, 27 Aug 2021 11:11:11 +0000</pubDate>
				<category><![CDATA[HMI and SCADA]]></category>
		<category><![CDATA[Ignition]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[MES]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[ignition]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/19104/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers/</guid>

					<description><![CDATA[<p>One of the fastest growing SCADA/HMI platforms today is Inductive Automation&apos;s Ignition. In addition to the well-known Vision visualization module, Ignition&#160;contains Perspective, a web-friendly visualization module built from the ground up to work in any web browser &#8212;&#160;even on mobile! Although most Ignition functions work the same across Perspective or Vision, there are some adjustments&#160;to&#160;work&#160;better&#160;in [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/19104/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers/">Creating Dynamic Ignition Perspective Projects, Part 3: Embedded Views and Flex Containers</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">One of the fastest growing SCADA/HMI platforms today is Inductive Automation&apos;s <a href="https://inductiveautomation.com/ignition/" target="_blank">Ignition</a>. In addition to the well-known <a href="https://inductiveautomation.com/ignition/modules/vision" target="_blank">Vision</a> visualization module, Ignition&nbsp;contains <a href="https://inductiveautomation.com/ignition/modules/perspective">Perspective</a>, a web-friendly visualization module built from the ground up to work in any web browser &mdash;&nbsp;even on mobile!</p>

<p class="wp-block-paragraph">Although most Ignition functions work the same across Perspective or Vision, there are some adjustments&nbsp;to&nbsp;work&nbsp;better&nbsp;in a web-friendly environment. This multi-part blog will serve as a guide to setting up dynamic Perspective screens that take full advantage of the powerful new features.</p>

<p class="wp-block-paragraph">In the last two blogs, we created a status display to toggle an enable bit and display a numeric value. In this blog, we will combine&nbsp;those objects into an embedded view and use a flex repeater to create a dynamic layout.</p>

<h2 class="wp-block-heading">Creating a New Flex View</h2>

<p class="wp-block-paragraph">To create a new view, right click &quot;Views&quot; in the Project Browser then click &quot;New View&quot; In the popup. Be sure to change the root container type to &quot;Flex Container&quot;. The root container type cannot be changed once the view is created.</p>

<figure class="wp-block-image"><img decoding="async" alt="Create a new view with a flex root container" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/1_new_flex_view.png"  /></figure>

<p class="wp-block-paragraph">Next, select the view in the project browser and resize it using the width and height properties in the property editor. Change the dimensions to 400x100px.</p>

<figure class="wp-block-image"><img decoding="async" alt="Resize the view for it to be a template" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/2_resized_view.png"  /></figure>

<p class="wp-block-paragraph">Next, return to the main view and copy the toggle button, enable display, and numeric value display. Paste these three components into the new view&apos;s root container.</p>

<p class="wp-block-paragraph"><figure class="wp-block-image"><img decoding="async" alt="Copy your components from the main view" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/3_copy_from_main_view.png"  /></figure><figure class="wp-block-image"><img decoding="async" alt="Paste your components to the template view" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/4_paste_to_main_view.png"  /></figure></p>

<p class="wp-block-paragraph">The three views line up on top of each other in the flex container, which is not what we want. We need to configure the flex container and object position properties to best display our data.</p>

<h2 class="wp-block-heading">Configuring the Flex Container</h2>

<p class="wp-block-paragraph">The flex container has many different properties that determine how objects are displayed, the first is the direction. Switch this to &quot;row&quot; to change the orientation of the three objects.</p>

<figure class="wp-block-image"><img decoding="async" alt="Change the flex container direction" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/6_flex_container_props.png"  /></figure>

<p class="wp-block-paragraph">Now our objects are in a row, but they are not the correct size. We want the button, enable, and numeric display to take up different amounts of space. Luckily, there are position properties on each object that can achieve this exact behavior.</p>

<figure class="wp-block-image"><img decoding="async" alt="Row oriented flex container" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/7_row_flex_container.png"  /></figure>

<p class="wp-block-paragraph">Select the button object and find the position properties in the property editor. The basis determines how much space the object &quot;wants&quot; to take up. It can be in percent (%) or pixels (px). Set the button basis to 20%, the enable label basis to 30%, and the numeric label to 50%.</p>

<figure class="wp-block-image"><img decoding="async" alt="Change the basis in the object's position props" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/8_flex_position_props.png"  /></figure>

<p class="wp-block-paragraph">The other parameters are shrink, which decides if the object should shrink if there isn&apos;t enough space, and grow, which decides if the object should grow to take up unallocated space. We do not need to adjust these.</p>

<p class="wp-block-paragraph">After adjusting the basis, each object takes up the allotted percentage of space.&nbsp;There is one final tweak: adding a margin to the button so it is spaced away&nbsp;from the edges and other components.&nbsp;</p>

<figure class="wp-block-image"><img decoding="async" alt="With proper basis settings, the elements look better" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/9_spaced_flex.png"  /></figure>

<p class="wp-block-paragraph">Select the button and find the &quot;style&quot; property in the property editor. Press the plus button to add a new style entry. Name it &quot;margin&quot; and set the value to 5px. Alternatively, you can click the style card icon button to graphically view and edit style definitions.&nbsp;</p>

<figure class="wp-block-image"><img decoding="async" alt="Add a margin to the button to space it from other components" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/11_add_margin.png"  /></figure>

<p class="wp-block-paragraph">With a margin on the button, our flex container view looks ready to go! All that&apos;s left to do is to&nbsp;add it to our main view.</p>

<figure class="wp-block-image"><img decoding="async" alt="That is a nice looking flex container!" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/12_final_result.png"  /></figure>

<h2 class="wp-block-heading">Embedding in Another View</h2>

<p class="wp-block-paragraph">Embedding views within other views is easy. Just find your desired view in the project browser, then drag it into your current&nbsp;view. Alternatively, you can grab an &quot;Embedded View&quot; object from the toolbox, then set the path parameter to your view&apos;s path. The embedded view now acts as a singular object.</p>

<figure class="wp-block-image"><img decoding="async" alt="Drag your embedded view into the main view" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/13_drag_into_main_view.png"  /></figure>

<p class="wp-block-paragraph">In this blog, we learned how to create an embedded view template and add it to another view. <a href="https://static.dmcinfo.com/latest-thinking/blog/id/10253/creating-dynamic-ignition-perspective-projects-part-4-parameters-indirect-bindings-and-flex-repeaters">In the next blog</a>, we will add parameters to this template so we can create multiple instances to get data from different sources!</p>

<p class="wp-block-paragraph"><strong>Learn more about DMC&apos;s&nbsp;<a href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/ignition-designer-programming">Ignition expertise</a>.&nbsp;&nbsp;<a href="https://static.dmcinfo.com/contact">Contact us</a>&nbsp;to get started on your next HMI, SCADA, or MES project.<br />
<br />
See other blogs in this series:&nbsp;</strong>Creating Dynamic Ignition Perspective Projects<br />
<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10250/creating-dynamic-ignition-perspective-projects-part-one-bindings-and-transforms">Part 1: Bindings and Transforms</a><br />
<a href="https://static.dmcinfo.com/latest-thinking/blog/id/10251/creating-dynamic-ignition-perspective-projects-part-2-button-event-actions">Part 2: Button Event Actions</a><br />
Part 3: Embedded Views and Flex Containers<br />
Part 4: View Parameters,&nbsp;Indirect Bindings, and Flex Repeaters<br />
Part 5: Flex Repeaters with Variable Number of Instances (coming soon)<br />
Part 6: Changing Colors and Other Properties (coming soon)</p>
<p>The post <a href="https://static.dmcinfo.com/blog/19104/creating-dynamic-ignition-perspective-projects-part-3-embedded-views-and-flex-containers/">Creating Dynamic Ignition Perspective Projects, Part 3: Embedded Views and Flex Containers</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
