UPS: apcupsd clean sources
[tomato.git] / release / src / router / apcupsd / src / drivers / snmplite / rfc1628-mib.cpp
blob02d7ab47a5096ddce56669b275afdeda2d7ce9ff
1 /*
2 * mib.cpp
4 * CI -> OID mapping for SNMP Lite UPS driver
5 */
7 /*
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,
22 * MA 02111-1307, USA.
25 #include "apc.h"
26 #include "snmplite-common.h"
27 #include "mibs.h"
28 #include "rfc1628-oids.h"
30 using namespace Asn;
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)
77 switch (ci)
79 case CI_VLINE:
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;
83 break;
85 case CI_VOUT:
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;
89 break;
91 case CI_VBATT:
92 Dmsg1(80, "Got CI_VBATT: %d\n", data.u32);
93 ups->BattVoltage = ((double)data.u32) / 10;
94 break;
96 case CI_FREQ:
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;
100 break;
102 case CI_LOAD:
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
110 // for the best.
111 ups->UPSLoad = 0;
112 for (alist<Snmp::Variable>::iterator iter = data.seq.begin();
113 iter != data.seq.end();
114 ++iter)
116 Dmsg1(80, "Got CI_LOAD: %d\n", iter->u32);
117 ups->UPSLoad += iter->u32;
119 ups->UPSLoad /= data.seq.size();
120 break;
122 case CI_ITEMP:
123 Dmsg1(80, "Got CI_ITEMP: %d\n", data.u32);
124 ups->UPSTemp = data.u32;
125 break;
127 case CI_NOMOUTV:
128 Dmsg1(80, "Got CI_NOMOUTV: %d\n", data.u32);
129 ups->NomOutputVoltage = data.u32;
130 break;
132 case CI_NOMINV:
133 Dmsg1(80, "Got CI_NOMINV: %d\n", data.u32);
134 ups->NomInputVoltage = data.u32;
135 break;
137 case CI_NOMPOWER:
138 Dmsg1(80, "Got CI_NOMPOWER: %d\n", data.u32);
139 ups->NomPower = data.u32;
140 break;
142 case CI_LTRANS:
143 Dmsg1(80, "Got CI_LTRANS: %d\n", data.u32);
144 ups->lotrans = data.u32;
145 break;
147 case CI_HTRANS:
148 Dmsg1(80, "Got CI_HTRANS: %d\n", data.u32);
149 ups->hitrans = data.u32;
150 break;
152 case CI_ST_STAT:
153 Dmsg1(80, "Got CI_ST_STAT: %d\n", data.u32);
154 switch (data.u32)
156 case 1: /* Passed */
157 ups->testresult = TEST_PASSED;
158 break;
159 case 2: /* Warning */
160 ups->testresult = TEST_WARNING;
161 break;
162 case 3: /* Error */
163 ups->testresult = TEST_FAILED;
164 break;
165 case 5: /* Test in progress */
166 ups->testresult = TEST_INPROGRESS;
167 break;
168 case 4: /* Aborted */
169 case 6: /* No test initiated */
170 ups->testresult = TEST_NONE;
171 break;
172 default:
173 ups->testresult = TEST_UNKNOWN;
174 break;
176 break;
178 case CI_DALARM:
179 Dmsg1(80, "Got CI_DALARM: %d\n", data.u32);
180 switch (data.u32)
182 case 1: // Disabled ("None")
183 astrncpy(ups->beepstate, "N", sizeof(ups->beepstate));
184 break;
185 case 2: // Enabled (T = 30 seconds...just a guess)
186 case 3: // Muted (but enabled)
187 default:
188 astrncpy(ups->beepstate, "T", sizeof(ups->beepstate));
189 break;
191 break;
193 case CI_UPSMODEL:
194 Dmsg1(80, "Got CI_UPSMODEL: %s\n", data.str.str());
195 astrncpy(ups->upsmodel, data.str, sizeof(ups->upsmodel));
196 break;
198 case CI_BATTLEV:
199 Dmsg1(80, "Got CI_BATTLEV: %d\n", data.u32);
200 ups->BattChg = data.u32;
201 break;
203 case CI_RUNTIM:
204 Dmsg1(80, "Got CI_RUNTIM: %d\n", data.u32);
205 ups->TimeLeft = data.u32;
206 break;
208 case CI_IDEN:
209 Dmsg1(80, "Got CI_IDEN: %s\n", data.str.str());
210 astrncpy(ups->upsname, data.str, sizeof(ups->upsname));
211 break;
213 case CI_STATUS:
214 Dmsg1(80, "Got CI_STATUS: %d\n", data.u32);
215 /* Clear the following flags: only one status will be TRUE */
216 ups->clear_online();
217 ups->clear_onbatt();
218 ups->clear_boost();
219 ups->clear_trim();
220 switch (data.u32) {
221 case 3:
222 ups->set_online();
223 break;
224 case 5:
225 ups->set_onbatt();
226 break;
227 case 6:
228 ups->set_online();
229 ups->set_boost();
230 break;
231 case 7:
232 ups->set_online();
233 ups->set_trim();
234 break;
235 case 1: /* other */
236 case 2: /* output turned off */
237 case 4: /* bypass */
238 default: /* unknown */
239 break;
241 break;
243 case CI_LowBattery:
244 Dmsg1(80, "Got CI_LowBattery: %d\n", data.u32);
245 switch (data.u32)
247 default:
248 case 1: // Unknown
249 case 2: // Normal
250 ups->clear_battlow();
251 break;
252 case 3: // Low
253 case 4: // Depleted
254 ups->set_battlow();
255 break;
257 break;
259 case CI_REVNO:
260 Dmsg1(80, "Got CI_REVNO: %s\n", data.str.str());
261 astrncpy(ups->firmrev, data.str, sizeof(ups->firmrev));
262 break;
264 case CI_DLBATT:
265 Dmsg1(80, "Got CI_DLBATT: %d\n", data.u32);
266 ups->dlowbatt = data.u32;
267 break;
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);
288 return 0;
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);
308 return 0;
311 // Export strategy to snmplite.cpp
312 struct MibStrategy Rfc1628MibStrategy =
314 "RFC",
315 Rfc1628CiOidMap,
316 rfc1628_update_ci,
317 rfc1628_killpower,
318 rfc1628_shutdown,