[Feedback] New Programmable Device Simulator

We are excited to announce a change to Ignition’s built-in simulator devices. In the latest nightly build a new device is available named Programmable Device Simulator that provides the ability to create your own simulator program with outputs you define.

Our thought when designing the new simulator functionality was users should be able to create tags that can be used in their own development process. Users need the flexibility to simulate devices with a tag structure they are building a project for.

We have included a number of built in functions that will result in tag outputs that hopefully meet your development needs. We have also provided the ability to set specific values at different points of the program should the functions not provide exactly what you need.

This functionality does replace the existing simulators that were included with Ignition. We have added the ability to quickly create the same simulators with this new functionality. If you happen to delete your existing simulator, adding a new Programmable Device Simulator and loading the same program will allow addresses within the device to map existing addresses.

Quick Start
The following instructions will setup the Dairy Simulator within the new Programmable Device Simulator:

  1. In your Gateway, navigate to Config > Device Connections
  2. Click Create new Device…
  3. Select Programmable Device Simulator
  4. Give the device a name of your choosing, note the properties that are available to modify
  5. Click button to save the device
  6. Open the More > edit device screen
  7. From the Load Program dropdown, select Dairy Simulator
  8. Click Load Simulator Program button
  9. Click Save Program button

Feel free to adjust the program before (or after) saving if you want to change some of the functionality.


  • Instruction File: A CSV with four columns:

    • Time Interval: Represents a “step” or point in time for the program. A program will start at interval 0, and set the Value Source on the tag. The program will wait for a number of milliseconds (determined by the Base Rate, defined below) before moving to the new Time Interval.
    • Browse Path: The full path to the tag you want to create in the simulator. Forward slashes are used to specify folders, as well as act as a delimiter for additional folders in the path.
    • Value Source: Determines how the value for the node at the Browse Path is generated. Either a static value or a function will be used to generate the value.
    • Data Type: The Data Type for this node. Valid types are:
      • boolean
      • int16
      • uint16
      • int32
      • uint32
      • int64
      • float
      • double
      • string
      • datetime
      • uint64 (Not all values fully supported by Ignition at this time)
  • Program: A runnable series of path configurations. The program can be imported via an Instruction File or manually entered/edited via the GUI. The program “runs” through the rows in the Instruction File. Each Program Device Simulator contains only 1 program.

  • Meta Tags: Each Programmable Device Simulator will have Meta Tags that allow users to interact with the program from the Designer/Session/Client. All tags will be listed under the parent folder [Controls] within the device. Altered Meta Tag values do not persist after restart. Meta tags provided:

    • Base Rate: The number of milliseconds determining how quickly the program should move between each Time Interval. The initial duration of the Base Rate is defined in the Program Device Simulator settings should you need this value to persist after restarts.
    • Pause: Setting this tag to True will stop the program at its current Time Interval. Setting it back to False will cause the program to resume from that point.
    • Program Counter: A count that tracks the Time Interval of the currently running program. This counter continues to increment for the duration of the program and resets when a program repeats.
    • Repeat: If True, the program will repeat indefinitely, meaning that once the last defined Time Interval has been reached, the program will start over again at Time Interval 0.
    • Reset: If True, the program is immediately reset to Time Interval 0 and the value will immediately change back to False.
  • Function: Users are allowed to define a “function” for the value source. This is not a Python or Expression function. Rather, the value in the cell is a string that looks like a function definition; eg., foo(x,x,x). The driver will attempt to parse the string, and then derive a value based on the function. Valid functions are:

    • sine
    • cosine
    • square
    • triangle
    • ramp
    • realistic
    • random
    • list
    • qv
    • readonly
  • Function Parameters: Values that are passed into a function. The following parameters may be available in functions:

    Parameter Definition Default Value
    min Minimum value for the function 0
    max Maximum value for the function 100
    period Represents a period of time as a number of Time Intervals. The default value of 10 represents “10 Time Intervals”. 10
    delta Allows users to determine the range of the number being added to a tag. A delta of 10 means “I’ll randomly pick a number between -10 and 10”. 10
    qualityCode Allows users to set the quality on a tag (assuming the function used contains a quality code parameter). Valid values are: Good, Bad, Uncertain Good
    repeat Does the function repeat for each time slice of the program, or does it report a single value when the instruction is run.The default value of true will ensure that a function will continue to run as long as the program itself is running. A value of false will only update a value when it reaches the specified Time Interval in the program true


