Heartbeat script having effects system wide

Written correctly it will do that too. HandShake as well as HeartBeat.

And the OP said he can still ping. For my largest project with over 100 device instances, I run a periodic ping and record the results to DB, then report a summary every day.

How can you detect loss of connection to Ignition using a heartbeat generated inside the PLC?

e.g. PLC counts to a certain value, once certain value is reached, Ignition resets back to 0.

If not reset within a certain time == comms loss.

Hadn’t thought of doing it that way! Unfortunately I rarely have control of my end devices so I probably won’t get too much opportunity to use it :frowning:

let’s wait to hear from @jdrichards70 to see how they’re trying to achieve this.

Something to add to the Spec’ for your OEM then :wink:

Eeek! No. Don't write from two directions. PLC should count and roll over. The low word of a PLC clock is fine. Ignition should count and roll over in its own timer event, writing to the appropriate OPC tag. Or write the low bits of Ignition's millisecond time to the OPC tag. It isn't important what the value is, just that it changes regularly.

Neither the OP nor @jdrichards70 shared their actual scripts, so there's no telling what the real problem is. Non-blocking writes should be used to prevent one broken device connection from killing the heartbeats to other device connections.

1 Like

That’s why I tagged you I knew you would have me sat-corrected :slight_smile:

My Field IO is generally Moxa IoLogik. I use an E1212 with a hardwired heartbeat Output back to an Input on the same module, with the Output set to pulse at 1000mS.

SCADA monitors/trends/alarms this and combined with my periodic ping mentioned above, I have a good idea of RIO/FIO outages. I know when SCADA is down because my mobile (cell) phone rings shortly after :stuck_out_tongue:

1 Like

I think it’s more than just my heartbeat issue. Once in a while, the operators will report the barcode scans are taking 30-60 seconds to show up on the HMI or a machine will pause for a bit waiting for something from Ignition. Everything on the network pings < 1ms while this happens.

script is stupid simple:

x = system.date.getSecond(system.date.now())

system.tag.write(“Corporate/Lincoln/Bay A/Line 4/Proof/Carousel 1/Heartbeat Count”, x)
system.tag.write(“Corporate/Lincoln/Bay A/Weld/Welder 2020/Welder/Heatbeat Tag”, x)

and I’ve even done this just to see what happens:
(runs every 2 seconds)
x = system.tag.read(“Corporate/Lincoln/Bay A/Weld/Welder 2020/Welder/Heatbeat Tag”).value
x = x + 1
if x > 59:
x = 0
else:
pass

system.tag.write(“Corporate/Lincoln/Bay A/Weld/Welder 2020/Welder/Heatbeat Tag”, x)

The OEM will change the code for me if a better way is out there, this is what the programmer wanted, he’s just looking for a change in the value every 10 seconds.

Thanks for the help.

Please use the Preformatted Text option (</> button) when posting scripts and error messages, as that will preserve formatting.

Sounds like you are running code in the foreground (GUI thread). Anything long-running should be in a separate thread (Invoked Async).

Hopefully @jdrichards70 can confirm that the scripting in question is configured as a Gateway script; agreed that you'd not want this in the client scope. Perhaps confirm your settings for the timer script?

@Matrix_Engineering - yes, thank you, I forgot the formatting, doh!. I can try async.

@Kevin.Collins - I tried fixed delay and fixed rate, same results. I am running with dedicated thread right now.

What would the proper or industry standard be for setting up the heartbeat? I usually just use the ‘is connected’ bit with the driver and this is the only machine I have had issues with…Siemens, arg!!! While my heartbeat dies, all the other real time data is coming through, so it’s not like the machine dropped offline or the driver locked up and I can manually change the tag value in a designer.

Hello, I had the same problem today.
I have 2 OPC server and when I disconnect one, I see the timer script slow down and not writing the heartbeat to the second one.
(They live in two completely separate timer script)

I receive an error ( I can’t share it at the moment ) in the system log saying that there was an error on the timer script code, even if there is no error.
The whole timer script is just a write on the tag.

I tested system.tag.write and system.tag.writeBlocking with the same outcome.

