1 /*  mge-mib.c - data to monitor MGE UPS SYSTEMS SNMP devices with NUT
2  *
3  *  Copyright (C)
4  *  	2002-2012	Arnaud Quette <http://arnaud.quette.free.fr/contact.html>
5  *  	2002-2003	J.W. Hoogervorst <jeroen@hoogervorst.net>
6  *
7  *  Sponsored by MGE UPS SYSTEMS <http://www.mgeups.com>
8  *   MGE Office Protection Systems <http://www.mgeops.com>
9  *   Eaton <http://powerquality.eaton.com>
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25  *
26  */
27 
28 #include "mge-mib.h"
29 
30 #define MGE_MIB_VERSION	"0.52"
31 
32 /* TODO:
33  * - MGE PDU MIB and sysOID (".1.3.6.1.4.1.705.2") */
34 
35 /* SNMP OIDs set */
36 #define MGE_BASE_OID		".1.3.6.1.4.1.705.1"
37 #define MGE_SYSOID			MGE_BASE_OID
38 #define MGE_OID_MODEL_NAME	MGE_BASE_OID ".1.1.0"
39 
40 static info_lkp_t mge_lowbatt_info[] = {
41 	{ 1, "LB", NULL, NULL },
42 	{ 2, "", NULL, NULL },
43 	{ 0, NULL, NULL, NULL }
44 };
45 
46 static info_lkp_t mge_onbatt_info[] = {
47 	{ 1, "OB", NULL, NULL },
48 	{ 2, "OL", NULL, NULL },
49 	{ 0, NULL, NULL, NULL }
50 };
51 
52 static info_lkp_t mge_bypass_info[] = {
53 	{ 1, "BYPASS", NULL, NULL },
54 	{ 2, "", NULL, NULL },
55 	{ 0, NULL, NULL, NULL }
56 };
57 
58 static info_lkp_t mge_boost_info[] = {
59 	{ 1, "BOOST", NULL, NULL },
60 	{ 2, "", NULL, NULL },
61 	{ 0, NULL, NULL, NULL }
62 };
63 
64 static info_lkp_t mge_trim_info[] = {
65 	{ 1, "TRIM", NULL, NULL },
66 	{ 2, "", NULL, NULL },
67 	{ 0, NULL, NULL, NULL }
68 };
69 
70 static info_lkp_t mge_overload_info[] = {
71 	{ 1, "OVER", NULL, NULL },
72 	{ 2, "", NULL, NULL },
73 	{ 0, NULL, NULL, NULL }
74 };
75 
76 
77 static info_lkp_t mge_replacebatt_info[] = {
78 	{ 1, "RB", NULL, NULL },
79 	{ 2, "", NULL, NULL },
80 	{ 0, NULL, NULL, NULL }
81 };
82 
83 static info_lkp_t mge_output_util_off_info[] = {
84 	{ 1, "OFF", NULL, NULL },
85 	{ 2, "", NULL, NULL },
86 	{ 0, NULL, NULL, NULL }
87 };
88 
89 static info_lkp_t mge_transfer_reason_info[] = {
90 	{ 1, "", NULL, NULL },
91 	{ 2, "input voltage out of range", NULL, NULL },
92 	{ 3, "input frequency out of range", NULL, NULL },
93 	{ 4, "utility off", NULL, NULL },
94 	{ 0, NULL, NULL, NULL }
95 };
96 
97 static info_lkp_t mge_test_result_info[] = {
98 	{ 1, "done and passed", NULL, NULL },
99 	{ 2, "done and warning", NULL, NULL },
100 	{ 3, "done and error", NULL, NULL },
101 	{ 4, "aborted", NULL, NULL },
102 	{ 5, "in progress", NULL, NULL },
103 	{ 6, "no test initiated", NULL, NULL },
104 	{ 0, NULL, NULL, NULL }
105 };
106 
107 static info_lkp_t mge_beeper_status_info[] = {
108 	{ 1, "disabled", NULL, NULL },
109 	{ 2, "enabled", NULL, NULL },
110 	{ 3, "muted", NULL, NULL },
111 	{ 0, NULL, NULL, NULL }
112 };
113 
114 static info_lkp_t mge_yes_no_info[] = {
115 	{ 1, "yes", NULL, NULL },
116 	{ 2, "no", NULL, NULL },
117 	{ 0, NULL, NULL, NULL }
118 };
119 
120 /* FIXME: the below may introduce status redundancy, that needs to be
121  * addressed by the driver, as for usbhid-ups! */
122 static info_lkp_t mge_power_source_info[] = {
123 	{ 1, "" /* other */, NULL, NULL },
124 	{ 2, "OFF" /* none */, NULL, NULL },
125 #if 0
126 	{ 3, "OL" /* normal */, NULL, NULL },
127 #endif
128 	{ 4, "BYPASS" /* bypass */, NULL, NULL },
129 	{ 5, "OB" /* battery */, NULL, NULL },
130 	{ 6, "BOOST" /* booster */, NULL, NULL },
131 	{ 7, "TRIM" /* reducer */, NULL, NULL },
132 	{ 0, NULL, NULL, NULL }
133 };
134 
135 /* Parameters default values */
136 #define DEFAULT_ONDELAY		"30"	/* Delay between return of utility power */
137 										/* and powering up of load, in seconds */
138 										/* CAUTION: ondelay > offdelay */
139 #define DEFAULT_OFFDELAY	"20"	/* Delay before power off, in seconds */
140 
141 #define MGE_NOTHING_VALUE	"1"
142 #define MGE_START_VALUE		"2"
143 #define MGE_STOP_VALUE		"3"
144 
145 /* TODO: PowerShare (per plug .1, .2, .3) and deals with delays */
146 
147 /* Snmp2NUT lookup table */
148 static snmp_info_t mge_mib[] = {
149 
150 	/* UPS page */
151 	{ "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "Eaton", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL },
152 	{ "ups.model", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.1.1.0", "Generic SNMP UPS", SU_FLAG_STATIC | SU_FLAG_OK, NULL },
153 	{ "ups.serial", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.1.7.0", "", SU_FLAG_STATIC | SU_FLAG_OK, NULL },
154 	{ "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.1.4.0", "", SU_FLAG_STATIC | SU_FLAG_OK, NULL },
155 	{ "ups.firmware.aux", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.12.12.0", "", SU_FLAG_STATIC | SU_FLAG_OK, NULL },
156 	{ "ups.load", 0, 1, ".1.3.6.1.4.1.705.1.7.2.1.4.1", "", SU_OUTPUT_1, NULL },
157 	{ "ups.beeper.status", ST_FLAG_STRING, SU_INFOSIZE, "1.3.6.1.2.1.33.1.9.8.0", "", 0, mge_beeper_status_info },
158 	{ "ups.L1.load", 0, 1, ".1.3.6.1.4.1.705.1.7.2.1.4.1", "", SU_OUTPUT_3, NULL },
159 	{ "ups.L2.load", 0, 1, ".1.3.6.1.4.1.705.1.7.2.1.4.2", "", SU_OUTPUT_3, NULL },
160 	{ "ups.L3.load", 0, 1, ".1.3.6.1.4.1.705.1.7.2.1.4.3", "", SU_OUTPUT_3, NULL },
161 	{ "ups.test.result", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.33.1.7.3.0", "", 0, mge_test_result_info },
162 	{ "ups.delay.shutdown", ST_FLAG_STRING | ST_FLAG_RW, 6, "1.3.6.1.2.1.33.1.8.2.0", DEFAULT_OFFDELAY, SU_FLAG_ABSENT | SU_FLAG_OK, NULL },
163 	{ "ups.delay.start", ST_FLAG_STRING | ST_FLAG_RW, 6, "1.3.6.1.2.1.33.1.8.3.0", DEFAULT_ONDELAY, SU_FLAG_ABSENT | SU_FLAG_OK, NULL },
164 	{ "ups.timer.shutdown", 0, 1, "1.3.6.1.2.1.33.1.8.2.0", "", SU_FLAG_OK, NULL },
165 	{ "ups.timer.start", 0, 1, "1.3.6.1.2.1.33.1.8.3.0", "", SU_FLAG_OK, NULL },
166 	{ "ups.timer.reboot", 0, 1, "1.3.6.1.2.1.33.1.8.4.0", "", SU_FLAG_OK, NULL },
167 	{ "ups.start.auto", ST_FLAG_RW, 1, "1.3.6.1.2.1.33.1.8.5.0", "", SU_FLAG_OK, mge_yes_no_info },
168 	/* status data */
169 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.5.11.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_replacebatt_info },
170 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.5.14.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_lowbatt_info },
171 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.5.16.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_lowbatt_info },
172 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.3.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_onbatt_info },
173 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.4.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_bypass_info },
174 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.7.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_output_util_off_info },
175 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.8.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_boost_info },
176 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.10.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_overload_info },
177 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.12.0", "", SU_FLAG_OK | SU_STATUS_BATT, mge_trim_info },
178 	{ "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.33.1.4.1.0", "", SU_STATUS_PWR | SU_FLAG_OK, mge_power_source_info },
179 
180 	/* FIXME: Alarms
181 	 * - upsmgBatteryChargerFault (.1.3.6.1.4.1.705.1.5.15.0), yes (1), no (2)
182 	 * => Battery charger fail!
183 	 * - upsmgBatteryFaultBattery (.1.3.6.1.4.1.705.1.5.9.0), yes (1), no (2)
184 	 * => "Battery fault!" or?
185 	 * - upsmgOutputOverTemp (.1.3.6.1.4.1.705.1.7.11.0), yes (1), no (2)
186 	 * => "Temperature too high!"
187 	 * - upsmgOutputInverterOff (.1.3.6.1.4.1.705.1.7.9.0), yes (1), no (2)
188 	 * => "??"
189 	 * - upsmgInputBadStatus (.1.3.6.1.4.1.705.1.6.3.0), yes (1), no (2)
190 	 * => "bad volt or bad freq"
191 	 */
192 
193 	/* Input page */
194 	{ "input.phases", 0, 1.0, ".1.3.6.1.4.1.705.1.6.1.0", "", 0, NULL },
195 	{ "input.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.2.1", "", SU_INPUT_1, NULL },
196 	{ "input.L1-N.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.2.1", "", SU_INPUT_3, NULL },
197 	{ "input.L2-N.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.2.2", "", SU_INPUT_3, NULL },
198 	{ "input.L3-N.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.2.3", "", SU_INPUT_3, NULL },
199 	{ "input.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.3.1", "", SU_INPUT_1, NULL },
200 	{ "input.L1.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.3.1", "", SU_INPUT_3, NULL },
201 	{ "input.L2.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.3.2", "", SU_INPUT_3, NULL },
202 	{ "input.L3.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.3.3", "", SU_INPUT_3, NULL },
203 	{ "input.voltage.minimum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.4.1", "", SU_INPUT_1, NULL },
204 	{ "input.L1-N.voltage.minimum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.4.1", "", SU_INPUT_3, NULL },
205 	{ "input.L2-N.voltage.minimum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.4.2", "", SU_INPUT_3, NULL },
206 	{ "input.L3-N.voltage.minimum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.4.3", "", SU_INPUT_3, NULL },
207 	{ "input.voltage.maximum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.5.1", "", SU_INPUT_1, NULL },
208 	{ "input.L1-N.voltage.maximum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.5.1", "", SU_INPUT_3, NULL },
209 	{ "input.L2-N.voltage.maximum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.5.2", "", SU_INPUT_3, NULL },
210 	{ "input.L3-N.voltage.maximum", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.5.3", "", SU_INPUT_3, NULL },
211 	{ "input.current", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.6.1", "", SU_INPUT_1, NULL },
212 	{ "input.L1.current", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.6.1", "", SU_INPUT_3, NULL },
213 	{ "input.L2.current", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.6.2", "", SU_INPUT_3, NULL },
214 	{ "input.L3.current", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.6.3", "", SU_INPUT_3, NULL },
215 	{ "input.transfer.reason", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.6.4.0", "", SU_FLAG_OK, mge_transfer_reason_info },
216 
217 	/* Output page */
218 	{ "output.phases", 0, 1.0, ".1.3.6.1.4.1.705.1.7.1.0", "", 0, NULL },
219 	{ "output.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.2.1", "", SU_OUTPUT_1, NULL },
220 	{ "output.L1-N.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.2.1", "", SU_OUTPUT_3, NULL },
221 	{ "output.L2-N.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.2.2", "", SU_OUTPUT_3, NULL },
222 	{ "output.L3-N.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.2.3", "", SU_OUTPUT_3, NULL },
223 	{ "output.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.3.1", "", SU_OUTPUT_1, NULL },
224 	{ "output.L1.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.3.1", "", SU_OUTPUT_3, NULL },
225 	{ "output.L2.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.3.2", "", SU_OUTPUT_3, NULL },
226 	{ "output.L3.frequency", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.3.3", "", SU_OUTPUT_3, NULL },
227 	{ "output.current", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.5.1", "", SU_OUTPUT_1, NULL },
228 	{ "output.L1.current", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.5.1", "", SU_OUTPUT_3, NULL },
229 	{ "output.L2.current", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.5.2", "", SU_OUTPUT_3, NULL },
230 	{ "output.L3.current", 0, 0.1, ".1.3.6.1.4.1.705.1.7.2.1.5.3", "", SU_OUTPUT_3, NULL },
231 
232 	/* Battery page */
233 	{ "battery.charge", 0, 1, ".1.3.6.1.4.1.705.1.5.2.0", "", SU_FLAG_OK, NULL },
234 	{ "battery.runtime", 0, 1, ".1.3.6.1.4.1.705.1.5.1.0", "", SU_FLAG_OK, NULL },
235 	{ "battery.runtime.low", 0, 1, ".1.3.6.1.4.1.705.1.4.7.0", "", SU_FLAG_OK, NULL },
236 	{ "battery.charge.low", ST_FLAG_STRING | ST_FLAG_RW, 2, ".1.3.6.1.4.1.705.1.4.8.0", "", SU_TYPE_INT | SU_FLAG_OK, NULL },
237 	{ "battery.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.5.5.0", "", SU_FLAG_OK, NULL },
238 
239 	/* Ambient page: Environment Sensor (ref 66 846) */
240 	{ "ambient.temperature", 0, 0.1, ".1.3.6.1.4.1.705.1.8.1.0", "", SU_TYPE_INT | SU_FLAG_OK, NULL },
241 	{ "ambient.humidity", 0, 0.1, ".1.3.6.1.4.1.705.1.8.2.0", "", SU_TYPE_INT | SU_FLAG_OK, NULL },
242 
243 	/* Outlet page */
244 	{ "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL },
245 	{ "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "Main Outlet",  SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL },
246 
247 	/* instant commands. */
248 	{ "test.battery.start", 0, 1, ".1.3.6.1.4.1.705.1.10.4.0", MGE_START_VALUE, SU_TYPE_CMD | SU_FLAG_OK, NULL },
249 	/* Also use IETF OIDs
250 	 * { "test.battery.stop", 0, 0, "1.3.6.1.2.1.33.1.7.1.0", "1.3.6.1.2.1.33.1.7.7.2", SU_TYPE_CMD, NULL },
251 	 * { "test.battery.start", 0, 0, "1.3.6.1.2.1.33.1.7.1.0", "1.3.6.1.2.1.33.1.7.7.3", SU_TYPE_CMD, NULL },
252 	 * { "test.battery.start.quick", 0, 0, "1.3.6.1.2.1.33.1.7.1.0", "1.3.6.1.2.1.33.1.7.7.4", SU_TYPE_CMD, NULL },
253 	 * { "test.battery.start.deep", 0, 0, "1.3.6.1.2.1.33.1.7.1.0", "1.3.6.1.2.1.33.1.7.7.5", SU_TYPE_CMD, NULL },
254 	 */
255 
256 	/* { "load.off", 0, 1, ".1.3.6.1.4.1.705.1.9.1.1.6.1", MGE_START_VALUE, SU_TYPE_CMD | SU_FLAG_OK, NULL },
257 	 * { "load.on", 0, 1, ".1.3.6.1.4.1.705.1.9.1.1.3.1", MGE_START_VALUE, SU_TYPE_CMD | SU_FLAG_OK, NULL },
258 	 * { "shutdown.return", 0, 1, ".1.3.6.1.4.1.705.1.9.1.1.9.1", MGE_START_VALUE, SU_TYPE_CMD | SU_FLAG_OK, NULL },
259 	 */
260 	/* IETF MIB fallback */
261 	{ "beeper.disable", 0, 1, "1.3.6.1.2.1.33.1.9.8.0", "1", SU_TYPE_CMD, NULL },
262 	{ "beeper.enable", 0, 1, "1.3.6.1.2.1.33.1.9.8.0", "2", SU_TYPE_CMD, NULL },
263 	{ "beeper.mute", 0, 1, "1.3.6.1.2.1.33.1.9.8.0", "3", SU_TYPE_CMD, NULL },
264 	/*{ "load.off", 0, 1, "1.3.6.1.2.1.33.1.8.2.0", DEFAULT_OFFDELAY, SU_TYPE_CMD, NULL },
265 	{ "load.on", 0, 1, "1.3.6.1.2.1.33.1.8.3.0", DEFAULT_ONDELAY, SU_TYPE_CMD, NULL },*/
266 	{ "load.off.delay", 0, 1, "1.3.6.1.2.1.33.1.8.2.0", NULL, SU_TYPE_CMD, NULL },
267 	{ "load.on.delay", 0, 1, "1.3.6.1.2.1.33.1.8.3.0", NULL, SU_TYPE_CMD, NULL },
268 
269 	/* end of structure. */
270 	{ NULL, 0, 0, NULL, NULL, 0, NULL }
271 };
272 
273 mib2nut_info_t	mge = { "mge", MGE_MIB_VERSION, NULL, MGE_OID_MODEL_NAME, mge_mib, MGE_SYSOID, NULL };
274