4 * CI -> OID mapping for SNMP Lite UPS driver
8 * Copyright (C) 2010 Adam Kropelin
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General
12 * Public License as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 #include "snmplite-common.h"
28 #include "rfc1628-oids.h"
32 static struct CiOidMap Rfc1628CiOidMap
[] =
34 // CI OID type dynamic?
35 {CI_UPSMODEL
, upsIdentModel
, OCTETSTRING
, false},
36 {CI_IDEN
, upsIdentName
, OCTETSTRING
, false},
37 {CI_REVNO
, upsIdentUPSSoftwareVersion
, OCTETSTRING
, false},
38 // {CI_MANDAT, upsAdvIdentDateOfManufacture, OCTETSTRING, false},
39 // {CI_BATTDAT, upsBasicBatteryLastReplaceDate, OCTETSTRING, false},
40 // {CI_NOMBATTV, upsAdvBatteryNominalVoltage, INTEGER, false},
41 {CI_NOMOUTV
, upsConfigOutputVoltage
, INTEGER
, false},
42 {CI_NOMINV
, upsConfigInputVoltage
, INTEGER
, false},
43 {CI_NOMPOWER
, upsConfigOutputPower
, INTEGER
, false},
44 {CI_LTRANS
, upsConfigLowVoltageTransferPoint
, INTEGER
, false},
45 {CI_HTRANS
, upsConfigHighVoltageTransferPoint
, INTEGER
, false},
46 // {CI_DWAKE, upsAdvConfigReturnDelay, TIMETICKS, false},
47 {CI_DALARM
, upsConfigAudibleStatus
, INTEGER
, false},
48 {CI_DLBATT
, upsConfigLowBattTime
, INTEGER
, false},
49 // {CI_DSHUTD, upsAdvConfigShutoffDelay, TIMETICKS, false},
50 // {CI_RETPCT, upsAdvConfigMinReturnCapacity, INTEGER, false},
51 // {CI_SENS, upsAdvConfigSensitivity, INTEGER, false},
52 // {CI_EXTBATTS, upsAdvBatteryNumOfBattPacks, INTEGER, false},
53 // {CI_STESTI, upsAdvTestDiagnosticSchedule, INTEGER, false},
54 {CI_VLINE
, upsInputTableInputVoltage
, SEQUENCE
, true },
55 {CI_VOUT
, upsOutputTableOutputVoltage
, SEQUENCE
, true },
56 {CI_VBATT
, upsBatteryVoltage
, INTEGER
, true },
57 {CI_FREQ
, upsInputTableInputFrequency
, SEQUENCE
, true },
58 {CI_LOAD
, upsOutputTableOutputPercentLoad
, SEQUENCE
, true },
59 {CI_ITEMP
, upsBatteryTemperature
, INTEGER
, true },
60 // {CI_ATEMP, mUpsEnvironAmbientTemperature, GAUGE, true },
61 // {CI_HUMID, mUpsEnvironRelativeHumidity, GAUGE, true },
62 {CI_ST_STAT
, upsTestResultsSummary
, INTEGER
, true },
63 {CI_BATTLEV
, upsEstimatedChargeRemaining
, INTEGER
, true },
64 {CI_RUNTIM
, upsEstimatedMinutesRemaining
, INTEGER
, true },
65 // {CI_WHY_BATT, upsAdvInputLineFailCause, INTEGER, true },
66 // {CI_BADBATTS, upsAdvBatteryNumOfBadBattPacks, INTEGER, true },
67 // {CI_VMIN, upsAdvInputMinLineVoltage, GAUGE, true },
68 // {CI_VMAX, upsAdvInputMaxLineVoltage, GAUGE, true },
69 {CI_STATUS
, upsOutputSource
, INTEGER
, true },
70 {CI_LowBattery
, upsBatteryStatus
, INTEGER
, true },
72 {-1, NULL
, false} /* END OF TABLE */
75 static void rfc1628_update_ci(UPSINFO
*ups
, int ci
, Snmp::Variable
&data
)
80 // We just take the voltage from the first input line and ignore the rest
81 Dmsg1(80, "Got CI_VLINE: %d\n", data
.seq
.begin()->u32
);
82 ups
->LineVoltage
= data
.seq
.begin()->u32
;
86 // We just take the voltage from the first input line and ignore the rest
87 Dmsg1(80, "Got CI_VOUT: %d\n", data
.seq
.begin()->u32
);
88 ups
->OutputVoltage
= data
.seq
.begin()->u32
;
92 Dmsg1(80, "Got CI_VBATT: %d\n", data
.u32
);
93 ups
->BattVoltage
= ((double)data
.u32
) / 10;
97 // We just take the freq from the first input line and ignore the rest
98 Dmsg1(80, "Got CI_FREQ: %d\n", data
.seq
.begin()->u32
);
99 ups
->LineFreq
= ((double)data
.seq
.begin()->u32
) / 10;
103 // MIB defines this as "The percentage of the UPS power capacity
104 // presently being used on this output line" so we should be able to
105 // add all these up to get a total load for the UPS as a whole.
106 // HOWEVER, manufacturers seem to actually be returning either the same
107 // value in each slot (APC implementation of RFC1628) or percent of
108 // power the line is capable of (Generex CS121 SNMP/WEB Adapter on a
109 // Newave Conceptpower DPA UPS). So we will average the values and hope
112 for (alist
<Snmp::Variable
>::iterator iter
= data
.seq
.begin();
113 iter
!= data
.seq
.end();
116 Dmsg1(80, "Got CI_LOAD: %d\n", iter
->u32
);
117 ups
->UPSLoad
+= iter
->u32
;
119 ups
->UPSLoad
/= data
.seq
.size();
123 Dmsg1(80, "Got CI_ITEMP: %d\n", data
.u32
);
124 ups
->UPSTemp
= data
.u32
;
128 Dmsg1(80, "Got CI_NOMOUTV: %d\n", data
.u32
);
129 ups
->NomOutputVoltage
= data
.u32
;
133 Dmsg1(80, "Got CI_NOMINV: %d\n", data
.u32
);
134 ups
->NomInputVoltage
= data
.u32
;
138 Dmsg1(80, "Got CI_NOMPOWER: %d\n", data
.u32
);
139 ups
->NomPower
= data
.u32
;
143 Dmsg1(80, "Got CI_LTRANS: %d\n", data
.u32
);
144 ups
->lotrans
= data
.u32
;
148 Dmsg1(80, "Got CI_HTRANS: %d\n", data
.u32
);
149 ups
->hitrans
= data
.u32
;
153 Dmsg1(80, "Got CI_ST_STAT: %d\n", data
.u32
);
157 ups
->testresult
= TEST_PASSED
;
159 case 2: /* Warning */
160 ups
->testresult
= TEST_WARNING
;
163 ups
->testresult
= TEST_FAILED
;
165 case 5: /* Test in progress */
166 ups
->testresult
= TEST_INPROGRESS
;
168 case 4: /* Aborted */
169 case 6: /* No test initiated */
170 ups
->testresult
= TEST_NONE
;
173 ups
->testresult
= TEST_UNKNOWN
;
179 Dmsg1(80, "Got CI_DALARM: %d\n", data
.u32
);
182 case 1: // Disabled ("None")
183 astrncpy(ups
->beepstate
, "N", sizeof(ups
->beepstate
));
185 case 2: // Enabled (T = 30 seconds...just a guess)
186 case 3: // Muted (but enabled)
188 astrncpy(ups
->beepstate
, "T", sizeof(ups
->beepstate
));
194 Dmsg1(80, "Got CI_UPSMODEL: %s\n", data
.str
.str());
195 astrncpy(ups
->upsmodel
, data
.str
, sizeof(ups
->upsmodel
));
199 Dmsg1(80, "Got CI_BATTLEV: %d\n", data
.u32
);
200 ups
->BattChg
= data
.u32
;
204 Dmsg1(80, "Got CI_RUNTIM: %d\n", data
.u32
);
205 ups
->TimeLeft
= data
.u32
;
209 Dmsg1(80, "Got CI_IDEN: %s\n", data
.str
.str());
210 astrncpy(ups
->upsname
, data
.str
, sizeof(ups
->upsname
));
214 Dmsg1(80, "Got CI_STATUS: %d\n", data
.u32
);
215 /* Clear the following flags: only one status will be TRUE */
236 case 2: /* output turned off */
238 default: /* unknown */
244 Dmsg1(80, "Got CI_LowBattery: %d\n", data
.u32
);
250 ups
->clear_battlow();
260 Dmsg1(80, "Got CI_REVNO: %s\n", data
.str
.str());
261 astrncpy(ups
->firmrev
, data
.str
, sizeof(ups
->firmrev
));
265 Dmsg1(80, "Got CI_DLBATT: %d\n", data
.u32
);
266 ups
->dlowbatt
= data
.u32
;
271 static int rfc1628_killpower(UPSINFO
*ups
)
273 struct snmplite_ups_internal_data
*sid
=
274 (struct snmplite_ups_internal_data
*)ups
->driver_internal_data
;
276 // Configure UPS to turn off output only (not entire UPS)
277 Snmp::Variable shutdownType
= { Asn::INTEGER
, 1 };
278 sid
->snmp
->Set(upsShutdownType
, &shutdownType
);
280 // Configure UPS to automatically restart when power is restored
281 Snmp::Variable autoRestart
= { Asn::INTEGER
, 1 };
282 sid
->snmp
->Set(upsAutoRestart
, &autoRestart
);
284 // Instruct UPS to turn off after 60 secs
285 Snmp::Variable shutdownDelay
= { Asn::INTEGER
, 60 };
286 sid
->snmp
->Set(upsShutdownAfterDelay
, &shutdownDelay
);
291 static int rfc1628_shutdown(UPSINFO
*ups
)
293 struct snmplite_ups_internal_data
*sid
=
294 (struct snmplite_ups_internal_data
*)ups
->driver_internal_data
;
296 // Configure UPS to turn off entire system
297 Snmp::Variable shutdownType
= { Asn::INTEGER
, 2 };
298 sid
->snmp
->Set(upsShutdownType
, &shutdownType
);
300 // Configure UPS to NOT automatically restart when power is restored
301 Snmp::Variable autoRestart
= { Asn::INTEGER
, 2 };
302 sid
->snmp
->Set(upsAutoRestart
, &autoRestart
);
304 // Instruct UPS to turn off after 60 secs
305 Snmp::Variable shutdownDelay
= { Asn::INTEGER
, 60 };
306 sid
->snmp
->Set(upsShutdownAfterDelay
, &shutdownDelay
);
311 // Export strategy to snmplite.cpp
312 struct MibStrategy Rfc1628MibStrategy
=