NetXMS Support Forum

English Support => General Support => Topic started by: twparker on March 08, 2024, 04:21:30 PM

Title: PDU SNMP Parsing
Post by: twparker on March 08, 2024, 04:21:30 PM
Hello all,

I have a PDU that I am trying to monitor power usage and temperature for, but the oid that I utilize for this purpose reports data in one long string string like this -

type=Master,,voltage=121.7,current=0.136,activePower=0.007,powerFactor=0.422,energy=2.893,temperature=23.3,humidity=30.7

What would be the best way to separate all of these data points into different DCIs?

Title: Re: PDU SNMP Parsing
Post by: Filipp Sudanov on March 08, 2024, 07:16:26 PM
This could be done with transformation scripts on a number of SNMP DCIs, but this is not convenient to manage, as transformation script on each of these DCis would be different. 

A cleaner approach would be to use script DCIs. In script library create a script, named e.g. getPduMetric with the following contents:

function main(oid, name) {
  transport = $node->createSNMPTransport();
  if (transport == null) return null;
  v = transport->getValue(oid);

  h = %{};
  for (a : v->split(",")) {
    b = a->split("=");
    if (b->size == 2) h[b] = b[1];
  }

  return h[name];
}

Then create a DCI on the node, origin should be Script. In the metric field we have name of the script with it's parameters:
getPduMetric(.1.3.6.1.2.1.1.1.0, activePower)

Script accepts two parameters - OID and variable name. This way you can have just one script and define everything in metric of your DCIs.
Title: Re: PDU SNMP Parsing
Post by: twparker on March 11, 2024, 08:45:05 PM
Thanks for the help, Filipp.

I tried to make a DCI with this script as the origin and I noticed that it keeps on disappearing from my Data Collection list a moment after hitting Apply and Close. Any suggestions?
Title: Re: PDU SNMP Parsing
Post by: Filipp Sudanov on March 13, 2024, 11:24:04 AM
Most probably your DCI became unsupported. If you right-click the list of DCIs, there's "show unsupported" in the context menu. Or you can switch to edit mode - there's pen icon above DCI list.

Check that DCI origin is set to script, check the name of the script. If you right-click your node and choose "execute script", you can run your script there to test if it returns some result. Script parameters, e.g. .1.3.6.1.2.1.1.1.0, activePower can be provided via parameters field.
Title: Re: PDU SNMP Parsing
Post by: twparker on March 15, 2024, 04:34:48 PM
So the error I got when I tried executing it was "Error 35 in line 10: Hash map key is not a string"

I thought I could just turn it into a string with

string(b);

However, I still get the above error.





Title: Re: PDU SNMP Parsing
Post by: Filipp Sudanov on March 15, 2024, 07:41:41 PM
is it this line?:
    if (b->size == 2) h[b] = b[1];
Try running your script via "Execute script" on your PDU node. You can add line like
    println(b);into your script, this way you'll see what exactly is contained in the variables. I'd start with checking of what comes in variable v, it could be that nothing just comes via snmp. Actually, transport->getValue() can return null if there's some problem, so after that line there should be a check for that:

    if (v == null) return null;
Title: Re: PDU SNMP Parsing
Post by: twparker on March 18, 2024, 09:07:29 PM
V returns a valid result namely the full OID value "type=Master,,voltage=121.0,current=0.000,activePower=0.000,powerFactor=1.000,energy=3.446,temperature=-1,humidity=-1

I thought the next function was stuck on the second comma because the only result I get for b is "type=Master" That led me to try this

function main(oid, name) {
  transport = $node->createSNMPTransport();
  if (transport == null) return null;
  v = transport->getValue(oid);
  z = string(v);
  x = substr(z, 13);


  h = %{};
  for (a : x->split(",")) {
    b = a->split("=");
 println(b);
    if (b->size == 2) h = b[1];
  }
    return h[name];
}


Apparently I can't change the value to a string before passing it to h.
Title: Re: PDU SNMP Parsing
Post by: Filipp Sudanov on March 19, 2024, 10:06:19 AM
Well, my bad, seems that I did not fully test the script that I've posted initially. It should be like this:

function main(oid, name) {
  transport = $node->createSNMPTransport();
  if (transport == null) return null;
  v = transport->getValue(oid);
  h = %{};
  for (a : v->split(",")) {
    b = a->split("=");
    if (b->size == 2) h[b[0]] = b[1];
  }
  return h[name];
}

The way it works - v->split(",") produces array where elements are "voltage=121.0" and so on. We loop through that array, so variable "a" has the value of each element of that array.
Now we need to split by "=" character and variable "b" becomes an array with two elements: [voltage, 121.0]. To access these elements we use index, so b[0] is "voltage" and b[1] is "121.0".
Now, h is a hashmap - sort of an array, but instead of numeric index elements are identified by string. We initialize it empty with h = %{}; And then we fill h with values with this code: h[b[0]] = b[1]; (and I now see the reason of the wrong code - forum editor is garbling the h[b[0]] part when pasting)
Title: Re: PDU SNMP Parsing
Post by: twparker on March 19, 2024, 04:56:04 PM
This works beautifully. Thanks so much, Filipp!