Create UDT OK, when I create an Instance, structure is invalid

Hi Everyone,

I have created several UDT's and they are working great. Today I created a new one but things went bad.

Here is my UDT:

Here is my instance:

If I export my UDT structure, it is populated like so:

If I export my newly created Instance, It is essentially Un-populated:

The only time it populates, is when I override the UDT and apply/save.
I now have to override all the parameters in the UDT with the SAME OPC Item Path, and it will populate/work, but everything is "over-ridden". Why must I do this?

Is this a bug?

Thanks!

Please post formatted code, not pictures of code. Please see Wiki - how to post code on this forum.

1 Like

I was merely showing examples of what is going on, for brevity.

However, if you want to see all, the code is as follows:

Original UDT:

{
  "typeColor": -16711936,
  "name": "Motor Starter",
  "parameters": {
    "TagNum": {
      "dataType": "Integer",
      "value": 0
    }
  },
  "tagType": "UdtType",
  "tags": [
    {
      "valueSource": "opc",
      "historyTimeDeadband": 10,
      "historyMaxAge": 1,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Sts_Running",
      "dataType": "Boolean",
      "historyProvider": "Tag_History",
      "historicalDeadbandStyle": "Discrete",
      "name": "Sts_Running",
      "historyEnabled": true,
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Alm_FailToStart",
      "dataType": "Boolean",
      "alarms": [
        {
          "setpointA": 1.0,
          "activePipeline": "ShawHMI/Alarms",
          "CustomEmailMessage": "{[.]Cfg_Label}+\" Fail to Start Alarm\"",
          "name": "Alarm",
          "priority": "High",
          "label": {
            "bindType": "Expression",
            "value": "{[.]Cfg_Label}+\" Fail to Start Alarm\""
          }
        }
      ],
      "name": "Alm_FailToStart",
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_Starts",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Int4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_Starts",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Alm_FailToStop",
      "dataType": "Boolean",
      "alarms": [
        {
          "setpointA": 1.0,
          "activePipeline": "ShawHMI/Alarms",
          "CustomEmailMessage": "{[.]Cfg_Label}+\" Fail to Stop Alarm\"",
          "name": "Alarm",
          "label": "{[.]Cfg_Label}+\" Fail to Stop Alarm\"",
          "priority": "High"
        }
      ],
      "name": "Alm_FailToStop",
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_DayStarts",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Int4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_DayStarts",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_MaxRunHrs",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Float4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_MaxRunHrs",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_PrevStarts",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Int4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_PrevStarts",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyTimeDeadband": 10,
      "historyMaxAge": 1,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Sts_Stopped",
      "dataType": "Boolean",
      "historyProvider": "Tag_History",
      "historicalDeadbandStyle": "Discrete",
      "name": "Sts_Stopped",
      "historyEnabled": true,
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Cfg_Label",
      "dataType": "String",
      "name": "Cfg_Label",
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_PrevRunHrs",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Float4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_PrevRunHrs",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_CurRunHrs",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Float4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_CurRunHrs",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_DayRunHrs",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Float4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_DayRunHrs",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Cfg_HasFailToStopAlm",
      "dataType": "Boolean",
      "name": "Cfg_HasFailToStopAlm",
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Cfg_HasFailToStartAlm",
      "dataType": "Boolean",
      "name": "Cfg_HasFailToStartAlm",
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "opc",
      "historyMaxAge": 10,
      "opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}_Runtime.Val_TotRunHrs",
      "historicalDeadband": 0.1,
      "historySampleRateUnits": "HOUR",
      "tagType": "AtomicTag",
      "dataType": "Float4",
      "historyProvider": "Tag_History",
      "historyMaxAgeUnits": "MIN",
      "name": "Val_TotRunHrs",
      "historyEnabled": true,
      "sampleMode": "Periodic",
      "historySampleRate": 1,
      "opcServer": "Ignition OPC UA Server"
    }
  ]
}