Coul I ask you which settings are the best for a simple and reliable heartbeat?

I don’t understand why this is happening even if I select dedicated thread.

I remember fixed delay and fixed rate was bugged, is it still the case?

Thanks

There was a bug in the OPC tag execution system that caused breakage on a single connection to hold up all tags on the same pace across all other OPC connections. I don’t recall what version it was fixed, but your case sounds suspiciously similar. What Ignition version are you using?

I will post the gateway and errors details on Monday as soon I will have a remote connection with the server.
The version is the 8.x.x.
One thing I’d like to understand is how scripts are managed.
For example, let’s assume we have this scenario:

2 plc tags with one script each, when the value change (udt tags with event change script):

  • A writeblock writing 2 booleans to PLC, resetting the request bit and setting an ack
  • an opc.read to retrieve the state of few tags
  • store some values on a database
  • writeblock to write an integer plus a bool to the plc with the result of the action performed

2 timer script, setting a boolean on the plc as heartbeat.

Now my question is, if for example we are in the situation when the timer script and the tag change event fire at the same time, will they be executed on their own thread or they will share the thread and so be executed one after another (with obvious writeblock time delay) ?

The same question bother me for consequential events being fired at the same time on multiple tag change scripts.
There is a difference between how ignition treat gateway tag change scripts vs udt tag change? Are they executed on the same thread?
In case a writeblock goes in timeout due to connection probelm, block all the other script of changing tags?

Would be nice if you can point me out some documentation about it,
Thankyou

That is not how you answer "What Ignition version are you using?" The rest of the digits matter.

1 Like

Haha, a bit like “what’s your address?” “I’m in Australia”

Sorry I probably have expressed myself in a wrong way.

As I mentioned I will post all the details on Monday as soon I will have a remote connection.

At the moment, as it is not my own projects, the only thing I can remember is that I’m working on a gateway version that is higher then 7.9.x, and I thoug that could be a useful information as maybe the bug mentioned above was fixed before 8.x.x

So the aim of my post was to ask clarification about my doubts that are not strictly related to the ignition version, waiting then to post the detail on Monday.

Sorry if my English is not so good and if someone sended mail at the wrong Australian address.

2 Likes

Gateway version : 8.1.0 (b2020110211)

The error i’m having is this one (running 2 separate timer scripts, shared - fixed delay performing a single writeblocking each on two separate opc servers. As soon one goes down, no write on the second is performed) :

Error during blocking write of tags through scripting.

java.util.concurrent.TimeoutException: null

at java.base/java.util.concurrent.CompletableFuture.timedGet(Unknown Source)

at java.base/java.util.concurrent.CompletableFuture.get(Unknown Source)

at com.inductiveautomation.ignition.gateway.script.GatewayTagUtilities.writeBlockingImpl(GatewayTagUtilities.java:237)

at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.writeBlocking(AbstractTagUtilities.java:408)

at jdk.internal.reflect.GeneratedMethodAccessor28.invoke(Unknown Source)

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.base/java.lang.reflect.Method.invoke(Unknown Source)

at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188)

at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:523)

at org.python.core.PyObject.__call__(PyObject.java:515)

at org.python.core.PyObject.__call__(PyObject.java:519)

at org.python.pycode._pyx99.f$0(:1)

at org.python.pycode._pyx99.call_function()

at org.python.core.PyTableCode.call(PyTableCode.java:171)

at org.python.core.PyCode.call(PyCode.java:18)

at org.python.core.Py.runCode(Py.java:1614)

at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:781)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:678)

at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:729)

at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runCode(ProjectScriptLifecycle.java:659)

at com.inductiveautomation.ignition.common.script.TimerScriptTask.run(TimerScriptTask.java:92)

at java.base/java.util.TimerThread.mainLoop(Unknown Source)

Gateway running on this vm :

Then i was wondering what can cause this warning i often see, and if is it something that i should try to fix:

Sounds like an upgrade would help you. From 8.1.3 changelog:

Use separate batches for writes to different OPC servers to prevent a slow-responding server from blocking an unrelated write to a fast-responding server.

2 Likes

Thank you very much Kevin,
I will upgrade then,
have a grate day