Function Description
sine(min, max, period, repeat) Sine wave
cosine(min, max, period, repeat) Cosine wave
square(min, max, period, repeat) Square wave
triangle(min, max, period, repeat) Triangle wave
ramp(min, max, period, repeat) Ramping value. Similar to the ramp values in the Generic Simulator
realistic(setPoint, proportion, integral, derivative, repeat) PID-driven realistic number generator
random(min, max, repeat) Random number, falling between the min and max values
list(val1, val2, etc…, repeat) Accepts any number of parameters. While the program is running and on a step with this function, the function will walk through each value in this list. If list is boolean, the repeat value is a required parameter
qv(value, statusCode) Sets a value and quality code. Allows users to simulate a value with bad quality. Valid values for statusCode are “good”, “bad”, and “uncertain”.
readonly(value) Sets a static value that is read only.


  • Simple Function

    TimeInterval BrowsePath ValueSource DataType
    0 TagA sine(0,100,10,true) Double

    The table above shows us function usage with parameters. Because the example is using default values, it is functionally equivalent to the following:

    TimeInteval BrowsePath ValueSource DataType
    0 TagA sine() Double

    Running this program should yield the following results (assuming repeat is enabled):

    • A tag at root named “TagA” should be created.
    • Since only a single Time Interval was defined, the program ends quickly; the delta time between the start of the program and the end should be around one Base Rate interval.
    • The simulator will use a internal clock to ensure that the value reported is representative of the actual period for the function requested and if history is enabled, a full wave would be graphed.
  • Advanced Program

    TimeInterval BrowsePath ValueSource DataType
    0 TagA sine() Double
    0 myFolder/TagB 0 Int32
    3 myFolder/TagB 4 Int32
    4 another_folder/TagC 100 Int32
    20 TagA ramp() Double
    30 myFolder/TagB 55 Int32

    The program above should yield the following results:

    1. TagA is initialized with the Sine function.
    2. TagB (which is located under myFolder in the simulator’s structure) is initialized with a value of 0
    3. TagC isn’t defined at the start, but that doesn’t matter; the program creates a TagC initially because it will exist in the device. If this is the first time the program ran, then TagC started with a value of 0. If it is the second time through, it maintains the value at the end of the program until it reaches an interval where something changes.
    4. Time Interval 1. The program doesn’t state that any changes should be made, so we’re done evaluating this Time Interval.
    5. Time Interval 2. Again, nothing to do here, so we wait another Base Rate duration.
    6. Time Interval 3, the value on TagB to 4.
    7. Time Interval 4. The value of TagC changes to 100. If this program has executed at least once before, then TagC could already have a value of 100, since this is the only entry in the program that changes the value on Tag C. However, it is possible that the user (or something else, such as a binding or script) wrote another value to this tag. At this point, our program is setting the value back to 100
    8. Time Interval 20, TagA switches to the Ramp function. This whole time it has been using the Sine function to generate some moving numbers, but now we’re telling it to use the Ramp function, which change the value (starting with the minimum value for the function) and uses a different method to determine its value.
    9. Time Interval 30. The value of TagB changes to 55.
    10. We’re now at the end of the program. If Repeat was enabled, we’ll move back to Time Interval 0 and start the whole process over again. If not, then the program ends for all tags.

Note: The above is how the simulator should behave. We have a couple open issues where the simulator isn’t behaving correctly during a repeating program.


Running Version: 8.0.7 (b2019122014)
I was hoping to give it a try tonight but I don’t see “Programmable Device Simulator” when creating a new device.

Am I missing something?

It was released in an 8.0.8 Nightly unfortunately. You’ll have to upgrade in order to get the feature. 8.0.8 RC is out. I haven’t looked this week to see if a full release is out yet.

Thanks, I’ll wait for the full release.

I’m trying to get the realistic function to work, and it keeps going negative. I’m probably just not understanding it, but how do I just simulate a value to hover around a certain setpoint?

In looking at the Realistic function, I am seeing a couple things that we likely will want to tweak that is likely causing your problem.

The main issue I am seeing is the setPoint you are defining is getting overridden as the process runs without factoring in your defined setPoint. We need to change that as the target is moving all over the place.

The second issue looks to be our choice of default for the I value of the PID function. 0.06 is causing it to take upwards of 50 cycles to reverse the trend. Changing it to 0.01 has provided more accurate results until the setPoint gets changed out.

I will be creating a bug for the setPoint piece as that needs to get resolved and we will discuss internally if the defaults should be changed.



In talking with the product owners about what the intention of the realistic function is, they feel it is behaving as intended. We will be updating the language of the parameter though as setPoint is confusing. The change will likely be to rename the parameter startPoint so that it provides a little more clarity. There will also be minor behavior changes to make sure that the startPoint is indeed a startPoint when the program starts running.

I have created a separate feature ticket around your request as we do feel it is valid. In the meantime, you may want to consider using the random() function instead with narrow min & max values. While the graph might not be as nice, the values can be kept in the range you are looking for.


Could you add a feature to the OPC-UA Browse to be able to generate tags for the simulator to match a given device? This would really simplify things for us.

For the most part we aren’t using the simulator functionality, we just need the tags defined so we can maintain projects locally(On our Gateway) after all the hardware has been delivered to the customer. Without the possibility of impacting the customer while we are doing the maintenance.

Thank you,

1 Like

It is nice if we can combine two formula in source value.
For example sine()*ramp()