Inherited from UDT:

{
  "name": "EQ_P101",
  "typeId": "Motor Starter",
  "parameters": {
    "TagNum": {
      "dataType": "String",
      "value": "101"
    }
  },
  "tagType": "UdtInstance",
  "tags": [
    {
      "name": "Val_DayStarts",
      "tagType": "AtomicTag"
    },
    {
      "name": "Cfg_HasFailToStartAlm",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_PrevStarts",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_DayRunHrs",
      "tagType": "AtomicTag"
    },
    {
      "name": "Sts_Running",
      "tagType": "AtomicTag"
    },
    {
      "name": "Sts_Stopped",
      "tagType": "AtomicTag"
    },
    {
      "opcItemPath": {
        "bindType": "parameter",
        "binding": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Alm_FailToStart"
      },
      "name": "Alm_FailToStart",
      "tagType": "AtomicTag"
    },
    {
      "name": "Cfg_Label",
      "tagType": "AtomicTag"
    },
    {
      "name": "Cfg_HasFailToStopAlm",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_TotRunHrs",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_PrevRunHrs",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_Starts",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_CurRunHrs",
      "tagType": "AtomicTag"
    },
    {
      "name": "Val_MaxRunHrs",
      "tagType": "AtomicTag"
    },
    {
      "name": "Alm_FailToStop",
      "tagType": "AtomicTag"
    }
  ]
}
1 Like

From the files, in the Def your "TagNum" parameter is an INT, but in the Instance you changed the Data Type to string, perhaps unintentionally?

Go to the instance > Param > Click the Green dot , to remove the overrides, then set the value to a valid value. This likely resolves it.

I changed that only because another UDT that worked had that structure.

I tried making this one easier to follow by allowing the entire tag name "P_101" in lieu of "TagName" variable of "101" with hard-coded "P_" in the UDT.

Anyway, neither method is working at the moment.

Drill down in your tag browser and see how the opc tags are being generated. That should give you a hint as to what might be wrong.

Nothing seems out of the ordinary. It involves tag substitution in the OPC path. If I direct link the tag, it works fine. Once I put my tag substitution back in, it fails.

Can you screenshot the opcitempath of one of the tags?

Nevermind, this is the issue:

"opcItemPath": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Sts_Running",

In the UDT instance this resolved to literally that string - it's not a binding/expression with dynamic parts; the {TagNum} is static, not a binding. It looks like you did a simple find/replace from notepad to add in those parameterisations.

Bindings need to be like this instead:

"opcItemPath": {
   "bindType": "parameter",
   "binding": "ns\u003d1;s\u003d[MCP]EQ_P{TagNum}.Sts_Running"
}

In my opinion, the tag import tool / paste json should automatically convert this for you, as this trips up a lot of people! and really, I'm 99% sure that you can't use these braces statically within these paths anyway, so there's no reason they shouldn't be auto-converted.

However the easy way to spot this is, if your UDT Instance tag's opcitempath has { } in them, then that's the likely cause. These should be resolved paths, not still have "dynamic" parts in them.

I added a feature request: [FEATURE] Auto-convert relevant UDT Type tag prop values with {..} in them to bindings

1 Like

While IA doesn't use them for their own drivers, they are not forbidden in OPC Node IDs. So, some random OPC server could expect them.

3 Likes

OK, I'm understanding this a lot better.

What works for now is I bring the OPC item(s) I need into my UDT. I create my "TagName" parameter. I then find the tag identifier from the element import(s), highlight it manually with the mouse (I can double-click and it highlights just the tag!), and click the chain-link to BIND to my parameter called "TagName", hit ENTER.

Do this for the remainder of UDT and it works perfectly..

I believe a proper export to .json for find/replace, would be ever so handy. I think Ignition doesn't bind the initial elements by default.

Or just run a script over your tag json copied to your clipboard and convert them from strings to the bindings structure, then you can reuse it again an snot potentially miss any