Issuing NCMD/DCMD commands in Ignition

Hi,

What is the best method for issuing Sparkplug NCMD and DCMD commands using Ignition scripting?

These are typically issued by the Sparkplug module providing the tags in Ignition in response to things like changing an MQTT tag value.

You might be able to use the system.cirruslink.engine.publish scripting function to accomplish this.

What are you doing that requires publishing to these topics manually?

Hi Kevin,

The cirruslink command sounds promising, thanks for the prompt response.

My architecture allows any MQTT client to request command execution (through NDATA/DDATA) for another client, but I plan to have ACLs and filter commands using Ignition so it is in control what commands actually get published to NCMD or DCMD

Hi Kevin,

Does Ignition allow for Sparkplug Proto Bufs encoding with the system.cirruslink.engine.publish method?

The payload it accepts is an opaque byte[] but I don’t know if there is anything available to encode one with available on the class path.

Maybe @wes0johnson from Cirrus Link can tell you.

As Kevin noted the publish method will accept any byte[]. So, if you can import the protobuf library and Tahu Python library into the Ignition Python runtime it should work.

Sorry to bring up an old thread, but running Ignition 8.1.5 I've done the following:

(1) paste the following files to "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib"
From here (https://github.com/eclipse/tahu/tree/master/client_libraries/python)

  • sparkplug_b.py
  • sparkplug_b_pb2.py

from here (protobuf/python/google at main · protocolbuffers/protobuf · GitHub)

  • google/protobuf/*

(2) I have a script with the following:

	import sparkplug_b_pb2

Below is the error I get when I run the script:

File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\sparkplug_b_pb2.py", line 6, in from google.protobuf import descriptor as _descriptor File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\google\protobuf\descriptor.py", line 39, in import six ImportError: No module named six

Before I go adding various dependencies manually, is there a better way?

Better way to do what? This thread was not discussing anything that required trying to use external Python libraries.

To issue a NCMD or DCMD correctly (per sparkplug spec), a payload needs to be encoded using protobuf. To help the user scripting, the sparkplug_b library also helps create the MQTT packet. Per @wes0johnson recommendation above, I am attempting to import these libraries into Ignition for my script.

It looks like google protobuf needs other dependencies (it’s not self-contained?). Hence, my question. For example, there is no “pip” process to grab all the dependencies that are needed?

Ah, gotcha… should have read this a little closer. I thought the system.cirruslink.engine.publish ending up being the solution here.

I think you actually can pip install into the pylib directory… haven’t tried it myself: Procedure for installing python libraries from source - #2 by PGriffith

Below is what I get when I try and install the "protobuf" library.

I was able to run the same command using python 2.7 and it worked fine, but I get the following when I use the library that it created:

File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\google\protobuf\internal\decoder.py", line 92, in
SURROGATE_PATTERN = re.compile(six.u(r'[\ud800-\udfff]'))
File "C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\site-packages\six.py", line 674, in u
return unicode(s.replace(r'\', r'\\'), "unicode_escape")
File "user-lib\pylib\encodings_init
.py", line 142, in search_function
raise CodecRegistryError,
encodings.CodecRegistryError: incompatible codecs in module "encodings.unicode_escape" (C:\Program Files\Inductive Automation\Ignition\user-lib\pylib\encodings\unicode_escape$py.class)

Any suggestions?

The failure to install protobuf via pip is because pip is no longer usable for Jython 2.7. I was just fighting this earlier this week.

But for the bigger issue of generating NCMD/DCMD from Ignition, writing to the corresponding tag in Ignition has always worked fine for me. I don’t understand why you’re avoiding that and building raw MQTT payloads. Can you walk me through a simple use case flow of events that requires building a raw NCMD?

Thanks Justin.

I suppose the original post was not making use of the additional MQTT Engine.

For my case, I didn’t realize that modifying a tag within Ignition’s MQTT Engine would translate to an NCMD being generated and sent. Going that route works for my use-case.

By the way, it’s good to note that this feature of writing to a node is disabled by default within the MQTT Engine configuration:

image

1 Like