[Solved] [Commit needed] SNMP Binding v2 is ignoring enterprise oid (V1TRAP data)

Hello people,
I’m trying to add ups via snmp addin to OpenHAB (I don’t want to use NUT or other intermediate apps).
The ups is eaton (via network-card-ms), but it should be comparable to all other ups-es.
This ups can use V1 and V3 protocol, so I choose V1 (as addon does not support V3). The OID 1.3.6.1.2.1.33.2 is trap for upsTrapOnBattery - that’s what i’m trying to catch.

This is tcpdump of snmp message when ups switches to battery:

Trap(52) E:33.2 192.168.2.244 enterpriseSpecific s=4 12154446 system.sysUptime.0=12154446 1.3.6.1.2.1.33.1.6.2.1.1.0 = 5 1.3.6.1.2.1.33.1.6.2.1.2.0 = 1.3.6.1.2.1.33.1.6.3.6

Please ignore other variables (it is alarm type and name).
Here is OpenHAB SNMP log:

[TRACE] [nding.snmp.internal.SnmpTargetHandler] - snmp:target:ups received trap CommandResponderEvent[securityModel=1, securityLevel=1, maxSizeResponsePDU=65535, pduHandle=PduHandle[0], stateReference=StateReference[msgID=0,pduHandle=PduHandle[0],securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=V1TRAP[reqestID=0,timestamp=1 day, 6:48:22.12,enterprise=1.3.6.1.2.1.33.2,genericTrap=6,specificTrap=4, VBS[1.3.6.1.2.1.1.3.0 = 1 day, 6:48:22.12; 1.3.6.1.2.1.33.1.6.2.1.1.0 = 5; 1.3.6.1.2.1.33.1.6.2.1.2.0 = 1.3.6.1.2.1.33.1.6.3.6]], messageProcessingModel=0, securityName=public, processed=false, peerAddress=192.168.2.244/33422, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@105c26c, tmStateReference=null]
[DEBUG] [nding.snmp.internal.SnmpTargetHandler] - received value 5 for unknown OID 1.3.6.1.2.1.33.1.6.2.1.1.0, skipping

The enterprise oid & value are received by snmp addon, but they are ignored further down the message queue:

This is from SnmpTargetHandler.java

if ((pdu.getType() == PDU.TRAP || pdu.getType() == PDU.V1TRAP) && config.community.equals(community)
                && targetAddressString.equals(address)) {
            pdu.getVariableBindings().forEach(variable -> {
                OID oid = variable.getOid();
                Variable value = variable.getVariable();
                updateChannels(oid, value, trapChannelSet);
            });

So here is my question/concern: Am I doing something wrong (i have this OID in .things file, but according to the code above, OH ignores enterprise OID), or i should change snmp source code, in order to include enterprise OID in updateChannels? I think that SNMP binding is not using PDUv1 class (but PDU), so code change might not be so trivial?
Any other possibilities to catch upsTrapOnBattery?

I‘m not sure what the problem is. Can you show the thing/channel definition and describe what exactly you want to happen and what is happening instead?

Hi Jan,
I’m happy that you are here - I see that you are in snmp dev list :slight_smile:

I want to use rule on “upsBattery” (from snmp.items below) - to do some stuff when mains voltage fails.
The problem is that from snmp trap message, only upsUptime is populated and upsBattery remains NULL. upsUptime is one of Variable Bindings passed to the event (other two are not relevant - if i had thing/item for them, they will be populated also).
It’s not an option to rely on upsUptime as trigger for the rule, because the ups sends other traps also.
To me it looks like either binding ignores “enterprise”,“genericTrap”,“specificTrap” from the PDU or the ups ‘forgets’ to send them as variables. I don’t know which is the correct behaviour.
Just to note that “enterprise”,“genericTrap”,“specificTrap” are available only in V1TRAP type of PDU - that is PDUv1 class from snmp4j.

snmp.things:

Thing snmp:target:ups [hostname="192.168.2.244", protocol="v1"]{
    Channels:
        Type number : ups_onBattery [ oid="1.3.6.1.2.1.33.2.0", mode="TRAP" ]
        Type string : ups_Name [oid="1.3.6.1.2.1.1.1.0", mode="READ", datatype="STRING"]
        Type number : ups_Temperature [oid="1.3.6.1.4.1.534.1.6.5.0", mode="READ", datatype="UINT32"]
        Type number : BatLevel [oid="1.3.6.1.4.1.705.1.5.2.0", mode="READ", datatype="UINT32"]
        Type number : ups_Uptime [oid="1.3.6.1.2.1.1.3.0", mode="TRAP"]
}

snmp.items:

Number upsBattery "UPS on battery [%s]" {channel="snmp:target:ups:ups_onBattery"}
Number upsTemperature "UPS Temperature [%d]" {channel="snmp:target:ups:ups_Temperature"}
Number upsBatlevel "Battery [%d]" {channel="snmp:target:ups:ups_BatLevel"}
String upsName "UPS: [%s]" {channel="snmp:target:ups:ups_Name"}
Number upsUptime "UPS Uptime [%f]" {channel="snmp:target:ups:ups_Uptime"}

Edit: That is what I finally did:
in SnmpTargetHandler.java:

import snmp4j.PDUv1; //in the import section
//In processPDU(), before or after " if ((pdu.getType() == PDU.TRAP || pdu.getType() == PDU.V1TRAP) && config.community.equals(community)"
if ((pdu.getType()==PDU.V1Trap)&&(config.community.equals(community))&&(pdu instanceof PDUv1))
{
                logger.trace("{} PDU is instance of PDUv1",thing.getUID());
                PDUv1 pduv1= (PDUv1)pdu;
                int etrap=pduv1.getGenericTrap();
                if(etrap==6) etrap=pduv1.getSpecificTrap();
                updateChannels(pduv1.getEnterprise(),new UnsignedInteger32(etrap); ,trapChannelSet);           
}

Recompiled from sources & put into addon folder…
The result is:

03:07:47.447 [TRACE] [nding.snmp.internal.SnmpTargetHandler] - snmp:target:ups received trap CommandResponderEvent[securityModel=1, securityLevel=1, maxSizeResponsePDU=65535, pduHandle=PduHandle[0], stateReference=StateReference[msgID=0,pduHandle=PduHandle[0],securityEngineID=null,securityModel=null,securityName=public,securityLevel=1,contextEngineID=null,contextName=null,retryMsgIDs=null], pdu=V1TRAP[reqestID=0,timestamp=4 days, 11:21:57.00,enterprise=1.3.6.1.2.1.33.2,genericTrap=6,specificTrap=3, VBS[1.3.6.1.2.1.1.3.0 = 4 days, 11:21:57.00; 1.3.6.1.2.1.33.1.6.2.1.1.0 = 9; 1.3.6.1.2.1.33.1.6.2.1.2.0 = 1.3.6.1.2.1.33.1.6.3.2]], messageProcessingModel=0, securityName=public, processed=false, peerAddress=192.168.2.244/39041, transportMapping=org.snmp4j.transport.DefaultUdpTransportMapping@64fef61b, tmStateReference=null]
03:07:47.465 [TRACE] [nding.snmp.internal.SnmpTargetHandler] - snmp:target:ups PDU is instance of PDUv1
03:07:47.469 [DEBUG] [nding.snmp.internal.SnmpTargetHandler] - received value 3 for unknown OID 1.3.6.1.2.1.33.2, skipping
03:07:47.477 [DEBUG] [nding.snmp.internal.SnmpTargetHandler] - received value 9 for unknown OID 1.3.6.1.2.1.33.1.6.2.1.1.0, skipping

The only thing that bothers me, is that maybe it is better to have some combination of GenericTrap and SpecificTrap (sum;negative SpecificTrap; string???)
Now I can process traps correctly - after editing things/items relevant OIDs (1.3.6.1.2.1.33.2 in my case)

@J-N-K, if you agree with the code, can you insert it in the official sources?

Thanks

I’m not super familiar with UPS and SNMP MIBs, but the one you referenced doesn’t have a .0 at the end, finding this page - http://www.oidview.com/mibs/0/UPS-MIB.html it should be a .1 instead?

upsTraps upsTraps 1.3.6.1.2.1.33.2 OBJECT IDENTIFIER
upsTrapOnBattery upsTrapOnBattery 1.3.6.1.2.1.33.2.1 NOTIFICATION-TYPE

Yep, this .0 was leftover from other items (I was trying to catch other trap VBS).

But the problem was missing handling of V1TRAP enterprise OIDs in the code. I will try to catch 2.5 deadline for improvements :slight_smile:

Hi @Vlad1024

did you solve it? how?

I’m trying to collect from the same OID .1.3.6.1.4.1.534.1.6.5.0, but I’m not able to do.

see:

Any suggestion would be appreciated.

Andrea

Not sure I’m able to recompile from source and put into add-on folder :slight_smile:

Can you please share the jar with the fix to put in the add-on folder?

@J-N-K shall we have the fixed version in the stable branch?

thanks
Andrea