UPS: apcupsd clean sources
[tomato.git] / release / src / router / apcupsd / src / drivers / snmplite / apc-mib.cpp
blob87ca1c2cd672dd483af0a3b5ffd3f78a2f13b8ac
1 /*
2 * mib.cpp
4 * CI -> OID mapping for SNMP Lite UPS driver
5 */
7 /*
8 * Copyright (C) 2009 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,
22 * MA 02111-1307, USA.
25 #include "apc.h"
26 #include "snmplite-common.h"
27 #include "mibs.h"
28 #include "apc-oids.h"
30 using namespace Asn;
32 static struct CiOidMap CiOidMap[] =
34 // CI OID type dynamic?
35 {CI_UPSMODEL, upsBasicIdentModel, OCTETSTRING, false},
36 {CI_SERNO, upsAdvIdentSerialNumber, OCTETSTRING, false},
37 {CI_IDEN, upsBasicIdentName, OCTETSTRING, false},
38 {CI_REVNO, upsAdvIdentFirmwareRevision, OCTETSTRING, false},
39 {CI_MANDAT, upsAdvIdentDateOfManufacture, OCTETSTRING, false},
40 {CI_BATTDAT, upsBasicBatteryLastReplaceDate, OCTETSTRING, false},
41 {CI_NOMBATTV, upsAdvBatteryNominalVoltage, INTEGER, false},
42 {CI_NOMOUTV, upsAdvConfigRatedOutputVoltage, INTEGER, false},
43 {CI_LTRANS, upsAdvConfigLowTransferVolt, INTEGER, false},
44 {CI_HTRANS, upsAdvConfigHighTransferVolt, INTEGER, false},
45 {CI_DWAKE, upsAdvConfigReturnDelay, TIMETICKS, false},
46 {CI_AlarmTimer, upsAdvConfigAlarmTimer, TIMETICKS, false}, // Must be before CI_DALARM
47 {CI_DALARM, upsAdvConfigAlarm, INTEGER, false},
48 {CI_DLBATT, upsAdvConfigLowBatteryRunTime, TIMETICKS, 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, upsAdvInputLineVoltage, GAUGE, true },
55 {CI_VOUT, upsAdvOutputVoltage, GAUGE, true },
56 {CI_VBATT, upsAdvBatteryActualVoltage, INTEGER, true },
57 {CI_FREQ, upsAdvInputFrequency, GAUGE, true },
58 {CI_LOAD, upsAdvOutputLoad, GAUGE, true },
59 {CI_ITEMP, upsAdvBatteryTemperature, GAUGE, true },
60 {CI_ATEMP, mUpsEnvironAmbientTemperature, GAUGE, true },
61 {CI_HUMID, mUpsEnvironRelativeHumidity, GAUGE, true },
62 {CI_ST_STAT, upsAdvTestDiagnosticsResults, INTEGER, true },
63 {CI_BATTLEV, upsAdvBatteryCapacity, GAUGE, true },
64 {CI_RUNTIM, upsAdvBatteryRunTimeRemaining, TIMETICKS, 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 },
70 // These 5 collectively are used to obtain the data for CI_STATUS.
71 // All bits are available in upsBasicStateOutputState at once but
72 // the old AP960x cards do not appear to support that OID, so we use
73 // it only for the overload flag which is not available elsewhere.
74 {CI_STATUS, upsBasicOutputStatus, INTEGER, true },
75 {CI_NeedReplacement, upsAdvBatteryReplaceIndicator, INTEGER, true },
76 {CI_LowBattery, upsBasicBatteryStatus, INTEGER, true },
77 {CI_Calibration, upsAdvTestCalibrationResults, INTEGER, true },
78 {CI_Overload, upsBasicStateOutputState, OCTETSTRING, true },
80 {-1, NULL, false} /* END OF TABLE */
83 #define TIMETICKS_TO_SECS 100
84 #define SECS_TO_MINS 60
86 static void apc_update_ci(UPSINFO *ups, int ci, Snmp::Variable &data)
88 static unsigned int alarmtimer = 0;
90 switch (ci)
92 case CI_VLINE:
93 Dmsg1(80, "Got CI_VLINE: %d\n", data.u32);
94 ups->LineVoltage = data.u32;
95 break;
97 case CI_VOUT:
98 Dmsg1(80, "Got CI_VOUT: %d\n", data.u32);
99 ups->OutputVoltage = data.u32;
100 break;
102 case CI_VBATT:
103 Dmsg1(80, "Got CI_VBATT: %d\n", data.u32);
104 ups->BattVoltage = data.u32;
105 break;
107 case CI_FREQ:
108 Dmsg1(80, "Got CI_FREQ: %d\n", data.u32);
109 ups->LineFreq = data.u32;
110 break;
112 case CI_LOAD:
113 Dmsg1(80, "Got CI_LOAD: %d\n", data.u32);
114 ups->UPSLoad = data.u32;
115 break;
117 case CI_ITEMP:
118 Dmsg1(80, "Got CI_ITEMP: %d\n", data.u32);
119 ups->UPSTemp = data.u32;
120 break;
122 case CI_ATEMP:
123 Dmsg1(80, "Got CI_ATEMP: %d\n", data.u32);
124 ups->ambtemp = data.u32;
125 break;
127 case CI_HUMID:
128 Dmsg1(80, "Got CI_HUMID: %d\n", data.u32);
129 ups->humidity = data.u32;
130 break;
132 case CI_NOMBATTV:
133 Dmsg1(80, "Got CI_NOMBATTV: %d\n", data.u32);
134 ups->nombattv = data.u32;
135 break;
137 case CI_NOMOUTV:
138 Dmsg1(80, "Got CI_NOMOUTV: %d\n", data.u32);
139 ups->NomOutputVoltage = data.u32;
140 break;
142 case CI_NOMINV:
143 Dmsg1(80, "Got CI_NOMINV: %d\n", data.u32);
144 ups->NomInputVoltage = data.u32;
145 break;
147 case CI_NOMPOWER:
148 Dmsg1(80, "Got CI_NOMPOWER: %d\n", data.u32);
149 ups->NomPower = data.u32;
150 break;
152 case CI_LTRANS:
153 Dmsg1(80, "Got CI_LTRANS: %d\n", data.u32);
154 ups->lotrans = data.u32;
155 break;
157 case CI_HTRANS:
158 Dmsg1(80, "Got CI_HTRANS: %d\n", data.u32);
159 ups->hitrans = data.u32;
160 break;
162 case CI_DWAKE:
163 Dmsg1(80, "Got CI_DWAKE: %d\n", data.u32);
164 ups->dwake = data.u32;
165 break;
167 case CI_ST_STAT:
168 Dmsg1(80, "Got CI_ST_STAT: %d\n", data.u32);
169 switch (data.u32)
171 case 1: /* Passed */
172 ups->testresult = TEST_PASSED;
173 break;
174 case 2: /* Failed */
175 case 3: /* Invalid test */
176 ups->testresult = TEST_FAILED;
177 break;
178 case 4: /* Test in progress */
179 ups->testresult = TEST_INPROGRESS;
180 break;
181 default:
182 ups->testresult = TEST_UNKNOWN;
183 break;
185 break;
187 case CI_AlarmTimer:
188 Dmsg1(80, "Got CI_AlarmTimer: %d\n", data.u32);
189 // Remember alarm timer setting; we will use it for CI_DALARM
190 alarmtimer = data.u32;
191 break;
193 case CI_DALARM:
194 Dmsg1(80, "Got CI_DALARM: %d\n", data.u32);
195 switch (data.u32)
197 case 1: // Timed (uses CI_AlarmTimer)
198 if (ups->UPS_Cap[CI_AlarmTimer] && alarmtimer < 30)
199 astrncpy(ups->beepstate, "0", sizeof(ups->beepstate)); // 5 secs
200 else
201 astrncpy(ups->beepstate, "T", sizeof(ups->beepstate)); // 30 secs
202 break;
203 case 2: // LowBatt
204 astrncpy(ups->beepstate, "L", sizeof(ups->beepstate));
205 break;
206 case 3: // None
207 astrncpy(ups->beepstate, "N", sizeof(ups->beepstate));
208 break;
209 default:
210 astrncpy(ups->beepstate, "T", sizeof(ups->beepstate));
211 break;
213 break;
215 case CI_UPSMODEL:
216 Dmsg1(80, "Got CI_UPSMODEL: %s\n", data.str.str());
217 astrncpy(ups->upsmodel, data.str, sizeof(ups->upsmodel));
218 break;
220 case CI_SERNO:
221 Dmsg1(80, "Got CI_SERNO: %s\n", data.str.str());
222 astrncpy(ups->serial, data.str, sizeof(ups->serial));
223 break;
225 case CI_MANDAT:
226 Dmsg1(80, "Got CI_MANDAT: %s\n", data.str.str());
227 astrncpy(ups->birth, data.str, sizeof(ups->birth));
228 break;
230 case CI_BATTLEV:
231 Dmsg1(80, "Got CI_BATTLEV: %d\n", data.u32);
232 ups->BattChg = data.u32;
233 break;
235 case CI_RUNTIM:
236 Dmsg1(80, "Got CI_RUNTIM: %d\n", data.u32);
237 ups->TimeLeft = data.u32 / TIMETICKS_TO_SECS / SECS_TO_MINS;
238 break;
240 case CI_BATTDAT:
241 Dmsg1(80, "Got CI_BATTDAT: %s\n", data.str.str());
242 astrncpy(ups->battdat, data.str, sizeof(ups->battdat));
243 break;
245 case CI_IDEN:
246 Dmsg1(80, "Got CI_IDEN: %s\n", data.str.str());
247 astrncpy(ups->upsname, data.str, sizeof(ups->upsname));
248 break;
250 case CI_STATUS:
251 Dmsg1(80, "Got CI_STATUS: %d\n", data.u32);
252 /* Clear the following flags: only one status will be TRUE */
253 ups->clear_online();
254 ups->clear_onbatt();
255 ups->clear_boost();
256 ups->clear_trim();
257 switch (data.u32) {
258 case 2:
259 ups->set_online();
260 break;
261 case 3:
262 ups->set_onbatt();
263 break;
264 case 4:
265 ups->set_online();
266 ups->set_boost();
267 break;
268 case 12:
269 ups->set_online();
270 ups->set_trim();
271 break;
272 case 1: /* unknown */
273 case 5: /* timed sleeping */
274 case 6: /* software bypass */
275 case 7: /* UPS off */
276 case 8: /* UPS rebooting */
277 case 9: /* switched bypass */
278 case 10: /* hardware failure bypass */
279 case 11: /* sleeping until power returns */
280 default: /* unknown */
281 break;
283 break;
285 case CI_NeedReplacement:
286 Dmsg1(80, "Got CI_NeedReplacement: %d\n", data.u32);
287 if (data.u32 == 2)
288 ups->set_replacebatt();
289 else
290 ups->clear_replacebatt();
291 break;
293 case CI_LowBattery:
294 Dmsg1(80, "Got CI_LowBattery: %d\n", data.u32);
295 if (data.u32 == 3)
296 ups->set_battlow();
297 else
298 ups->clear_battlow();
299 break;
301 case CI_Calibration:
302 Dmsg1(80, "Got CI_Calibration: %d\n", data.u32);
303 if (data.u32 == 3)
304 ups->set_calibration();
305 else
306 ups->clear_calibration();
307 break;
309 case CI_Overload:
310 Dmsg1(80, "Got CI_Overload: %c\n", data.str[8]);
311 if (data.str[8] == '1')
312 ups->set_overload();
313 else
314 ups->clear_overload();
315 break;
317 case CI_DSHUTD:
318 Dmsg1(80, "Got CI_DSHUTD: %d\n", data.u32);
319 ups->dshutd = data.u32 / TIMETICKS_TO_SECS;
320 break;
322 case CI_RETPCT:
323 Dmsg1(80, "Got CI_RETPCT: %d\n", data.u32);
324 ups->rtnpct = data.u32;
325 break;
327 case CI_WHY_BATT:
328 switch (data.u32)
330 case 1:
331 ups->lastxfer = XFER_NONE;
332 break;
333 case 2: /* High line voltage */
334 ups->lastxfer = XFER_OVERVOLT;
335 break;
336 case 3: /* Brownout */
337 case 4: /* Blackout */
338 ups->lastxfer = XFER_UNDERVOLT;
339 break;
340 case 5: /* Small sag */
341 case 6: /* Deep sag */
342 case 7: /* Small spike */
343 case 8: /* Deep spike */
344 ups->lastxfer = XFER_NOTCHSPIKE;
345 break;
346 case 9:
347 ups->lastxfer = XFER_SELFTEST;
348 break;
349 case 10:
350 ups->lastxfer = XFER_RIPPLE;
351 break;
352 default:
353 ups->lastxfer = XFER_UNKNOWN;
354 break;
356 break;
358 case CI_SENS:
359 Dmsg1(80, "Got CI_SENS: %d\n", data.u32);
360 switch (data.u32)
362 case 1:
363 astrncpy(ups->sensitivity, "Auto", sizeof(ups->sensitivity));
364 break;
365 case 2:
366 astrncpy(ups->sensitivity, "Low", sizeof(ups->sensitivity));
367 break;
368 case 3:
369 astrncpy(ups->sensitivity, "Medium", sizeof(ups->sensitivity));
370 break;
371 case 4:
372 astrncpy(ups->sensitivity, "High", sizeof(ups->sensitivity));
373 break;
374 default:
375 astrncpy(ups->sensitivity, "Unknown", sizeof(ups->sensitivity));
376 break;
378 break;
380 case CI_REVNO:
381 Dmsg1(80, "Got CI_REVNO: %s\n", data.str.str());
382 astrncpy(ups->firmrev, data.str, sizeof(ups->firmrev));
383 break;
385 case CI_EXTBATTS:
386 Dmsg1(80, "Got CI_EXTBATTS: %d\n", data.u32);
387 ups->extbatts = data.u32;
388 break;
390 case CI_BADBATTS:
391 Dmsg1(80, "Got CI_BADBATTS: %d\n", data.u32);
392 ups->badbatts = data.u32;
393 break;
395 case CI_DLBATT:
396 Dmsg1(80, "Got CI_DLBATT: %d\n", data.u32);
397 ups->dlowbatt = data.u32 / TIMETICKS_TO_SECS / SECS_TO_MINS;
398 break;
400 case CI_STESTI:
401 Dmsg1(80, "Got CI_STESTI: %d\n", data.u32);
402 switch (data.u32) {
403 case 2:
404 astrncpy(ups->selftest, "336", sizeof(ups->selftest));
405 break;
406 case 3:
407 astrncpy(ups->selftest, "168", sizeof(ups->selftest));
408 break;
409 case 4:
410 astrncpy(ups->selftest, "ON", sizeof(ups->selftest));
411 break;
412 case 1:
413 case 5:
414 default:
415 astrncpy(ups->selftest, "OFF", sizeof(ups->selftest));
416 break;
418 break;
420 case CI_VMIN:
421 Dmsg1(80, "Got CI_VMIN: %d\n", data.u32);
422 ups->LineMin = data.u32;
423 break;
425 case CI_VMAX:
426 Dmsg1(80, "Got CI_VMAX: %d\n", data.u32);
427 ups->LineMax = data.u32;
428 break;
432 static int apc_killpower(UPSINFO *ups)
434 struct snmplite_ups_internal_data *sid =
435 (struct snmplite_ups_internal_data *)ups->driver_internal_data;
437 Snmp::Variable var = { Asn::INTEGER, 2 };
438 return sid->snmp->Set(upsBasicControlConserveBattery, &var);
441 static int apc_shutdown(UPSINFO *ups)
443 struct snmplite_ups_internal_data *sid =
444 (struct snmplite_ups_internal_data *)ups->driver_internal_data;
446 Snmp::Variable var = { Asn::INTEGER, 2 };
447 return sid->snmp->Set(upsAdvControlUpsOff, &var);
450 // Export strategy to snmplite.cpp
451 struct MibStrategy ApcMibStrategy =
453 "APC",
454 CiOidMap,
455 apc_update_ci,
456 apc_killpower,
457 apc_shutdown,