1 /* mge-xml.c Model specific routines for Eaton / MGE XML protocol UPSes
2
3 Copyright (C)
4 2008-2009 Arjen de Korte <adkorte-guest@alioth.debian.org>
5 2009-2021 Eaton (author: Arnaud Quette <ArnaudQuette@Eaton.com>)
6 2017 Eaton (author: Jim Klimov <EvgenyKlimov@Eaton.com>)
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <ne_xml.h>
28
29 #include "common.h"
30 #include "dstate.h"
31
32 #include "netxml-ups.h"
33 #include "mge-xml.h"
34 #include "main.h" /* for testvar() */
35
36 #define MGE_XML_VERSION "MGEXML/0.31"
37
38 #define MGE_XML_INITUPS "/"
39 #define MGE_XML_INITINFO "/mgeups/product.xml /product.xml /ws/product.xml"
40
41 #define ST_FLAG_RW 0x0001
42 #define ST_FLAG_STATIC 0x0002
43
44 static int mge_ambient_value = 0;
45
46 /* The number of phases is not present in XML data as a separate node,
47 * but we can infer it from presence of non-zero data on several
48 * per-line nodes. */
49 static int
50 inited_phaseinfo_in = 0,
51 inited_phaseinfo_bypass = 0,
52 inited_phaseinfo_out = 0,
53 num_inphases = -1,
54 num_bypassphases = -1,
55 num_outphases = -1;
56
57 static char mge_scratch_buf[256];
58
59 static char var[128];
60 static char val[128];
61
62 static int mge_shutdown_pending = 0;
63
64 /* This flag flips to 0 when/if we post the detailed deprecation message */
65 static int mge_report_deprecation__convert_deci = 1;
66
67 typedef enum {
68 ROOTPARENT = NE_XML_STATEROOT,
69
70 _UNEXPECTED,
71 _PARSEERROR,
72
73 PRODUCT_INFO = 100, /* "/mgeups/product.xml" */
74
75 PI_SUMMARY = 110,
76 PI_HTML_PROPERTIES_PAGE,
77 PI_XML_SUMMARY_PAGE,
78 PI_CENTRAL_CFG,
79 PI_CSV_LOGS,
80 /* /PI_SUMMARY */
81
82 PI_ALARMS = 120,
83 PI_SUBSCRIPTION,
84 PI_POLLING,
85 /* /ALARMS */
86
87 PI_MANAGEMENT = 130,
88 PI_MANAGEMENT_PAGE,
89 PI_XML_MANAGEMENT_PAGE,
90 /* /MANAGEMENT */
91
92 PI_UPS_DATA = 140,
93 PI_GET_OBJECT,
94 PI_SET_OBJECT,
95 /* /UPS_DATA */
96
97 /* /PRODUCT_INFO */
98
99 SUMMARY = 200, /* "/upsprop.xml" */
100 SU_OBJECT,
101 /* /SUMMARY */
102
103 GET_OBJECT = 300, /* "/getvalue.cgi" */
104 GO_OBJECT,
105 /* /GET_OBJECT */
106
107 SET_OBJECT = 400, /* "/setvalue.cgi" */
108 SO_OBJECT,
109 /* /SET_OBJECT */
110
111 ALARM = 500,
112
113 XML_CLIENT = 600,
114 XC_GENERAL = 610,
115 XC_STARTUP,
116 XC_SHUTDOWN,
117 XC_BROADCAST
118
119 } mge_xml_state_t;
120
121 typedef struct {
122 const char *nutname; /* NUT variable name */
123 uint32_t nutflags; /* NUT flags (to set in addinfo) */
124 size_t nutlen; /* length of the NUT string */
125 const char *xmlname; /* XML variable name */
126 uint32_t xmlflags; /* XML flags (to be used to determine what kind of variable this is */
127 size_t xmllen; /* length of the XML string */
128 const char *(*convert)(const char *value); /* conversion function from XML<->NUT value (returns
129 NULL if no further processing is required) */
130 } xml_info_t;
131
online_info(const char * arg_val)132 static const char *online_info(const char *arg_val)
133 {
134 if (arg_val[0] == '1') {
135 STATUS_SET(ONLINE);
136 } else {
137 STATUS_CLR(ONLINE);
138 }
139
140 return NULL;
141 }
142
discharging_info(const char * arg_val)143 static const char *discharging_info(const char *arg_val)
144 {
145 if (arg_val[0] == '1') {
146 STATUS_SET(DISCHRG);
147 /* Workaround NMC bug: both charging and discharging set to 1 */
148 if(STATUS_BIT(CHRG)) {
149 STATUS_CLR(CHRG);
150 }
151 } else {
152 STATUS_CLR(DISCHRG);
153 }
154
155 return NULL;
156 }
157
charging_info(const char * arg_val)158 static const char *charging_info(const char *arg_val)
159 {
160 if (arg_val[0] == '1') {
161 STATUS_SET(CHRG);
162 } else {
163 STATUS_CLR(CHRG);
164 }
165
166 return NULL;
167 }
168
lowbatt_info(const char * arg_val)169 static const char *lowbatt_info(const char *arg_val)
170 {
171 if (arg_val[0] == '1') {
172 STATUS_SET(LOWBATT);
173 } else {
174 STATUS_CLR(LOWBATT);
175 }
176
177 return NULL;
178 }
179
overload_info(const char * arg_val)180 static const char *overload_info(const char *arg_val)
181 {
182 if (arg_val[0] == '1') {
183 STATUS_SET(OVERLOAD);
184 } else {
185 STATUS_CLR(OVERLOAD);
186 }
187
188 return NULL;
189 }
190
replacebatt_info(const char * arg_val)191 static const char *replacebatt_info(const char *arg_val)
192 {
193 if (arg_val[0] == '1') {
194 STATUS_SET(REPLACEBATT);
195 } else {
196 STATUS_CLR(REPLACEBATT);
197 }
198
199 return NULL;
200 }
201
trim_info(const char * arg_val)202 static const char *trim_info(const char *arg_val)
203 {
204 if (arg_val[0] == '1') {
205 STATUS_SET(TRIM);
206 } else {
207 STATUS_CLR(TRIM);
208 }
209
210 return NULL;
211 }
212
boost_info(const char * arg_val)213 static const char *boost_info(const char *arg_val)
214 {
215 if (arg_val[0] == '1') {
216 STATUS_SET(BOOST);
217 } else {
218 STATUS_CLR(BOOST);
219 }
220
221 return NULL;
222 }
223
bypass_aut_info(const char * arg_val)224 static const char *bypass_aut_info(const char *arg_val)
225 {
226 if (arg_val[0] == '1') {
227 STATUS_SET(BYPASSAUTO);
228 } else {
229 STATUS_CLR(BYPASSAUTO);
230 }
231
232 return NULL;
233 }
234
bypass_man_info(const char * arg_val)235 static const char *bypass_man_info(const char *arg_val)
236 {
237 if (arg_val[0] == '1') {
238 STATUS_SET(BYPASSMAN);
239 } else {
240 STATUS_CLR(BYPASSMAN);
241 }
242
243 return NULL;
244 }
245
off_info(const char * arg_val)246 static const char *off_info(const char *arg_val)
247 {
248 if (arg_val[0] == '0') {
249 STATUS_SET(OFF);
250 } else {
251 STATUS_CLR(OFF);
252 }
253
254 return NULL;
255 }
256
257 /* note: this value is reverted (0=set, 1=not set). We report "battery
258 not installed" rather than "battery installed", so that devices
259 that don't implement this variable have a battery by default */
nobattery_info(const char * arg_val)260 static const char *nobattery_info(const char *arg_val)
261 {
262 if (arg_val[0] == '0') {
263 STATUS_SET(NOBATTERY);
264 } else {
265 STATUS_CLR(NOBATTERY);
266 }
267
268 return NULL;
269 }
270
fanfail_info(const char * arg_val)271 static const char *fanfail_info(const char *arg_val)
272 {
273 if (arg_val[0] == '1') {
274 STATUS_SET(FANFAIL);
275 } else {
276 STATUS_CLR(FANFAIL);
277 }
278
279 return NULL;
280 }
281
282 #if 0
283 static const char *shutdownimm_info(const char *arg_val)
284 {
285 if (arg_val[0] == '1') {
286 STATUS_SET(SHUTDOWNIMM);
287 } else {
288 STATUS_CLR(SHUTDOWNIMM);
289 }
290
291 return NULL;
292 }
293 #endif
294
overheat_info(const char * arg_val)295 static const char *overheat_info(const char *arg_val)
296 {
297 if (arg_val[0] == '1') {
298 STATUS_SET(OVERHEAT);
299 } else {
300 STATUS_CLR(OVERHEAT);
301 }
302
303 return NULL;
304 }
305
commfault_info(const char * arg_val)306 static const char *commfault_info(const char *arg_val)
307 {
308 if (arg_val[0] == '1') {
309 STATUS_SET(COMMFAULT);
310 } else {
311 STATUS_CLR(COMMFAULT);
312 }
313
314 return NULL;
315 }
316
internalfailure_info(const char * arg_val)317 static const char *internalfailure_info(const char *arg_val)
318 {
319 if (arg_val[0] == '1') {
320 STATUS_SET(INTERNALFAULT);
321 } else {
322 STATUS_CLR(INTERNALFAULT);
323 }
324
325 return NULL;
326 }
327
battvoltlo_info(const char * arg_val)328 static const char *battvoltlo_info(const char *arg_val)
329 {
330 if (arg_val[0] == '1') {
331 STATUS_SET(BATTVOLTLO);
332 } else {
333 STATUS_CLR(BATTVOLTLO);
334 }
335
336 return NULL;
337 }
338
battvolthi_info(const char * arg_val)339 static const char *battvolthi_info(const char *arg_val)
340 {
341 if (arg_val[0] == '1') {
342 STATUS_SET(BATTVOLTHI);
343 } else {
344 STATUS_CLR(BATTVOLTHI);
345 }
346
347 return NULL;
348 }
349
chargerfail_info(const char * arg_val)350 static const char *chargerfail_info(const char *arg_val)
351 {
352 if ((arg_val[0] == '1') || !strncasecmp(arg_val, "Yes", 3)) {
353 STATUS_SET(CHARGERFAIL);
354 } else {
355 STATUS_CLR(CHARGERFAIL);
356 }
357
358 return NULL;
359 }
360
vrange_info(const char * arg_val)361 static const char *vrange_info(const char *arg_val)
362 {
363 if ((arg_val[0] == '1') || !strncasecmp(arg_val, "Yes", 3)) {
364 STATUS_SET(VRANGE);
365 } else {
366 STATUS_CLR(VRANGE);
367 }
368
369 return NULL;
370 }
371
frange_info(const char * arg_val)372 static const char *frange_info(const char *arg_val)
373 {
374 if ((arg_val[0] == '1') || !strncasecmp(arg_val, "Yes", 3)) {
375 STATUS_SET(FRANGE);
376 } else {
377 STATUS_CLR(FRANGE);
378 }
379
380 return NULL;
381 }
382
fuse_fault_info(const char * arg_val)383 static const char *fuse_fault_info(const char *arg_val)
384 {
385 if (arg_val[0] == '1') {
386 STATUS_SET(FUSEFAULT);
387 } else {
388 STATUS_CLR(FUSEFAULT);
389 }
390
391 return NULL;
392 }
393
yes_no_info(const char * arg_val)394 static const char *yes_no_info(const char *arg_val)
395 {
396 switch(arg_val[0])
397 {
398 case '1':
399 return "yes";
400 case '0':
401 return "no";
402 default:
403 upsdebugx(2, "%s: unexpected value [%s]", __func__, arg_val);
404 return "<unknown>";
405 }
406 }
407
on_off_info(const char * arg_val)408 static const char *on_off_info(const char *arg_val)
409 {
410 switch(arg_val[0])
411 {
412 case '1':
413 return "on";
414 case '0':
415 return "off";
416 default:
417 upsdebugx(2, "%s: unexpected value [%s]", __func__, arg_val);
418 return "<unknown>";
419 }
420 }
421
convert_deci(const char * arg_val)422 static const char *convert_deci(const char *arg_val)
423 {
424 /* Note: this routine was needed for original MGE devices, before the company
425 * was bought out and split in 2007 between Eaton (1ph devices) and Schneider
426 * (3ph devices). Those firmwares back when the driver was written apparently
427 * served 10x the measured values. Not sure if any such units are in service
428 * now (with same FW, and with no upgrade path). Reign of XML/PDC is waning.
429 * For currently known NetXML servers, the value served is good without more
430 * conversions. If older devices pop up in the field, we can add an estimation
431 * by e.g. reported voltage and amps (to be an order of magnitude for power).
432 * Alternately we can look at model names and/or firmware versions or release
433 * dates, if we get those and if we know enough to map them to either logic. */
434
435 if (testvar("do_convert_deci")) {
436 /* Old code for old devices: */
437 if (mge_report_deprecation__convert_deci) {
438 upslogx(LOG_NOTICE, "%s() is now deprecated, so values from XML are normally not decimated. This driver instance has however configured do_convert_deci in your ups.conf, so this behavior for old MGE NetXML-capable devices is preserved.", __func__);
439 mge_report_deprecation__convert_deci = 0;
440 }
441 snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%.1f", 0.1 * (float)(atoi(arg_val)));
442 return mge_scratch_buf;
443 }
444
445 if (mge_report_deprecation__convert_deci) {
446 upslogx(LOG_NOTICE, "%s() is now deprecated, so values from XML are not decimated. If you happen to have an old MGE NetXML-capable device that now shows measurements 10x too big, and a firmware update does not solve this, please inform NUT devs via the issue tracker at %s with details about your hardware and firmware versions. Also try to enable do_convert_deci in your ups.conf", __func__, PACKAGE_BUGREPORT );
447 mge_report_deprecation__convert_deci = 0;
448 }
449 upsdebugx(5, "%s() is now deprecated, so value '%s' is not decimated. If this change broke your setup, please see details logged above.", __func__, arg_val);
450 return arg_val;
451 }
452
453 /* Ignore a zero value if the UPS is not switched off */
ignore_if_zero(const char * arg_val)454 static const char *ignore_if_zero(const char *arg_val)
455 {
456 if (atoi(arg_val) == 0) {
457 return NULL;
458 }
459
460 return convert_deci(arg_val);
461 }
462
463 /* Set the 'ups.date' from the combined value
464 * (ex. 2008/03/01 15:23:26) and return the time */
split_date_time(const char * arg_val)465 static const char *split_date_time(const char *arg_val)
466 {
467 char *last = NULL;
468
469 snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%s", arg_val);
470 dstate_setinfo("ups.date", "%s", strtok_r(mge_scratch_buf, " -", &last));
471
472 return strtok_r(NULL, " ", &last);
473 }
474
url_convert(const char * arg_val)475 static const char *url_convert(const char *arg_val)
476 {
477 char buf[256], *last = NULL;
478
479 snprintf(buf, sizeof(buf), "%s", arg_val);
480 snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "/%s", strtok_r(buf, " \r\n\t", &last));
481
482 return mge_scratch_buf;
483 }
484
mge_battery_capacity(const char * arg_val)485 static const char *mge_battery_capacity(const char *arg_val)
486 {
487 snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%.2f", (float)(atoi(arg_val)) / 3600.0);
488 return mge_scratch_buf;
489 }
490
mge_powerfactor_conversion(const char * arg_val)491 static const char *mge_powerfactor_conversion(const char *arg_val)
492 {
493 snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%.2f", (float)(atoi(arg_val)) / 100.0);
494 return mge_scratch_buf;
495 }
496
mge_beeper_info(const char * arg_val)497 static const char *mge_beeper_info(const char *arg_val)
498 {
499 switch (atoi(arg_val))
500 {
501 case 1:
502 return "disabled";
503 case 2:
504 return "enabled";
505 case 3:
506 return "muted";
507 }
508 return NULL;
509 }
510
mge_upstype_conversion(const char * arg_val)511 static const char *mge_upstype_conversion(const char *arg_val)
512 {
513 switch (atoi(arg_val))
514 {
515 case 1:
516 return "offline / line interactive";
517 case 2:
518 return "online";
519 case 3:
520 return "online - unitary/parallel";
521 case 4:
522 return "online - parallel with hot standy";
523 case 5:
524 return "online - hot standby redundancy";
525 }
526 return NULL;
527 }
528
mge_sensitivity_info(const char * arg_val)529 static const char *mge_sensitivity_info(const char *arg_val)
530 {
531 switch (atoi(arg_val))
532 {
533 case 0:
534 return "normal";
535 case 1:
536 return "high";
537 case 2:
538 return "low";
539 }
540 return NULL;
541 }
542
mge_test_result_info(const char * arg_val)543 static const char *mge_test_result_info(const char *arg_val)
544 {
545 STATUS_CLR(CAL);
546 switch (atoi(arg_val))
547 {
548 case 1:
549 return "done and passed";
550 case 2:
551 return "done and warning";
552 case 3:
553 return "done and error";
554 case 4:
555 return "aborted";
556 case 5:
557 STATUS_SET(CAL);
558 return "in progress";
559 case 6:
560 return "no test initiated";
561 case 7:
562 return "test scheduled";
563 }
564 return NULL;
565 }
566
mge_ambient_info(const char * arg_val)567 static const char *mge_ambient_info(const char *arg_val)
568 {
569 switch (mge_ambient_value)
570 {
571 case 1:
572 return arg_val;
573 default:
574 return NULL;
575 }
576 }
577
mge_timer_shutdown(const char * delay_before_shutoff)578 static const char *mge_timer_shutdown(const char *delay_before_shutoff)
579 {
580 if (atoi(delay_before_shutoff) > -1 ) {
581 STATUS_SET(SHUTDOWNIMM);
582 mge_shutdown_pending = 1;
583
584 if( atoi(delay_before_shutoff) > shutdown_duration ) {
585 STATUS_CLR(SHUTDOWNIMM);
586 mge_shutdown_pending = 0;
587 }
588 } else {
589 STATUS_CLR(SHUTDOWNIMM);
590 mge_shutdown_pending = 0;
591 }
592
593 return val;
594 }
595
mge_shutdown_imminent(const char * arg_val)596 static const char *mge_shutdown_imminent(const char *arg_val)
597 {
598 const int shutdown_delay = atoi(arg_val);
599
600 /* shutdown is already managed by mge_timer_shutdown, give up */
601 if(mge_shutdown_pending) {
602 return NULL;
603 }
604
605 /* We may have "NONE" or "-1" or ?? as value
606 * We also double check both the string and numeric values to be zero!*/
607 if ((arg_val) && (arg_val[0] == '0') && (shutdown_delay == 0)) {
608 STATUS_SET(SHUTDOWNIMM);
609 } else {
610 STATUS_CLR(SHUTDOWNIMM);
611 }
612
613 return NULL;
614 }
615
616 static xml_info_t mge_xml2nut[] = {
617 /* NMC configuration (mapped 1:1 for now) */
618 { "device.contact", ST_FLAG_RW, 0, "System.Contact", 0, 0, NULL },
619 { "device.location", ST_FLAG_RW, 0, "System.Location", 0, 0, NULL },
620 /* Not used for now; might however be used in future for history & stats collection
621 { "System.History.Log.Interval", ST_FLAG_RW, 0, "System.History.Log.Interval", 0, 0, NULL },
622 */
623 #if (0) /* not interresting for NUT */
624 { "System.Environment.Log.Interval", ST_FLAG_RW, 0, "System.Environment.Log.Interval", 0, 0, NULL },
625 { "System.Outlet[1].iName", ST_FLAG_RW, 0, "System.Outlet[1].iName", 0, 0, NULL },
626 /* Mapped as ups.delay.shutdown
627 { "System.ShutdownDuration", ST_FLAG_RW, 0, "System.ShutdownDuration", 0, 0, NULL },
628 */
629 { "System.ShutdownTimerSelected", ST_FLAG_RW, 0, "System.ShutdownTimerSelected", 0, 0, NULL },
630 { "System.ShutdownTimer", ST_FLAG_RW, 0, "System.ShutdownTimer", 0, 0, NULL },
631 /* Mapped as battery.runtime.low
632 { "System.RunTimeToEmptyLimit", ST_FLAG_RW, 0, "System.RunTimeToEmptyLimit", 0, 0, NULL },
633 */
634 { "System.RemainingCapacityLimit", ST_FLAG_RW, 0, "System.RemainingCapacityLimit", 0, 0, NULL },
635 { "System.RestartLevel", ST_FLAG_RW, 0, "System.RestartLevel", 0, 0, NULL },
636 { "System.Outlet[2].iName", ST_FLAG_RW, 0, "System.Outlet[2].iName", 0, 0, NULL },
637 /* Mapped as outlet.1.delay.shutdown
638 { "System.Outlet[2].ShutdownDuration", ST_FLAG_RW, 0, "System.Outlet[2].ShutdownDuration", 0, 0, NULL },
639 */
640 { "System.Outlet[2].ShutdownTimer", ST_FLAG_RW, 0, "System.Outlet[2].ShutdownTimer", 0, 0, NULL },
641 { "System.Outlet[2].StartupTimer", ST_FLAG_RW, 0, "System.Outlet[2].StartupTimer", 0, 0, NULL },
642 { "System.Outlet[2].RemainingCapacityLimit", ST_FLAG_RW, 0, "System.Outlet[2].RemainingCapacityLimit", 0, 0, NULL },
643 /* For future extension, and support of shutdown on load segment
644 * { "System.Outlet[2].RunTimeToShutdown", ST_FLAG_RW, 0, "System.Outlet[2].RunTimeToShutdown", 0, 0, NULL }, */
645 { "System.Outlet[3].iName", ST_FLAG_RW, 0, "System.Outlet[3].iName", 0, 0, NULL },
646 /* Mapped as outlet.2.delay.shutdown
647 { "System.Outlet[3].ShutdownDuration", ST_FLAG_RW, 0, "System.Outlet[3].ShutdownDuration", 0, 0, NULL },
648 */
649 { "System.Outlet[3].ShutdownTimer", ST_FLAG_RW, 0, "System.Outlet[3].ShutdownTimer", 0, 0, NULL },
650 { "System.Outlet[3].StartupTimer", ST_FLAG_RW, 0, "System.Outlet[3].StartupTimer", 0, 0, NULL },
651 { "System.Outlet[3].RemainingCapacityLimit", ST_FLAG_RW, 0, "System.Outlet[3].RemainingCapacityLimit", 0, 0, NULL },
652 /* For future extension, and support of shutdown on load segment
653 * { "System.Outlet[3].RunTimeToShutdown", ST_FLAG_RW, 0, "System.Outlet[3].RunTimeToShutdown", 0, 0, NULL }, */
654 { "System.Outlet[1].OffDelay", ST_FLAG_RW, 0, "System.Outlet[1].OffDelay", 0, 0, NULL },
655 { "System.Outlet[1].Toggle", ST_FLAG_RW, 0, "System.Outlet[1].Toggle", 0, 0, NULL },
656 { "System.Outlet[1].OnDelay", ST_FLAG_RW, 0, "System.Outlet[1].OnDelay", 0, 0, NULL },
657 { "System.Outlet[2].OffDelay", ST_FLAG_RW, 0, "System.Outlet[2].OffDelay", 0, 0, NULL },
658 { "System.Outlet[2].Toggle", ST_FLAG_RW, 0, "System.Outlet[2].Toggle", 0, 0, NULL },
659 { "System.Outlet[2].OnDelay", ST_FLAG_RW, 0, "System.Outlet[2].OnDelay", 0, 0, NULL },
660 { "System.Outlet[3].OffDelay", ST_FLAG_RW, 0, "System.Outlet[3].OffDelay", 0, 0, NULL },
661 { "System.Outlet[3].Toggle", ST_FLAG_RW, 0, "System.Outlet[3].Toggle", 0, 0, NULL },
662 { "System.Outlet[3].OnDelay", ST_FLAG_RW, 0, "System.Outlet[3].OnDelay", 0, 0, NULL },
663 { "System.Login", ST_FLAG_RW, 0, "System.Login", 0, 0, NULL },
664 { "System.Password", ST_FLAG_RW, 0, "System.Password", 0, 0, NULL },
665 { "System.Security", ST_FLAG_RW, 0, "System.Security", 0, 0, NULL },
666 { "System.FirmwareUpgrade", ST_FLAG_RW, 0, "System.FirmwareUpgrade", 0, 0, NULL },
667 { "System.Network.SNMP.ReadCommunity", ST_FLAG_RW, 0, "System.Network.SNMP.ReadCommunity", 0, 0, NULL },
668 { "System.Network.SNMP.ReadCommunityName", 0, 0, "System.Network.SNMP.ReadCommunityName", 0, 0, NULL },
669 { "System.Network.SNMP.ReadCommunitySecurityLevel", 0, 0, "System.Network.SNMP.ReadCommunitySecurityLevel", 0, 0, NULL },
670 { "System.Network.SNMP.ReadCommunitySecurityRight", 0, 0, "System.Network.SNMP.ReadCommunitySecurityRight", 0, 0, NULL },
671 { "System.Network.SNMP.WriteCommunity", ST_FLAG_RW, 0, "System.Network.SNMP.WriteCommunity", 0, 0, NULL },
672 { "System.Network.SNMP.WriteCommunityName", 0, 0, "System.Network.SNMP.WriteCommunityName", 0, 0, NULL },
673 { "System.Network.SNMP.WriteCommunitySecurityLevel", 0, 0, "System.Network.SNMP.WriteCommunitySecurityLevel", 0, 0, NULL },
674 { "System.Network.SNMP.WriteCommunitySecurityRight", ST_FLAG_RW, 0, "System.Network.SNMP.WriteCommunitySecurityRight", 0, 0, NULL },
675 { "System.Network.SNMP.Admin", ST_FLAG_RW, 0, "System.Network.SNMP.Admin", 0, 0, NULL },
676 { "System.Network.SNMP.AdminPassword", ST_FLAG_RW, 0, "System.Network.SNMP.AdminPassword", 0, 0, NULL },
677 { "System.Network.SNMP.AdminSecurityLevel", ST_FLAG_RW, 0, "System.Network.SNMP.AdminSecurityLevel", 0, 0, NULL },
678 { "System.Network.SNMP.AdminSecurityRight", 0, 0, "System.Network.SNMP.AdminSecurityRight", 0, 0, NULL },
679 { "System.Network.SNMP.User", ST_FLAG_RW, 0, "System.Network.SNMP.User", 0, 0, NULL },
680 { "System.Network.SNMP.UserPassword", ST_FLAG_RW, 0, "System.Network.SNMP.UserPassword", 0, 0, NULL },
681 { "System.Network.SNMP.UserSecurityLevel", ST_FLAG_RW, 0, "System.Network.SNMP.UserSecurityLevel", 0, 0, NULL },
682 { "System.Network.SNMP.UserSecurityRight", 0, 0, "System.Network.SNMP.UserSecurityRight", 0, 0, NULL },
683 { "System.Network.SNMP.NotificationUserName", ST_FLAG_RW, 0, "System.Network.SNMP.NotificationUserName", 0, 0, NULL },
684 { "System.Network.SNMP.snmpVersion", ST_FLAG_RW, 0, "System.Network.SNMP.snmpVersion", 0, 0, NULL },
685 { "System.Network.SNMP.engineBoots", 0, 0, "System.Network.SNMP.engineBoots", 0, 0, NULL },
686 { "System.Network.Telnet.Access", ST_FLAG_RW, 0, "System.Network.Telnet.Access", 0, 0, NULL },
687 { "System.Network.Telnet.Security", ST_FLAG_RW, 0, "System.Network.Telnet.Security", 0, 0, NULL },
688 { "System.Network.Telnet.Console", ST_FLAG_RW, 0, "System.Network.Telnet.Console", 0, 0, NULL },
689 { "System.Email.Sender", ST_FLAG_RW, 0, "System.Email.Sender", 0, 0, NULL },
690 { "System.Email.Subject", ST_FLAG_RW, 0, "System.Email.Subject", 0, 0, NULL },
691 { "System.Email.UPSName", ST_FLAG_RW, 0, "System.Email.UPSName", 0, 0, NULL },
692 { "System.Email.Message", ST_FLAG_RW, 0, "System.Email.Message", 0, 0, NULL },
693 { "System.Email.Localization", ST_FLAG_RW, 0, "System.Email.Localization", 0, 0, NULL },
694 { "System.Email.EventName", ST_FLAG_RW, 0, "System.Email.EventName", 0, 0, NULL },
695 { "System.Email[0].Recipient", ST_FLAG_RW, 0, "System.Email[0].Recipient", 0, 0, NULL },
696 { "System.Email[0].Selected", ST_FLAG_RW, 0, "System.Email[0].Selected", 0, 0, NULL },
697 { "System.Email[0].Enotify", ST_FLAG_RW, 0, "System.Email[0].Enotify", 0, 0, NULL },
698 { "System.Email[0].Measures.Log", ST_FLAG_RW, 0, "System.Email[0].Measures.Log", 0, 0, NULL },
699 { "System.Email[0].Events.Log", ST_FLAG_RW, 0, "System.Email[0].Events.Log", 0, 0, NULL },
700 { "System.Email[0].SystemEvents.Log", ST_FLAG_RW, 0, "System.Email[0].SystemEvents.Log", 0, 0, NULL },
701 { "System.Email[0].Environment.Log", ST_FLAG_RW, 0, "System.Email[0].Environment.Log", 0, 0, NULL },
702 { "System.Email[0].Report.Periodicity", ST_FLAG_RW, 0, "System.Email[0].Report.Periodicity", 0, 0, NULL },
703 { "System.Email[0].Report.Hour", ST_FLAG_RW, 0, "System.Email[0].Report.Hour", 0, 0, NULL },
704 { "System.Email[0].Report.Next", ST_FLAG_RW, 0, "System.Email[0].Report.Next", 0, 0, NULL },
705 { "System.Email[0].EventList.Discharging", ST_FLAG_RW, 0, "System.Email[0].EventList.Discharging", 0, 0, NULL },
706 { "System.Email[0].EventList.ACPresent", ST_FLAG_RW, 0, "System.Email[0].EventList.ACPresent", 0, 0, NULL },
707 { "System.Email[0].EventList.RunTimeToShutdown", ST_FLAG_RW, 0, "System.Email[0].EventList.RunTimeToShutdown", 0, 0, NULL },
708 { "System.Email[0].EventList.BelowRemainingCapacityLimit", ST_FLAG_RW, 0, "System.Email[0].EventList.BelowRemainingCapacityLimit", 0, 0, NULL },
709 { "System.Email[0].EventList.NeedReplacement.1", ST_FLAG_RW, 0, "System.Email[0].EventList.NeedReplacement.1", 0, 0, NULL },
710 { "System.Email[0].EventList.NeedReplacement.0", ST_FLAG_RW, 0, "System.Email[0].EventList.NeedReplacement.0", 0, 0, NULL },
711 { "System.Email[0].EventList.Overload.1", ST_FLAG_RW, 0, "System.Email[0].EventList.Overload.1", 0, 0, NULL },
712 { "System.Email[0].EventList.Overload.0", ST_FLAG_RW, 0, "System.Email[0].EventList.Overload.0", 0, 0, NULL },
713 { "System.Email[0].EventList.InternalFailure.1", ST_FLAG_RW, 0, "System.Email[0].EventList.InternalFailure.1", 0, 0, NULL },
714 { "System.Email[0].EventList.InternalFailure.0", ST_FLAG_RW, 0, "System.Email[0].EventList.InternalFailure.0", 0, 0, NULL },
715 { "System.Email[0].EventList.CommunicationLost.1", ST_FLAG_RW, 0, "System.Email[0].EventList.CommunicationLost.1", 0, 0, NULL },
716 { "System.Email[0].EventList.CommunicationLost.0", ST_FLAG_RW, 0, "System.Email[0].EventList.CommunicationLost.0", 0, 0, NULL },
717 { "System.Email[0].EventList.Charger.InternalFailure", ST_FLAG_RW, 0, "System.Email[0].EventList.Charger.InternalFailure", 0, 0, NULL },
718 { "System.Email[0].EventList.Input[2].Used.1", ST_FLAG_RW, 0, "System.Email[0].EventList.Input[2].Used.1", 0, 0, NULL },
719 { "System.Email[0].EventList.Input[2].Used.0", ST_FLAG_RW, 0, "System.Email[0].EventList.Input[2].Used.0", 0, 0, NULL },
720 { "System.Email[0].EventList.PowerModule.RedundancyLost.1", ST_FLAG_RW, 0, "System.Email[0].EventList.PowerModule.RedundancyLost.1", 0, 0, NULL },
721 { "System.Email[0].EventList.PowerModule.RedundancyLost.0", ST_FLAG_RW, 0, "System.Email[0].EventList.PowerModule.RedundancyLost.0", 0, 0, NULL },
722 { "System.Email[0].EventList.PowerModule.ProtectionLost.1", ST_FLAG_RW, 0, "System.Email[0].EventList.PowerModule.ProtectionLost.1", 0, 0, NULL },
723 { "System.Email[0].EventList.PowerModule.ProtectionLost.0", ST_FLAG_RW, 0, "System.Email[0].EventList.PowerModule.ProtectionLost.0", 0, 0, NULL },
724 { "System.Email[0].EventList.FirmwareUpgrade", ST_FLAG_RW, 0, "System.Email[0].EventList.FirmwareUpgrade", 0, 0, NULL },
725 { "System.Email[0].EventList.Environment.CommunicationLost", ST_FLAG_RW, 0, "System.Email[0].EventList.Environment.CommunicationLost", 0, 0, NULL },
726 { "System.Email[0].EventList.Environment.Notify", ST_FLAG_RW, 0, "System.Email[0].EventList.Environment.Notify", 0, 0, NULL },
727 { "System.Email[1].Recipient", ST_FLAG_RW, 0, "System.Email[1].Recipient", 0, 0, NULL },
728 { "System.Email[1].Selected", ST_FLAG_RW, 0, "System.Email[1].Selected", 0, 0, NULL },
729 { "System.Email[1].Enotify", ST_FLAG_RW, 0, "System.Email[1].Enotify", 0, 0, NULL },
730 { "System.Email[1].Measures.Log", ST_FLAG_RW, 0, "System.Email[1].Measures.Log", 0, 0, NULL },
731 { "System.Email[1].Events.Log", ST_FLAG_RW, 0, "System.Email[1].Events.Log", 0, 0, NULL },
732 { "System.Email[1].SystemEvents.Log", ST_FLAG_RW, 0, "System.Email[1].SystemEvents.Log", 0, 0, NULL },
733 { "System.Email[1].Environment.Log", ST_FLAG_RW, 0, "System.Email[1].Environment.Log", 0, 0, NULL },
734 { "System.Email[1].Report.Periodicity", ST_FLAG_RW, 0, "System.Email[1].Report.Periodicity", 0, 0, NULL },
735 { "System.Email[1].Report.Hour", ST_FLAG_RW, 0, "System.Email[1].Report.Hour", 0, 0, NULL },
736 { "System.Email[1].Report.Next", ST_FLAG_RW, 0, "System.Email[1].Report.Next", 0, 0, NULL },
737 { "System.Email[1].EventList.Discharging", ST_FLAG_RW, 0, "System.Email[1].EventList.Discharging", 0, 0, NULL },
738 { "System.Email[1].EventList.ACPresent", ST_FLAG_RW, 0, "System.Email[1].EventList.ACPresent", 0, 0, NULL },
739 { "System.Email[1].EventList.RunTimeToShutdown", ST_FLAG_RW, 0, "System.Email[1].EventList.RunTimeToShutdown", 0, 0, NULL },
740 { "System.Email[1].EventList.BelowRemainingCapacityLimit", ST_FLAG_RW, 0, "System.Email[1].EventList.BelowRemainingCapacityLimit", 0, 0, NULL },
741 { "System.Email[1].EventList.NeedReplacement.1", ST_FLAG_RW, 0, "System.Email[1].EventList.NeedReplacement.1", 0, 0, NULL },
742 { "System.Email[1].EventList.NeedReplacement.0", ST_FLAG_RW, 0, "System.Email[1].EventList.NeedReplacement.0", 0, 0, NULL },
743 { "System.Email[1].EventList.Overload.1", ST_FLAG_RW, 0, "System.Email[1].EventList.Overload.1", 0, 0, NULL },
744 { "System.Email[1].EventList.Overload.0", ST_FLAG_RW, 0, "System.Email[1].EventList.Overload.0", 0, 0, NULL },
745 { "System.Email[1].EventList.InternalFailure.1", ST_FLAG_RW, 0, "System.Email[1].EventList.InternalFailure.1", 0, 0, NULL },
746 { "System.Email[1].EventList.InternalFailure.0", ST_FLAG_RW, 0, "System.Email[1].EventList.InternalFailure.0", 0, 0, NULL },
747 { "System.Email[1].EventList.CommunicationLost.1", ST_FLAG_RW, 0, "System.Email[1].EventList.CommunicationLost.1", 0, 0, NULL },
748 { "System.Email[1].EventList.CommunicationLost.0", ST_FLAG_RW, 0, "System.Email[1].EventList.CommunicationLost.0", 0, 0, NULL },
749 { "System.Email[1].EventList.Charger.InternalFailure", ST_FLAG_RW, 0, "System.Email[1].EventList.Charger.InternalFailure", 0, 0, NULL },
750 { "System.Email[1].EventList.Input[2].Used.1", ST_FLAG_RW, 0, "System.Email[1].EventList.Input[2].Used.1", 0, 0, NULL },
751 { "System.Email[1].EventList.Input[2].Used.0", ST_FLAG_RW, 0, "System.Email[1].EventList.Input[2].Used.0", 0, 0, NULL },
752 { "System.Email[1].EventList.PowerModule.RedundancyLost.1", ST_FLAG_RW, 0, "System.Email[1].EventList.PowerModule.RedundancyLost.1", 0, 0, NULL },
753 { "System.Email[1].EventList.PowerModule.RedundancyLost.0", ST_FLAG_RW, 0, "System.Email[1].EventList.PowerModule.RedundancyLost.0", 0, 0, NULL },
754 { "System.Email[1].EventList.PowerModule.ProtectionLost.1", ST_FLAG_RW, 0, "System.Email[1].EventList.PowerModule.ProtectionLost.1", 0, 0, NULL },
755 { "System.Email[1].EventList.PowerModule.ProtectionLost.0", ST_FLAG_RW, 0, "System.Email[1].EventList.PowerModule.ProtectionLost.0", 0, 0, NULL },
756 { "System.Email[1].EventList.FirmwareUpgrade", ST_FLAG_RW, 0, "System.Email[1].EventList.FirmwareUpgrade", 0, 0, NULL },
757 { "System.Email[1].EventList.Environment.CommunicationLost", ST_FLAG_RW, 0, "System.Email[1].EventList.Environment.CommunicationLost", 0, 0, NULL },
758 { "System.Email[1].EventList.Environment.Notify", ST_FLAG_RW, 0, "System.Email[1].EventList.Environment.Notify", 0, 0, NULL },
759 { "System.Email[2].Recipient", ST_FLAG_RW, 0, "System.Email[2].Recipient", 0, 0, NULL },
760 { "System.Email[2].Selected", ST_FLAG_RW, 0, "System.Email[2].Selected", 0, 0, NULL },
761 { "System.Email[2].Enotify", ST_FLAG_RW, 0, "System.Email[2].Enotify", 0, 0, NULL },
762 { "System.Email[2].Measures.Log", ST_FLAG_RW, 0, "System.Email[2].Measures.Log", 0, 0, NULL },
763 { "System.Email[2].Events.Log", ST_FLAG_RW, 0, "System.Email[2].Events.Log", 0, 0, NULL },
764 { "System.Email[2].SystemEvents.Log", ST_FLAG_RW, 0, "System.Email[2].SystemEvents.Log", 0, 0, NULL },
765 { "System.Email[2].Environment.Log", ST_FLAG_RW, 0, "System.Email[2].Environment.Log", 0, 0, NULL },
766 { "System.Email[2].Report.Periodicity", ST_FLAG_RW, 0, "System.Email[2].Report.Periodicity", 0, 0, NULL },
767 { "System.Email[2].Report.Hour", ST_FLAG_RW, 0, "System.Email[2].Report.Hour", 0, 0, NULL },
768 { "System.Email[2].Report.Next", ST_FLAG_RW, 0, "System.Email[2].Report.Next", 0, 0, NULL },
769 { "System.Email[2].EventList.Discharging", ST_FLAG_RW, 0, "System.Email[2].EventList.Discharging", 0, 0, NULL },
770 { "System.Email[2].EventList.ACPresent", ST_FLAG_RW, 0, "System.Email[2].EventList.ACPresent", 0, 0, NULL },
771 { "System.Email[2].EventList.RunTimeToShutdown", ST_FLAG_RW, 0, "System.Email[2].EventList.RunTimeToShutdown", 0, 0, NULL },
772 { "System.Email[2].EventList.BelowRemainingCapacityLimit", ST_FLAG_RW, 0, "System.Email[2].EventList.BelowRemainingCapacityLimit", 0, 0, NULL },
773 { "System.Email[2].EventList.NeedReplacement.1", ST_FLAG_RW, 0, "System.Email[2].EventList.NeedReplacement.1", 0, 0, NULL },
774 { "System.Email[2].EventList.NeedReplacement.0", ST_FLAG_RW, 0, "System.Email[2].EventList.NeedReplacement.0", 0, 0, NULL },
775 { "System.Email[2].EventList.Overload.1", ST_FLAG_RW, 0, "System.Email[2].EventList.Overload.1", 0, 0, NULL },
776 { "System.Email[2].EventList.Overload.0", ST_FLAG_RW, 0, "System.Email[2].EventList.Overload.0", 0, 0, NULL },
777 { "System.Email[2].EventList.InternalFailure.1", ST_FLAG_RW, 0, "System.Email[2].EventList.InternalFailure.1", 0, 0, NULL },
778 { "System.Email[2].EventList.InternalFailure.0", ST_FLAG_RW, 0, "System.Email[2].EventList.InternalFailure.0", 0, 0, NULL },
779 { "System.Email[2].EventList.CommunicationLost.1", ST_FLAG_RW, 0, "System.Email[2].EventList.CommunicationLost.1", 0, 0, NULL },
780 { "System.Email[2].EventList.CommunicationLost.0", ST_FLAG_RW, 0, "System.Email[2].EventList.CommunicationLost.0", 0, 0, NULL },
781 { "System.Email[2].EventList.Charger.InternalFailure", ST_FLAG_RW, 0, "System.Email[2].EventList.Charger.InternalFailure", 0, 0, NULL },
782 { "System.Email[2].EventList.Input[2].Used.1", ST_FLAG_RW, 0, "System.Email[2].EventList.Input[2].Used.1", 0, 0, NULL },
783 { "System.Email[2].EventList.Input[2].Used.0", ST_FLAG_RW, 0, "System.Email[2].EventList.Input[2].Used.0", 0, 0, NULL },
784 { "System.Email[2].EventList.PowerModule.RedundancyLost.1", ST_FLAG_RW, 0, "System.Email[2].EventList.PowerModule.RedundancyLost.1", 0, 0, NULL },
785 { "System.Email[2].EventList.PowerModule.RedundancyLost.0", ST_FLAG_RW, 0, "System.Email[2].EventList.PowerModule.RedundancyLost.0", 0, 0, NULL },
786 { "System.Email[2].EventList.PowerModule.ProtectionLost.1", ST_FLAG_RW, 0, "System.Email[2].EventList.PowerModule.ProtectionLost.1", 0, 0, NULL },
787 { "System.Email[2].EventList.PowerModule.ProtectionLost.0", ST_FLAG_RW, 0, "System.Email[2].EventList.PowerModule.ProtectionLost.0", 0, 0, NULL },
788 { "System.Email[2].EventList.FirmwareUpgrade", ST_FLAG_RW, 0, "System.Email[2].EventList.FirmwareUpgrade", 0, 0, NULL },
789 { "System.Email[2].EventList.Environment.CommunicationLost", ST_FLAG_RW, 0, "System.Email[2].EventList.Environment.CommunicationLost", 0, 0, NULL },
790 { "System.Email[2].EventList.Environment.Notify", ST_FLAG_RW, 0, "System.Email[2].EventList.Environment.Notify", 0, 0, NULL },
791 { "System.Email[3].Recipient", ST_FLAG_RW, 0, "System.Email[3].Recipient", 0, 0, NULL },
792 { "System.Email[3].Selected", ST_FLAG_RW, 0, "System.Email[3].Selected", 0, 0, NULL },
793 { "System.Email[3].Enotify", ST_FLAG_RW, 0, "System.Email[3].Enotify", 0, 0, NULL },
794 { "System.Email[3].Measures.Log", ST_FLAG_RW, 0, "System.Email[3].Measures.Log", 0, 0, NULL },
795 { "System.Email[3].Events.Log", ST_FLAG_RW, 0, "System.Email[3].Events.Log", 0, 0, NULL },
796 { "System.Email[3].SystemEvents.Log", ST_FLAG_RW, 0, "System.Email[3].SystemEvents.Log", 0, 0, NULL },
797 { "System.Email[3].Environment.Log", ST_FLAG_RW, 0, "System.Email[3].Environment.Log", 0, 0, NULL },
798 { "System.Email[3].Report.Periodicity", ST_FLAG_RW, 0, "System.Email[3].Report.Periodicity", 0, 0, NULL },
799 { "System.Email[3].Report.Hour", ST_FLAG_RW, 0, "System.Email[3].Report.Hour", 0, 0, NULL },
800 { "System.Email[3].Report.Next", ST_FLAG_RW, 0, "System.Email[3].Report.Next", 0, 0, NULL },
801 { "System.Email[3].EventList.Discharging", ST_FLAG_RW, 0, "System.Email[3].EventList.Discharging", 0, 0, NULL },
802 { "System.Email[3].EventList.ACPresent", ST_FLAG_RW, 0, "System.Email[3].EventList.ACPresent", 0, 0, NULL },
803 { "System.Email[3].EventList.RunTimeToShutdown", ST_FLAG_RW, 0, "System.Email[3].EventList.RunTimeToShutdown", 0, 0, NULL },
804 { "System.Email[3].EventList.BelowRemainingCapacityLimit", ST_FLAG_RW, 0, "System.Email[3].EventList.BelowRemainingCapacityLimit", 0, 0, NULL },
805 { "System.Email[3].EventList.NeedReplacement.1", ST_FLAG_RW, 0, "System.Email[3].EventList.NeedReplacement.1", 0, 0, NULL },
806 { "System.Email[3].EventList.NeedReplacement.0", ST_FLAG_RW, 0, "System.Email[3].EventList.NeedReplacement.0", 0, 0, NULL },
807 { "System.Email[3].EventList.Overload.1", ST_FLAG_RW, 0, "System.Email[3].EventList.Overload.1", 0, 0, NULL },
808 { "System.Email[3].EventList.Overload.0", ST_FLAG_RW, 0, "System.Email[3].EventList.Overload.0", 0, 0, NULL },
809 { "System.Email[3].EventList.InternalFailure.1", ST_FLAG_RW, 0, "System.Email[3].EventList.InternalFailure.1", 0, 0, NULL },
810 { "System.Email[3].EventList.InternalFailure.0", ST_FLAG_RW, 0, "System.Email[3].EventList.InternalFailure.0", 0, 0, NULL },
811 { "System.Email[3].EventList.CommunicationLost.1", ST_FLAG_RW, 0, "System.Email[3].EventList.CommunicationLost.1", 0, 0, NULL },
812 { "System.Email[3].EventList.CommunicationLost.0", ST_FLAG_RW, 0, "System.Email[3].EventList.CommunicationLost.0", 0, 0, NULL },
813 { "System.Email[3].EventList.Charger.InternalFailure", ST_FLAG_RW, 0, "System.Email[3].EventList.Charger.InternalFailure", 0, 0, NULL },
814 { "System.Email[3].EventList.Input[2].Used.1", ST_FLAG_RW, 0, "System.Email[3].EventList.Input[2].Used.1", 0, 0, NULL },
815 { "System.Email[3].EventList.Input[2].Used.0", ST_FLAG_RW, 0, "System.Email[3].EventList.Input[2].Used.0", 0, 0, NULL },
816 { "System.Email[3].EventList.PowerModule.RedundancyLost.1", ST_FLAG_RW, 0, "System.Email[3].EventList.PowerModule.RedundancyLost.1", 0, 0, NULL },
817 { "System.Email[3].EventList.PowerModule.RedundancyLost.0", ST_FLAG_RW, 0, "System.Email[3].EventList.PowerModule.RedundancyLost.0", 0, 0, NULL },
818 { "System.Email[3].EventList.PowerModule.ProtectionLost.1", ST_FLAG_RW, 0, "System.Email[3].EventList.PowerModule.ProtectionLost.1", 0, 0, NULL },
819 { "System.Email[3].EventList.PowerModule.ProtectionLost.0", ST_FLAG_RW, 0, "System.Email[3].EventList.PowerModule.ProtectionLost.0", 0, 0, NULL },
820 { "System.Email[3].EventList.FirmwareUpgrade", ST_FLAG_RW, 0, "System.Email[3].EventList.FirmwareUpgrade", 0, 0, NULL },
821 { "System.Email[3].EventList.Environment.CommunicationLost", ST_FLAG_RW, 0, "System.Email[3].EventList.Environment.CommunicationLost", 0, 0, NULL },
822 { "System.Email[3].EventList.Environment.Notify", ST_FLAG_RW, 0, "System.Email[3].EventList.Environment.Notify", 0, 0, NULL },
823 { "System.Schedule[0].Off", ST_FLAG_RW, 0, "System.Schedule[0].Off", 0, 0, NULL },
824 { "System.Schedule[0].On", ST_FLAG_RW, 0, "System.Schedule[0].On", 0, 0, NULL },
825 { "System.Schedule[1].Off", ST_FLAG_RW, 0, "System.Schedule[1].Off", 0, 0, NULL },
826 { "System.Schedule[1].On", ST_FLAG_RW, 0, "System.Schedule[1].On", 0, 0, NULL },
827 { "System.Schedule[2].Off", ST_FLAG_RW, 0, "System.Schedule[2].Off", 0, 0, NULL },
828 { "System.Schedule[2].On", ST_FLAG_RW, 0, "System.Schedule[2].On", 0, 0, NULL },
829 { "System.Schedule[3].Off", ST_FLAG_RW, 0, "System.Schedule[3].Off", 0, 0, NULL },
830 { "System.Schedule[3].On", ST_FLAG_RW, 0, "System.Schedule[3].On", 0, 0, NULL },
831 { "System.Schedule[4].Off", ST_FLAG_RW, 0, "System.Schedule[4].Off", 0, 0, NULL },
832 { "System.Schedule[4].On", ST_FLAG_RW, 0, "System.Schedule[4].On", 0, 0, NULL },
833 { "System.Schedule[5].Off", ST_FLAG_RW, 0, "System.Schedule[5].Off", 0, 0, NULL },
834 { "System.Schedule[5].On", ST_FLAG_RW, 0, "System.Schedule[5].On", 0, 0, NULL },
835 { "System.Schedule[6].Off", ST_FLAG_RW, 0, "System.Schedule[6].Off", 0, 0, NULL },
836 { "System.Schedule[6].On", ST_FLAG_RW, 0, "System.Schedule[6].On", 0, 0, NULL },
837 { "System.NetworkManagementSystem[0].Name", ST_FLAG_RW, 0, "System.NetworkManagementSystem[0].Name", 0, 0, NULL },
838 { "System.NetworkManagementSystem[0].HostName", ST_FLAG_RW, 0, "System.NetworkManagementSystem[0].HostName", 0, 0, NULL },
839 { "System.NetworkManagementSystem[0].TrapCommunity", ST_FLAG_RW, 0, "System.NetworkManagementSystem[0].TrapCommunity", 0, 0, NULL },
840 { "System.NetworkManagementSystem[0].TrapSnmpVersion", ST_FLAG_RW, 0, "System.NetworkManagementSystem[0].TrapSnmpVersion", 0, 0, NULL },
841 { "System.NetworkManagementSystem[0].TrapSelectedMibs", ST_FLAG_RW, 0, "System.NetworkManagementSystem[0].TrapSelectedMibs", 0, 0, NULL },
842 { "System.NetworkManagementSystem[1].Name", ST_FLAG_RW, 0, "System.NetworkManagementSystem[1].Name", 0, 0, NULL },
843 { "System.NetworkManagementSystem[1].HostName", ST_FLAG_RW, 0, "System.NetworkManagementSystem[1].HostName", 0, 0, NULL },
844 { "System.NetworkManagementSystem[1].TrapCommunity", ST_FLAG_RW, 0, "System.NetworkManagementSystem[1].TrapCommunity", 0, 0, NULL },
845 { "System.NetworkManagementSystem[1].TrapSnmpVersion", ST_FLAG_RW, 0, "System.NetworkManagementSystem[1].TrapSnmpVersion", 0, 0, NULL },
846 { "System.NetworkManagementSystem[1].TrapSelectedMibs", ST_FLAG_RW, 0, "System.NetworkManagementSystem[1].TrapSelectedMibs", 0, 0, NULL },
847 { "System.NetworkManagementSystem[2].Name", ST_FLAG_RW, 0, "System.NetworkManagementSystem[2].Name", 0, 0, NULL },
848 { "System.NetworkManagementSystem[2].HostName", ST_FLAG_RW, 0, "System.NetworkManagementSystem[2].HostName", 0, 0, NULL },
849 { "System.NetworkManagementSystem[2].TrapCommunity", ST_FLAG_RW, 0, "System.NetworkManagementSystem[2].TrapCommunity", 0, 0, NULL },
850 { "System.NetworkManagementSystem[2].TrapSnmpVersion", ST_FLAG_RW, 0, "System.NetworkManagementSystem[2].TrapSnmpVersion", 0, 0, NULL },
851 { "System.NetworkManagementSystem[2].TrapSelectedMibs", ST_FLAG_RW, 0, "System.NetworkManagementSystem[2].TrapSelectedMibs", 0, 0, NULL },
852 { "System.ClientCfg.ShutdownTimer.Select", ST_FLAG_RW, 0, "System.ClientCfg.ShutdownTimer.Select", 0, 0, NULL },
853 { "System.ClientCfg.ShutdownTimer", ST_FLAG_RW, 0, "System.ClientCfg.ShutdownTimer", 0, 0, NULL },
854 { "System.ClientCfg.ShutdownDuration", ST_FLAG_RW, 0, "System.ClientCfg.ShutdownDuration", 0, 0, NULL },
855 { "System.ClientCfg.BroadcastAdmins", ST_FLAG_RW, 0, "System.ClientCfg.BroadcastAdmins", 0, 0, NULL },
856 { "System.ClientCfg.BroadcastUsers", ST_FLAG_RW, 0, "System.ClientCfg.BroadcastUsers", 0, 0, NULL },
857 { "Environment.iName", ST_FLAG_RW, 0, "Environment.iName", 0, 0, NULL },
858 { "Environment.Temperature.Unit", ST_FLAG_RW, 0, "Environment.Temperature.Unit", 0, 0, NULL },
859 { "Environment.Temperature.Hysteresis", ST_FLAG_RW, 0, "Environment.Temperature.Hysteresis", 0, 0, NULL },
860 { "Environment.Temperature.Offset", ST_FLAG_RW, 0, "Environment.Temperature.Offset", 0, 0, NULL },
861 { "Environment.Temperature.HighNotify", ST_FLAG_RW, 0, "Environment.Temperature.HighNotify", 0, 0, NULL },
862 { "Environment.Temperature.LowNotify", ST_FLAG_RW, 0, "Environment.Temperature.LowNotify", 0, 0, NULL },
863 { "Environment.Temperature.HighShutdown", ST_FLAG_RW, 0, "Environment.Temperature.HighShutdown", 0, 0, NULL },
864 { "Environment.Temperature.LowShutdown", ST_FLAG_RW, 0, "Environment.Temperature.LowShutdown", 0, 0, NULL },
865 { "Environment.Humidity.Hysteresis", ST_FLAG_RW, 0, "Environment.Humidity.Hysteresis", 0, 0, NULL },
866 { "Environment.Humidity.Offset", ST_FLAG_RW, 0, "Environment.Humidity.Offset", 0, 0, NULL },
867 { "Environment.Humidity.HighNotify", ST_FLAG_RW, 0, "Environment.Humidity.HighNotify", 0, 0, NULL },
868 { "Environment.Humidity.LowNotify", ST_FLAG_RW, 0, "Environment.Humidity.LowNotify", 0, 0, NULL },
869 { "Environment.Humidity.HighShutdown", ST_FLAG_RW, 0, "Environment.Humidity.HighShutdown", 0, 0, NULL },
870 { "Environment.Humidity.LowShutdown", ST_FLAG_RW, 0, "Environment.Humidity.LowShutdown", 0, 0, NULL },
871 { "Environment.Input[1].iName", ST_FLAG_RW, 0, "Environment.Input[1].iName", 0, 0, NULL },
872 { "Environment.Input[1].State[0].Description", ST_FLAG_RW, 0, "Environment.Input[1].State[0].Description", 0, 0, NULL },
873 { "Environment.Input[1].State[0].Notify", ST_FLAG_RW, 0, "Environment.Input[1].State[0].Notify", 0, 0, NULL },
874 { "Environment.Input[1].State[0].Shutdown", ST_FLAG_RW, 0, "Environment.Input[1].State[0].Shutdown", 0, 0, NULL },
875 { "Environment.Input[1].State[1].Description", ST_FLAG_RW, 0, "Environment.Input[1].State[1].Description", 0, 0, NULL },
876 { "Environment.Input[1].State[1].Notify", ST_FLAG_RW, 0, "Environment.Input[1].State[1].Notify", 0, 0, NULL },
877 { "Environment.Input[1].State[1].Shutdown", ST_FLAG_RW, 0, "Environment.Input[1].State[1].Shutdown", 0, 0, NULL },
878 { "Environment.Input[2].iName", ST_FLAG_RW, 0, "Environment.Input[2].iName", 0, 0, NULL },
879 { "Environment.Input[2].State[0].Description", ST_FLAG_RW, 0, "Environment.Input[2].State[0].Description", 0, 0, NULL },
880 { "Environment.Input[2].State[0].Notify", ST_FLAG_RW, 0, "Environment.Input[2].State[0].Notify", 0, 0, NULL },
881 { "Environment.Input[2].State[0].Shutdown", ST_FLAG_RW, 0, "Environment.Input[2].State[0].Shutdown", 0, 0, NULL },
882 { "Environment.Input[2].State[1].Description", ST_FLAG_RW, 0, "Environment.Input[2].State[1].Description", 0, 0, NULL },
883 { "Environment.Input[2].State[1].Notify", ST_FLAG_RW, 0, "Environment.Input[2].State[1].Notify", 0, 0, NULL },
884 { "Environment.Input[2].State[1].Shutdown", ST_FLAG_RW, 0, "Environment.Input[2].State[1].Shutdown", 0, 0, NULL },
885 { "System.TimeSync", ST_FLAG_RW, 0, "System.TimeSync", 0, 0, NULL },
886 { "System.TimeNtp", ST_FLAG_RW, 0, "System.TimeNtp", 0, 0, NULL },
887 { "System.TimeZone", ST_FLAG_RW, 0, "System.TimeZone", 0, 0, NULL },
888 { "System.TimeDaylight", ST_FLAG_RW, 0, "System.TimeDaylight", 0, 0, NULL },
889 #endif /* not interresting for NUT */
890
891 /* Special case: boolean values that are mapped to ups.status and ups.alarm */
892 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", 0, 0, online_info },
893 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.Charging", 0, 0, charging_info },
894 /* NMC bug: keep discharging test AFTER charging test */
895 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.Discharging", 0, 0, discharging_info },
896 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit", 0, 0, lowbatt_info },
897 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.Overload", 0, 0, overload_info },
898 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.NeedReplacement", 0, 0, replacebatt_info },
899 { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.Buck", 0, 0, trim_info },
900 { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.Boost", 0, 0, boost_info },
901 { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.VoltageOutOfRange", 0, 0, vrange_info },
902 { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.FrequencyOutOfRange", 0, 0, frange_info },
903 { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.FuseFault", 0, 0, fuse_fault_info },
904 { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.InternalFailure", 0, 0, internalfailure_info },
905 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.Good", 0, 0, off_info },
906 /* { NULL, 0, 0, "UPS.PowerConverter.Input[1].PresentStatus.Used", 0, 0, online_info }, */
907 { NULL, 0, 0, "UPS.PowerConverter.Input[2].PresentStatus.Used", 0, 0, bypass_aut_info }, /* Automatic bypass */
908 /* { NULL, 0, 0, "UPS.PowerConverter.Input[3].PresentStatus.Used", 0, 0, onbatt_info }, */
909 { NULL, 0, 0, "UPS.PowerConverter.Input[4].PresentStatus.Used", 0, 0, bypass_man_info }, /* Manual bypass */
910 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.FanFailure", 0, 0, fanfail_info },
911 { NULL, 0, 0, "UPS.BatterySystem.Battery.PresentStatus.Present", 0, 0, nobattery_info },
912 { NULL, 0, 0, "UPS.BatterySystem.Charger.PresentStatus.InternalFailure", 0, 0, chargerfail_info },
913 { NULL, 0, 0, "UPS.BatterySystem.Charger.PresentStatus.VoltageTooHigh", 0, 0, battvolthi_info },
914 { NULL, 0, 0, "UPS.BatterySystem.Charger.PresentStatus.VoltageTooLow", 0, 0, battvoltlo_info },
915 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.InternalFailure", 0, 0, internalfailure_info },
916 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.CommunicationLost", 0, 0, commfault_info },
917 { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.OverTemperature", 0, 0, overheat_info },
918 /* { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.ShutdownImminent", 0, 0, shutdownimm_info }, */
919
920 /* Battery page */
921 { "battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", 0, 0, NULL },
922 { "battery.charge.low", 0, 0, "UPS.PowerSummary.RemainingCapacityLimitSetting", 0, 0, NULL },
923 { "battery.charge.low", 0, 0, "UPS.PowerSummary.RemainingCapacityLimit", 0, 0, NULL }, /* Read only */
924 { "battery.charge.restart", 0, 0, "UPS.PowerSummary.RestartLevel", 0, 0, NULL },
925 { "battery.capacity", 0, 0, "UPS.BatterySystem.Battery.DesignCapacity", 0, 0, mge_battery_capacity }, /* conversion needed from As to Ah */
926 { "battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", 0, 0, NULL },
927 { "battery.runtime.low", ST_FLAG_RW, 0, "System.RunTimeToEmptyLimit", 0, 0, NULL },
928 { "battery.temperature", 0, 0, "UPS.BatterySystem.Battery.Temperature", 0, 0, NULL },
929 { "battery.packs.external", 0, 0, "UPS.BatterySystem.Battery.Count", 0, 0, NULL },
930 { "battery.type", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iDeviceChemistry", 0, 0, NULL },
931 { "battery.type", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iDeviceChemistery", 0, 0, NULL }, /* [sic] */
932 { "battery.voltage.nominal", ST_FLAG_STATIC, 0, "UPS.BatterySystem.ConfigVoltage", 0, 0, NULL },
933 { "battery.protection", 0, 0, "UPS.BatterySystem.Battery.DeepDischargeProtection", 0, 0, yes_no_info },
934 { "battery.energysave", 0, 0, "UPS.PowerConverter.Input[3].EnergySaving", 0, 0, yes_no_info },
935
936 /* UPS page */
937 { "ups.mfr", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iManufacturer", 0, 0, NULL },
938 { "ups.model", ST_FLAG_STATIC, 0, "System.Description", 0, 0, NULL },
939 { "ups.model", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iProduct", 0, 0, NULL },
940 { "ups.model.aux", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iModel", 0, 0, NULL },
941 { "ups.time", 0, 0, "System.LastAcquisition", 0, 0, split_date_time },
942 /* -> XML variable System.Location [Computer Room] doesn't map to any NUT variable */
943 /* -> XML variable System.Contact [Computer Room Manager] doesn't map to any NUT variable */
944 /* -> XML variable UPS.PowerSummary.iProduct [Evolution] doesn't map to any NUT variable */
945 /* -> XML variable UPS.PowerSummary.iModel [650] doesn't map to any NUT variable */
946 { "ups.serial", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iSerialNumber", 0, 0, NULL },
947 { "ups.firmware", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iVersion", 0, 0, NULL },
948 { "ups.load", 0, 0, "UPS.PowerSummary.PercentLoad", 0, 0, NULL },
949 { "ups.load.high", 0, 0, "UPS.Flow[4].ConfigPercentLoad", 0, 0, NULL },
950 { "ups.delay.shutdown", ST_FLAG_RW, 0, "System.ShutdownDuration", 0, 0, NULL },
951 { "ups.timer.start", ST_FLAG_RW, 0, "UPS.PowerSummary.DelayBeforeStartup", 0, 0, NULL},
952 { "ups.timer.shutdown", ST_FLAG_RW, 0, "UPS.PowerSummary.DelayBeforeShutdown", 0, 0, mge_timer_shutdown },
953 /* Catch shutdown imminent criteria, keep it after
954 UPS.PowerSummary.DelayBeforeShutdown managment */
955 { NULL, 0, 0, "System.RunTimeToShutdown", 0, 0, mge_shutdown_imminent },
956 { "ups.timer.reboot", 0, 0, "UPS.PowerSummary.DelayBeforeReboot", 0, 0, NULL },
957 { "ups.test.result", 0, 0, "UPS.BatterySystem.Battery.Test", 0, 0, mge_test_result_info },
958 { "ups.test.interval", 0, 0, "UPS.BatterySystem.Battery.TestPeriod", 0, 0, NULL },
959 { "ups.beeper.status", 0 ,0, "UPS.BatterySystem.Battery.AudibleAlarmControl", 0, 0, mge_beeper_info },
960 { "ups.beeper.status", 0 ,0, "UPS.PowerSummary.AudibleAlarmControl", 0, 0, mge_beeper_info },
961 { "ups.temperature", 0, 0, "UPS.PowerSummary.Temperature", 0, 0, NULL },
962 { "ups.power", 0, 0, "UPS.PowerConverter.Output.ApparentPower", 0, 0, NULL },
963 { "ups.L1.power", 0, 0, "UPS.PowerConverter.Output.Phase[1].ApparentPower", 0, 0, ignore_if_zero },
964 { "ups.L2.power", 0, 0, "UPS.PowerConverter.Output.Phase[2].ApparentPower", 0, 0, ignore_if_zero },
965 { "ups.L3.power", 0, 0, "UPS.PowerConverter.Output.Phase[3].ApparentPower", 0, 0, ignore_if_zero },
966 { "ups.power.nominal", ST_FLAG_STATIC, 0, "UPS.Flow[4].ConfigApparentPower", 0, 0, NULL },
967 { "ups.realpower", 0, 0, "UPS.PowerConverter.Output.ActivePower", 0, 0, NULL },
968 { "ups.L1.realpower", 0, 0, "UPS.PowerConverter.Output.Phase[1].ActivePower", 0, 0, ignore_if_zero },
969 { "ups.L2.realpower", 0, 0, "UPS.PowerConverter.Output.Phase[2].ActivePower", 0, 0, ignore_if_zero },
970 { "ups.L3.realpower", 0, 0, "UPS.PowerConverter.Output.Phase[3].ActivePower", 0, 0, ignore_if_zero },
971 { "ups.realpower.nominal", ST_FLAG_STATIC, 0, "UPS.Flow[4].ConfigActivePower", 0, 0, NULL },
972 { "ups.start.auto", 0, 0, "UPS.PowerConverter.Input[1].AutomaticRestart", 0, 0, yes_no_info },
973 { "ups.start.battery", 0, 0, "UPS.PowerConverter.Input[3].StartOnBattery", 0, 0, yes_no_info },
974 { "ups.start.reboot", 0, 0, "UPS.PowerConverter.Output.ForcedReboot", 0, 0, yes_no_info },
975 { "ups.type", ST_FLAG_STATIC, 0, "UPS.PowerConverter.ConverterType", 0, 0, mge_upstype_conversion },
976
977 /* Input page */
978 { "input.voltage", 0, 0, "UPS.PowerConverter.Input[1].Voltage", 0, 0, NULL },
979 { "input.L1-N.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[1].Voltage", 0, 0, NULL },
980 { "input.L2-N.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[2].Voltage", 0, 0, NULL },
981 { "input.L3-N.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[3].Voltage", 0, 0, NULL },
982 { "input.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[12].Voltage", 0, 0, NULL },
983 { "input.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[23].Voltage", 0, 0, NULL },
984 { "input.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[31].Voltage", 0, 0, NULL },
985 { "input.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[11].Voltage", 0, 0, convert_deci },
986 { "input.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[22].Voltage", 0, 0, convert_deci },
987 { "input.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Input[1].Phase[33].Voltage", 0, 0, convert_deci },
988 { "input.voltage.nominal", 0, 0, "UPS.Flow[1].ConfigVoltage", 0, 0, NULL },
989 { "input.current", 0, 0, "UPS.PowerConverter.Input[1].Current", 0, 0, NULL },
990 { "input.L1.current", 0, 0, "UPS.PowerConverter.Input[1].Phase[1].Current", 0, 0, convert_deci },
991 { "input.L2.current", 0, 0, "UPS.PowerConverter.Input[1].Phase[2].Current", 0, 0, convert_deci },
992 { "input.L3.current", 0, 0, "UPS.PowerConverter.Input[1].Phase[3].Current", 0, 0, convert_deci },
993 { "input.current.nominal", 0, 0, "UPS.Flow[1].ConfigCurrent", 0, 0, NULL },
994 { "input.frequency", 0, 0, "UPS.PowerConverter.Input[1].Frequency", 0, 0, NULL },
995 { "input.frequency.nominal", 0, 0, "UPS.Flow[1].ConfigFrequency", 0, 0, NULL },
996 { "input.voltage.extended", 0, 0, "UPS.PowerConverter.Output.ExtendedVoltageMode", 0, 0, yes_no_info },
997 { "input.frequency.extended", 0, 0, "UPS.PowerConverter.Output.ExtendedFrequencyMode", 0, 0, yes_no_info },
998 /* same as "input.transfer.boost.low" */
999 { "input.transfer.low", 0, 0, "UPS.PowerConverter.Output.LowVoltageTransfer", 0, 0, NULL },
1000 { "input.transfer.boost.low", 0, 0, "UPS.PowerConverter.Output.LowVoltageBoostTransfer", 0, 0, NULL },
1001 { "input.transfer.boost.high", 0, 0, "UPS.PowerConverter.Output.HighVoltageBoostTransfer", 0, 0, NULL },
1002 { "input.transfer.trim.low", 0, 0, "UPS.PowerConverter.Output.LowVoltageBuckTransfer", 0, 0, NULL },
1003 /* same as "input.transfer.trim.high" */
1004 { "input.transfer.high", 0, 0, "UPS.PowerConverter.Output.HighVoltageTransfer", 0, 0, NULL },
1005 { "input.transfer.trim.high", 0, 0, "UPS.PowerConverter.Output.HighVoltageBuckTransfer", 0, 0, NULL },
1006 { "input.sensitivity", 0, 0, "UPS.PowerConverter.Output.SensitivityMode", 0, 0, mge_sensitivity_info },
1007
1008 /* Bypass page */
1009 { "input.bypass.voltage", 0, 0, "UPS.PowerConverter.Input[2].Voltage", 0, 0, NULL },
1010 { "input.bypass.L1-N.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[1].Voltage", 0, 0, NULL },
1011 { "input.bypass.L2-N.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[2].Voltage", 0, 0, NULL },
1012 { "input.bypass.L3-N.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[3].Voltage", 0, 0, NULL },
1013 { "input.bypass.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[12].Voltage", 0, 0, NULL },
1014 { "input.bypass.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[23].Voltage", 0, 0, NULL },
1015 { "input.bypass.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[31].Voltage", 0, 0, NULL },
1016 { "input.bypass.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[11].Voltage", 0, 0, NULL },
1017 { "input.bypass.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[22].Voltage", 0, 0, NULL },
1018 { "input.bypass.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Input[2].Phase[33].Voltage", 0, 0, NULL },
1019 { "input.bypass.voltage.nominal", 0, 0, "UPS.Flow[2].ConfigVoltage", 0, 0, NULL },
1020 { "input.bypass.current", 0, 0, "UPS.PowerConverter.Input[2].Current", 0, 0, NULL },
1021 { "input.bypass.L1.current", 0, 0, "UPS.PowerConverter.Input[2].Phase[1].Current", 0, 0, NULL },
1022 { "input.bypass.L2.current", 0, 0, "UPS.PowerConverter.Input[2].Phase[2].Current", 0, 0, NULL },
1023 { "input.bypass.L3.current", 0, 0, "UPS.PowerConverter.Input[2].Phase[3].Current", 0, 0, NULL },
1024 { "input.bypass.current.nominal", 0, 0, "UPS.Flow[2].ConfigCurrent", 0, 0, NULL },
1025 { "input.bypass.frequency", 0, 0, "UPS.PowerConverter.Input[2].Frequency", 0, 0, NULL },
1026 { "input.bypass.frequency.nominal", 0, 0, "UPS.Flow[2].ConfigFrequency", 0, 0, NULL },
1027
1028 /* Output page */
1029 { "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", 0, 0, NULL },
1030 { "output.L1-N.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[1].Voltage", 0, 0, NULL },
1031 { "output.L2-N.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[2].Voltage", 0, 0, NULL },
1032 { "output.L3-N.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[3].Voltage", 0, 0, NULL },
1033 { "output.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[12].Voltage", 0, 0, NULL },
1034 { "output.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[23].Voltage", 0, 0, NULL },
1035 { "output.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[31].Voltage", 0, 0, NULL },
1036 { "output.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[11].Voltage", 0, 0, ignore_if_zero },
1037 { "output.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[22].Voltage", 0, 0, ignore_if_zero },
1038 { "output.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[33].Voltage", 0, 0, ignore_if_zero },
1039 { "output.voltage.nominal", 0, 0, "UPS.Flow[4].ConfigVoltage", 0, 0, NULL },
1040 { "output.current", 0, 0, "UPS.PowerConverter.Output.Current", 0, 0, NULL },
1041 { "output.L1.current", 0, 0, "UPS.PowerConverter.Output.Phase[1].Current", 0, 0, convert_deci },
1042 { "output.L2.current", 0, 0, "UPS.PowerConverter.Output.Phase[2].Current", 0, 0, convert_deci },
1043 { "output.L3.current", 0, 0, "UPS.PowerConverter.Output.Phase[3].Current", 0, 0, convert_deci },
1044 { "output.current.nominal", 0, 0, "UPS.Flow[4].ConfigCurrent", 0, 0, NULL },
1045 { "output.frequency", 0, 0, "UPS.PowerConverter.Output.Frequency", 0, 0, NULL },
1046 { "output.frequency.nominal", 0, 0, "UPS.Flow[4].ConfigFrequency", 0, 0, NULL },
1047 { "output.powerfactor", 0, 0, "UPS.PowerConverter.Output.PowerFactor", 0, 0, mge_powerfactor_conversion },
1048
1049 /* Ambient page */
1050 { "ambient.humidity", 0, 0, "Environment.Humidity", 0, 0, NULL },
1051 { "ambient.humidity.high", ST_FLAG_RW, 0, "Environment.Humidity.HighThreshold", 0, 0, NULL },
1052 { "ambient.humidity.low", ST_FLAG_RW, 0, "Environment.Humidity.LowThreshold", 0, 0, NULL },
1053 { "ambient.humidity.maximum", 0, 0, "Environment.PresentStatus.HighHumidity", 0, 0, mge_ambient_info },
1054 { "ambient.humidity.minimum", 0, 0, "Environment.PresentStatus.LowHumidity", 0, 0, mge_ambient_info },
1055 { "ambient.temperature", 0, 0, "Environment.Temperature", 0, 0, NULL },
1056 { "ambient.temperature.high", ST_FLAG_RW, 0, "Environment.Temperature.HighThreshold", 0, 0, NULL },
1057 { "ambient.temperature.low", ST_FLAG_RW, 0, "Environment.Temperature.LowThreshold", 0, 0, NULL },
1058 { "ambient.temperature.maximum", 0, 0, "Environment.PresentStatus.HighTemperature", 0, 0, mge_ambient_info },
1059 { "ambient.temperature.minimum", 0, 0, "Environment.PresentStatus.LowTemperature", 0, 0, mge_ambient_info },
1060
1061 /* Outlet page (using MGE UPS SYSTEMS - PowerShare technology) */
1062 { "outlet.id", 0, 0, "UPS.OutletSystem.Outlet[1].OutletID", 0, 0, NULL },
1063 { "outlet.desc", 0, 0, "UPS.OutletSystem.Outlet[1].iName", 0, 0, NULL },
1064 { "outlet.switchable", 0, 0, "UPS.OutletSystem.Outlet[1].PresentStatus.Switchable", 0, 0, yes_no_info },
1065
1066 { "outlet.1.id", 0, 0, "UPS.OutletSystem.Outlet[2].OutletID", 0, 0, NULL },
1067 { "outlet.1.desc", 0, 0, "UPS.OutletSystem.Outlet[2].iName", 0, 0, NULL },
1068 { "outlet.1.switchable", 0, 0, "UPS.OutletSystem.Outlet[2].PresentStatus.Switchable", 0, 0, yes_no_info },
1069 { "outlet.1.status", 0, 0, "UPS.OutletSystem.Outlet[2].PresentStatus.SwitchOnOff", 0, 0, on_off_info },
1070 /* For low end models, with 1 non backup'ed outlet */
1071 { "outlet.1.status", 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", 0, 0, NULL }, /* on_off_info */
1072 { "outlet.1.battery.charge.low", 0, 0, "UPS.OutletSystem.Outlet[2].RemainingCapacityLimit", 0, 0, NULL },
1073 { "outlet.1.timer.start", 0, 0, "UPS.OutletSystem.Outlet[2].DelayBeforeStartup", 0, 0, NULL },
1074 { "outlet.1.timer.shutdown", 0, 0, "UPS.OutletSystem.Outlet[2].DelayBeforeShutdown", 0, 0, NULL },
1075 { "outlet.1.delay.start", 0, 0, "UPS.OutletSystem.Outlet[2].StartupTimer", 0, 0, NULL },
1076 /* { "outlet.1.delay.shutdown", 0, 0, "UPS.OutletSystem.Outlet[2].ShutdownTimer", 0, 0, NULL }, */
1077 { "outlet.1.delay.shutdown", ST_FLAG_RW, 0, "System.Outlet[2].ShutdownDuration", 0, 0, NULL },
1078
1079 { "outlet.2.id", 0, 0, "UPS.OutletSystem.Outlet[3].OutletID", 0, 0, NULL },
1080 { "outlet.2.desc", 0, 0, "UPS.OutletSystem.Outlet[3].iName", 0, 0, NULL },
1081 { "outlet.2.switchable", 0, 0, "UPS.OutletSystem.Outlet[3].PresentStatus.Switchable", 0, 0, yes_no_info },
1082 { "outlet.2.status", 0, 0, "UPS.OutletSystem.Outlet[3].PresentStatus.SwitchOnOff", 0, 0, on_off_info },
1083 { "outlet.2.battery.charge.low", 0, 0, "UPS.OutletSystem.Outlet[3].RemainingCapacityLimit", 0, 0, NULL },
1084 { "outlet.2.timer.start", 0, 0, "UPS.OutletSystem.Outlet[3].DelayBeforeStartup", 0, 0, NULL },
1085 { "outlet.2.timer.shutdown", 0, 0, "UPS.OutletSystem.Outlet[3].DelayBeforeShutdown", 0, 0, NULL },
1086 { "outlet.2.delay.start", 0, 0, "UPS.OutletSystem.Outlet[3].StartupTimer", 0, 0, NULL },
1087 /* { "outlet.2.delay.shutdown", 0, 0, "UPS.OutletSystem.Outlet[3].ShutdownTimer", 0, 0, NULL }, */
1088 { "outlet.2.delay.shutdown", ST_FLAG_RW, 0, "System.Outlet[3].ShutdownDuration", 0, 0, NULL },
1089
1090 /* For newer ePDU Monitored */
1091 { "outlet.1.desc", 0, 0, "PDU.OutletSystem.Outlet[1].iName", 0, 0, NULL },
1092 { "outlet.1.current", 0, 0, "PDU.OutletSystem.Outlet[1].Current", 0, 0, convert_deci },
1093 /* FIXME: also map these?
1094 * "PDU.OutletSystem.Outlet[1].CurrentLimit" => settable, triggers CurrentTooHigh
1095 * "PDU.OutletSystem.Outlet[1].PresentStatus.CurrentTooHigh" (0/1)
1096 */
1097 { "outlet.2.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
1098 { "outlet.2.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
1099 { "outlet.3.desc", 0, 0, "PDU.OutletSystem.Outlet[3].iName", 0, 0, NULL },
1100 { "outlet.3.current", 0, 0, "PDU.OutletSystem.Outlet[3].Current", 0, 0, convert_deci },
1101 { "outlet.4.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
1102 { "outlet.4.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
1103 { "outlet.5.desc", 0, 0, "PDU.OutletSystem.Outlet[3].iName", 0, 0, NULL },
1104 { "outlet.5.current", 0, 0, "PDU.OutletSystem.Outlet[3].Current", 0, 0, convert_deci },
1105 { "outlet.6.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
1106 { "outlet.6.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
1107 { "outlet.7.desc", 0, 0, "PDU.OutletSystem.Outlet[3].iName", 0, 0, NULL },
1108 { "outlet.7.current", 0, 0, "PDU.OutletSystem.Outlet[3].Current", 0, 0, convert_deci },
1109 { "outlet.8.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
1110 { "outlet.8.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
1111
1112 { NULL, 0, 0, NULL, 0, 0, NULL }
1113 };
1114
1115 /* A start-element callback for element with given namespace/name. */
mge_xml_startelm_cb(void * userdata,int parent,const char * nspace,const char * name,const char ** atts)1116 static int mge_xml_startelm_cb(void *userdata, int parent, const char *nspace, const char *name, const char **atts)
1117 {
1118 int state = _UNEXPECTED;
1119 NUT_UNUSED_VARIABLE(userdata);
1120 NUT_UNUSED_VARIABLE(nspace);
1121
1122 switch(parent)
1123 {
1124 case ROOTPARENT:
1125 if (!strcasecmp(name, "PRODUCT_INFO")) {
1126 /* name="Network Management Card" type="Mosaic M" version="BA" */
1127 /* name="Network Management Card" type="Transverse" version="GB (SN 49EH29101)" */
1128 /* name="Monitored ePDU" type="Monitored ePDU" version="Version Upgrade" */
1129 /* name="PDU Network Management Card" type="SCOB" version="02.00.0036" signature="34008876" protocol="XML.V4" */
1130 int i;
1131 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1132 if (!strcasecmp(atts[i], "name")) {
1133 snprintf(val, sizeof(val), "%s", atts[i+1]);
1134 }
1135 if (!strcasecmp(atts[i], "type")) {
1136 snprintfcat(val, sizeof(val), "/%s", atts[i+1]);
1137 if (!strcasecmp(atts[i+1], "Transverse")) {
1138 mge_ambient_value = 1;
1139 } else if (strstr(atts[i+1], "ePDU")) {
1140 dstate_setinfo("device.type", "pdu");
1141 }
1142 }
1143 if (!strcasecmp(atts[i], "version")) {
1144 char *s;
1145 snprintfcat(val, sizeof(val), "/%s", atts[i+1]);
1146 s = strstr(val, " (SN ");
1147 if (s) {
1148 dstate_setinfo("ups.serial", "%s", str_rtrim(s + 5, ')'));
1149 s[0] = '\0';
1150 }
1151 dstate_setinfo("ups.firmware.aux", "%s", val);
1152 }
1153 /* netxml-ups currently only supports XML version 3 (for UPS),
1154 * and not version 4 (for UPS and PDU)! */
1155 if (!strcasecmp(atts[i], "protocol")) {
1156 if (!strcasecmp(atts[i+1], "XML.V4")) {
1157 fatalx(EXIT_FAILURE, "XML v4 protocol is not supported!");
1158 }
1159 }
1160 }
1161 state = PRODUCT_INFO;
1162 break;
1163 }
1164 if (!strcasecmp(name, "SUMMARY")) {
1165 state = SUMMARY;
1166 break;
1167 }
1168 if (!strcasecmp(name, "GET_OBJECT")) {
1169 state = GET_OBJECT;
1170 break;
1171 }
1172 if (!strcasecmp(name, "SET_OBJECT")) {
1173 state = SET_OBJECT;
1174 break;
1175 }
1176 if (!strcasecmp(name, "ALARM")) {
1177 int i;
1178 var[0] = val[0] = '\0';
1179 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1180 if (!strcasecmp(atts[i], "object")) {
1181 snprintf(var, sizeof(var), "%s", atts[i+1]);
1182 }
1183 if (!strcasecmp(atts[i], "value")) {
1184 snprintf(val, sizeof(var), "%s", atts[i+1]);
1185 }
1186 if (!strcasecmp(atts[i], "date")) {
1187 dstate_setinfo("ups.time", "%s", split_date_time(atts[i+1]));
1188 }
1189 }
1190 state = ALARM;
1191 break;
1192 }
1193 if (!strcasecmp(name, "XML-CLIENT")) {
1194 state = XML_CLIENT;
1195 break;
1196 }
1197 break;
1198
1199 case PRODUCT_INFO:
1200 if (!strcasecmp(name, "SUMMARY")) {
1201 state = PI_SUMMARY;
1202 break;
1203 }
1204
1205 if (!strcasecmp(name, "ALARMS")) {
1206 state = PI_ALARMS;
1207 break;
1208 }
1209
1210 if (!strcasecmp(name, "MANAGEMENT")) {
1211 state = PI_MANAGEMENT;
1212 break;
1213 }
1214
1215 if ( (!strcasecmp(name, "UPS_DATA"))
1216 || (!strcasecmp(name, "DEV_DATA")) ) {
1217 state = PI_UPS_DATA;
1218 break;
1219 }
1220 break;
1221
1222 case PI_SUMMARY:
1223 if (!strcasecmp(name, "HTML_PROPERTIES_PAGE")) {
1224 /* url="mgeups/default.htm" */
1225 state = PI_HTML_PROPERTIES_PAGE;
1226 break;
1227 }
1228 if (!strcasecmp(name, "XML_SUMMARY_PAGE")) {
1229 /* url="upsprop.xml" or url="ws/summary.xml" */
1230 int i;
1231 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1232 if (!strncasecmp(atts[i], "url", 3)) {
1233 free(mge_xml_subdriver.summary);
1234 mge_xml_subdriver.summary = strdup(url_convert(atts[i+1]));
1235 }
1236 }
1237 state = PI_XML_SUMMARY_PAGE;
1238 break;
1239 }
1240 if (!strcasecmp(name, "CENTRAL_CFG")) {
1241 /* url="config.xml" */
1242 int i;
1243 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1244 if (!strncasecmp(atts[i], "url", 3)) {
1245 free(mge_xml_subdriver.configure);
1246 mge_xml_subdriver.configure = strdup(url_convert(atts[i+1]));
1247 }
1248 }
1249 state = PI_CENTRAL_CFG;
1250 break;
1251 }
1252 if (!strcasecmp(name, "CSV_LOGS")) {
1253 /* url="logevent.csv" dateRange="no" eventFiltering="no" */
1254 state = PI_CSV_LOGS;
1255 break;
1256 }
1257 break;
1258
1259 case PI_ALARMS:
1260 if (!strcasecmp(name, "SUBSCRIPTION")) {
1261 /* url="subscribe.cgi" security="basic" */
1262 int i;
1263 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1264 if (!strncasecmp(atts[i], "url", 3)) {
1265 free(mge_xml_subdriver.subscribe);
1266 mge_xml_subdriver.subscribe = strdup(url_convert(atts[i+1]));
1267 }
1268 }
1269 state = PI_SUBSCRIPTION;
1270 break;
1271 }
1272
1273 if (!strcasecmp(name, "POLLING")) {
1274 /* url="mgeups/lastalarms.cgi" security="none" */
1275 state = PI_POLLING;
1276 break;
1277 }
1278 break;
1279
1280
1281 case PI_MANAGEMENT:
1282 if (!strcasecmp(name, "MANAGEMENT_PAGE")) {
1283 /* name="Manager list" id="ManagerList" url="FS/FLASH0/TrapReceiverList.cfg" security="none" */
1284 /* name="Shutdown criteria settings" id="Shutdown" url="FS/FLASH0/ShutdownParameters.cfg" security="none" */
1285 /* name="Network settings" id="Network" url="FS/FLASH0/NetworkSettings.cfg" security="none" */
1286 /* name="Centralized configuration settings" id="ClientCfg" url="FS/FLASH0/CentralizedConfig.cfg" security="none" */
1287 state = PI_MANAGEMENT_PAGE;
1288 break;
1289 }
1290 if (!strcasecmp(name, "XML_MANAGEMENT_PAGE")) {
1291 /* name="Set Card Time" id="SetTime" url="management/set_time.xml" security="none" */
1292 state = PI_XML_MANAGEMENT_PAGE;
1293 break;
1294 }
1295 break;
1296
1297 case PI_UPS_DATA:
1298 if (!strcasecmp(name, "GET_OBJECT")) {
1299 /* url="getvalue.cgi" security="none" */
1300 int i;
1301 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1302 if (!strncasecmp(atts[i], "url", 3)) {
1303 free(mge_xml_subdriver.getobject);
1304 mge_xml_subdriver.getobject = strdup(url_convert(atts[i+1]));
1305 }
1306 }
1307 state = PI_GET_OBJECT;
1308 break;
1309 }
1310 if (!strcasecmp(name, "SET_OBJECT")) {
1311 /* url="setvalue.cgi" security="ssl" */
1312 int i;
1313 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1314 if (!strncasecmp(atts[i], "url", 3)) {
1315 free(mge_xml_subdriver.setobject);
1316 mge_xml_subdriver.setobject = strdup(url_convert(atts[i+1]));
1317 }
1318 }
1319 state = PI_SET_OBJECT;
1320 break;
1321 }
1322 break;
1323
1324 case SUMMARY:
1325 if (!strcasecmp(name, "OBJECT")) {
1326 /* name="UPS.PowerSummary.iProduct" */
1327 int i;
1328 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1329 if (!strcasecmp(atts[i], "name")) {
1330 snprintf(var, sizeof(var), "%s", atts[i+1]);
1331 val[0] = '\0'; /*don't inherit something from another object */
1332 }
1333 }
1334 state = SU_OBJECT;
1335 break;
1336 }
1337 break;
1338
1339 case GET_OBJECT:
1340 if (!strcasecmp(name, "OBJECT")) {
1341 /* name="System.RunTimeToEmptyLimit" unit="s" access="RW" */
1342 int i;
1343 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1344 if (!strcasecmp(atts[i], "name")) {
1345 snprintf(var, sizeof(var), "%s", atts[i+1]);
1346 val[0] = '\0'; /*don't inherit something from another object */
1347 }
1348 if (!strcasecmp(atts[i], "access")) {
1349 /* do something with RO/RW access? */
1350 }
1351 }
1352 state = GO_OBJECT;
1353 break;
1354 }
1355 break;
1356
1357 case XML_CLIENT:
1358 if (!strcasecmp(name, "GENERAL")) {
1359 state = XC_GENERAL;
1360 break;
1361 }
1362 /* FIXME? Is the fall-through to handling "GENERAL" intended?
1363 * was so in legacy code before the goto below... */
1364 goto fallthrough_case_general;
1365
1366 case XC_GENERAL:
1367 fallthrough_case_general:
1368 if (!strcasecmp(name, "STARTUP")) {
1369 /* config="CENTRALIZED" */
1370 state = XC_STARTUP;
1371 break;
1372 }
1373 if (!strcasecmp(name, "SHUTDOWN")) {
1374 /* shutdownTimer="NONE" shutdownDuration="150" */
1375 int i;
1376 for (i = 0; atts[i] && atts[i+1]; i += 2) {
1377 if (!strcasecmp(atts[i], "shutdownTimer")) {
1378 dstate_setinfo("driver.timer.shutdown", "%s", atts[i+1]);
1379 }
1380 if (!strcasecmp(atts[i], "shutdownDuration")) {
1381 dstate_setinfo("driver.delay.shutdown", "%s", atts[i+1]);
1382 }
1383 }
1384 state = XC_SHUTDOWN;
1385 break;
1386 }
1387 if (!strcasecmp(name, "BROADCAST")) {
1388 /* admins="ON" users="ON" */
1389 state = XC_BROADCAST;
1390 break;
1391 }
1392 }
1393
1394 upsdebugx(3, "%s: name <%s> (parent = %d, state = %d)", __func__, name, parent, state);
1395 return state;
1396 }
1397
1398 /* Character data callback; may return non-zero to abort the parse. */
mge_xml_cdata_cb(void * userdata,int state,const char * cdata,size_t len)1399 static int mge_xml_cdata_cb(void *userdata, int state, const char *cdata, size_t len)
1400 {
1401 NUT_UNUSED_VARIABLE(userdata);
1402
1403 /* skip empty lines */
1404 if ((len == 1) && (cdata[0] == '\n')) {
1405 upsdebugx(3, "%s: cdata ignored (state = %d)", __func__, state);
1406 return 0;
1407 }
1408
1409 upsdebugx(3, "%s: cdata [%.*s] (state = %d)", __func__, (int)len, cdata, state);
1410
1411 switch(state)
1412 {
1413 case ALARM:
1414 upsdebugx(2, "ALARM%.*s", (int)len, cdata);
1415 break;
1416
1417 case SU_OBJECT:
1418 case GO_OBJECT:
1419 snprintfcat(val, sizeof(val), "%.*s", (int)len, cdata);
1420 break;
1421 }
1422
1423 return 0;
1424 }
1425
1426 /* End element callback; may return non-zero to abort the parse. */
mge_xml_endelm_cb(void * userdata,int state,const char * nspace,const char * name)1427 static int mge_xml_endelm_cb(void *userdata, int state, const char *nspace, const char *name)
1428 {
1429 xml_info_t *info;
1430 const char *value;
1431 NUT_UNUSED_VARIABLE(userdata);
1432 NUT_UNUSED_VARIABLE(nspace);
1433
1434 /* ignore objects for which no value was set */
1435 if (strlen(val) == 0) {
1436 upsdebugx(3, "%s: name </%s> ignored, no value set (state = %d)", __func__, name, state);
1437 return 0;
1438 }
1439
1440 upsdebugx(3, "%s: name </%s> (state = %d)", __func__, name, state);
1441
1442 switch(state)
1443 {
1444 case ALARM:
1445 case SU_OBJECT:
1446 case GO_OBJECT:
1447 for (info = mge_xml2nut; info->xmlname != NULL; info++) {
1448 if (strcasecmp(var, info->xmlname)) {
1449 continue;
1450 }
1451
1452 upsdebugx(3, "-> XML variable %s [%s] maps to NUT variable %s", var, val, info->nutname);
1453
1454 if ((info->nutflags & ST_FLAG_STATIC) && dstate_getinfo(info->nutname)) {
1455 return 0;
1456 }
1457
1458 if (info->convert) {
1459 value = info->convert(val);
1460 upsdebugx(4, "-> XML variable %s [%s] which maps to NUT variable %s was converted to value %s for the NUT driver state", var, val, info->nutname, value);
1461 } else {
1462 value = val;
1463 }
1464
1465 if (value != NULL) {
1466 dstate_setinfo(info->nutname, "%s", value);
1467 }
1468
1469 return 0;
1470 }
1471
1472 upsdebugx(3, "-> XML variable %s [%s] doesn't map to any NUT variable", var, val);
1473 break;
1474
1475 case PI_GET_OBJECT:
1476 case GET_OBJECT:
1477 /* We've just got a snapshot of all runtime data, saved well into
1478 * dstate's already, so can estimate missing values if needed. */
1479
1480 /* For phase setup, we assume it does not change during run-time.
1481 * Essentially this means that once we've detected it is N-phase,
1482 * it stays this way for the rest of the driver run/life-time. */
1483 /* To change this behavior just flip the maychange flag to "1" */
1484
1485 dstate_detect_phasecount("input.", 1,
1486 &inited_phaseinfo_in, &num_inphases, 0);
1487 dstate_detect_phasecount("input.bypass.", 1,
1488 &inited_phaseinfo_bypass, &num_bypassphases, 0);
1489 dstate_detect_phasecount("output.", 1,
1490 &inited_phaseinfo_out, &num_outphases, 0);
1491
1492 break;
1493 }
1494
1495 return 0;
1496 }
1497
1498 subdriver_t mge_xml_subdriver = {
1499 MGE_XML_VERSION,
1500 MGE_XML_INITUPS,
1501 MGE_XML_INITINFO,
1502 NULL,
1503 NULL,
1504 NULL,
1505 NULL,
1506 NULL,
1507 mge_xml_startelm_cb,
1508 mge_xml_cdata_cb,
1509 mge_xml_endelm_cb,
1510 };
1511
vname_nut2mge_xml(const char * name)1512 const char *vname_nut2mge_xml(const char *name) {
1513 assert(NULL != name);
1514
1515 size_t i = 0;
1516
1517 for (; i < sizeof(mge_xml2nut) / sizeof(xml_info_t); ++i) {
1518 xml_info_t *info = mge_xml2nut + i;
1519
1520 if (NULL != info->nutname)
1521 if (0 == strcasecmp(name, info->nutname))
1522 return info->xmlname;
1523 }
1524
1525 return NULL;
1526 }
1527
vname_mge_xml2nut(const char * name)1528 const char *vname_mge_xml2nut(const char *name) {
1529 assert(NULL != name);
1530
1531 size_t i = 0;
1532
1533 for (; i < sizeof(mge_xml2nut) / sizeof(xml_info_t); ++i) {
1534 xml_info_t *info = mge_xml2nut + i;
1535
1536 if (NULL != info->xmlname)
1537 if (0 == strcasecmp(name, info->xmlname))
1538 return info->nutname;
1539 }
1540
1541 return NULL;
1542 }
1543
vvalue_mge_xml2nut(const char * name,const char * value,size_t len)1544 char *vvalue_mge_xml2nut(const char *name, const char *value, size_t len) {
1545 assert(NULL != name);
1546
1547 size_t i = 0;
1548
1549 for (; i < sizeof(mge_xml2nut) / sizeof(xml_info_t); ++i) {
1550 xml_info_t *info = mge_xml2nut + i;
1551
1552 if (NULL != info->nutname)
1553 if (0 == strcasecmp(name, info->nutname)) {
1554 /* Copy value */
1555 char *vcpy = (char *)malloc((len + 1) * sizeof(char));
1556
1557 if (NULL == vcpy)
1558 return vcpy;
1559
1560 memcpy(vcpy, value, len * sizeof(char));
1561 vcpy[len] = '\0';
1562
1563 /* Convert */
1564 if (NULL != info->convert) {
1565 char *vconv = (char *)info->convert(vcpy);
1566
1567 free(vcpy);
1568
1569 return vconv;
1570 }
1571 else
1572 return vcpy;
1573 }
1574 }
1575
1576 return NULL;
1577 }
1578
vname_register_rw(void)1579 void vname_register_rw(void) {
1580 size_t i = 0;
1581
1582 for (; i < sizeof(mge_xml2nut) / sizeof(xml_info_t); ++i) {
1583 xml_info_t *info = mge_xml2nut + i;
1584
1585 if (NULL != info->nutname && info->nutflags & ST_FLAG_RW) {
1586 dstate_setinfo(info->nutname, "%s", "");
1587 dstate_setflags(info->nutname, ST_FLAG_RW);
1588 }
1589 }
1590 }
1591