diff --git a/clients/upsclient.c b/clients/upsclient.c index f749a4c7d0..b90587b001 100644 --- a/clients/upsclient.c +++ b/clients/upsclient.c @@ -25,7 +25,7 @@ #ifdef HAVE_PTHREAD /* this include is needed on AIX to have errno stored in thread local storage */ #include -#endif +#endif #include #include @@ -37,7 +37,6 @@ #include #include #include -#include #include "upsclient.h" #include "common.h" diff --git a/configure.ac b/configure.ac index f6d6ebf933..9b1d52b0be 100644 --- a/configure.ac +++ b/configure.ac @@ -1781,8 +1781,9 @@ if test "${want_regenerate_dmf_snmp}" != no ; then can_generate_dmf_snmp=no CURDIR="$(pwd)" && \ if test "${nut_with_dmf}" = "yes"; then - { OUTDIR="$(mktemp -d configure-test.dmfify.$$.XXXXXXX)" && \ + ( OUTDIR="$(mktemp -d configure-test.dmfify.$$.XXXXXXX)" && \ test -d "$OUTDIR" && OUTDIR="$(cd "${OUTDIR}" && pwd)" && \ + trap "cd '${CURDIR}' && rm -rf '${OUTDIR}'" 0 1 2 3 15 && \ if test -z "${srcdir}" -o "${srcdir}" = . ; then SRCDIR="${CURDIR}"; else SRCDIR="$(cd "${srcdir}" && pwd)"; fi && \ DMFDIR="$(cd "${SRCDIR}/scripts/DMF" && pwd)" && \ { cd "${DMFDIR}" && \ @@ -1802,8 +1803,8 @@ if test "${want_regenerate_dmf_snmp}" != no ; then || { can_generate_dmf_snmp="no: ERROR: Failed nut_cpp parse of a test C to DMF for '$F'"; false ; break; } \ done ; } ; \ } - RES=$?; rm -rf "$OUTDIR"; test "${RES}" = 0 - } >&5 2>&5 \ + RES=$?; cd "${CURDIR}"; rm -rf "${OUTDIR}"; test "${RES}" = 0 + ) >&5 2>&5 \ && can_generate_dmf_snmp=yes fi if test -n "${CURDIR}" ; then cd "${CURDIR}" ; fi diff --git a/docs/nut-names.txt b/docs/nut-names.txt index 6535579e22..e7f4d86a1b 100644 --- a/docs/nut-names.txt +++ b/docs/nut-names.txt @@ -194,7 +194,9 @@ input: Incoming line/power information | input.power | Current sum value of all (ePDU) phases apparent power (VA) | 500 | input.source | The current input power source | 1 -| input.source.preferred | The preferred power source | 1 +| input.source.preferred | The preferred power source | 1 +| input.phase.shift | Voltage dephasing between input + sources (degrees) | 181 |================================================================================= output: Outgoing power/inverter information @@ -486,7 +488,8 @@ of the user manual. | outlet.count | Total number of outlets | 12 | outlet.n.id | Outlet system identifier (opaque string) | 1 -| outlet.n.desc | Outlet name / description +| outlet.n.name | Outlet name (opaque string) | A1 +| outlet.n.desc | Outlet description (opaque string) | Main outlet | outlet.n.groupid | Identifier of the group to which the outlet belongs to | 1 diff --git a/docs/nut.dict b/docs/nut.dict index 2b594d077c..72f984c195 100644 --- a/docs/nut.dict +++ b/docs/nut.dict @@ -1,4 +1,4 @@ -personal_ws-1.1 en 2458 utf-8 +personal_ws-1.1 en 2459 utf-8 AAS ACFAIL ACFREQ @@ -1413,6 +1413,7 @@ decrement decrypt defun dep +dephasing deps desc deschis diff --git a/docs/snmp-subdrivers.txt b/docs/snmp-subdrivers.txt index 5b4fd9de4c..0fe7332bab 100644 --- a/docs/snmp-subdrivers.txt +++ b/docs/snmp-subdrivers.txt @@ -205,14 +205,14 @@ you must examine the NUT variables of the form "unmapped.*" in the hid_info_t data structure, and map them to actual NUT variables and instant commands. There are currently no step-by-step instructions for how to do this. Please look at the files to see how the currently implemented -subdrivers are written.: +subdrivers are written: - apc-mib.c/h - baytech-mib.c/h - bestpower-mib.c/h - compaq-mib.c/h - cyberpower-mib.c/h -- eaton-mib.c/h +- eaton-*-mib.c/h - ietf-mib.c/h - mge-mib.c/h - netvision-mib.c/h diff --git a/drivers/Makefile.am b/drivers/Makefile.am index be0f08a186..617c6754c2 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -16,9 +16,6 @@ AM_CFLAGS = -I$(top_srcdir)/include if WITH_USB AM_CFLAGS += $(LIBUSB_CFLAGS) endif -if WITH_SNMP - AM_CFLAGS += $(LIBNETSNMP_CFLAGS) -endif if WITH_NEON AM_CFLAGS += $(LIBNEON_CFLAGS) endif @@ -207,13 +204,17 @@ mge_shut_CFLAGS = $(AM_CFLAGS) -DSHUT_MODE mge_shut_LDADD = $(LDADD) # SNMP -snmp_ups_SOURCES = snmp-ups.c apc-mib.c baytech-mib.c compaq-mib.c eaton-mib.c \ +snmp_ups_SOURCES = snmp-ups.c apc-mib.c baytech-mib.c compaq-mib.c \ + eaton-pdu-genesis2-mib.c eaton-pdu-marlin-mib.c eaton-pdu-marlin-helpers.c \ + eaton-pdu-pulizzi-mib.c eaton-pdu-revelation-mib.c \ ietf-mib.c mge-mib.c netvision-mib.c powerware-mib.c raritan-pdu-mib.c \ bestpower-mib.c cyberpower-mib.c delta_ups-mib.c xppc-mib.c huawei-mib.c \ eaton-ats16-mib.c apc-ats-mib.c raritan-px2-mib.c eaton-ats30-mib.c \ apc-pdu-mib.c +snmp_ups_CFLAGS = $(AM_CFLAGS) +snmp_ups_CFLAGS += $(LIBNETSNMP_CFLAGS) snmp_ups_LDADD = $(LDADD_DRIVERS) $(LIBNETSNMP_LIBS) -snmp_ups_CFLAGS = $(AM_CFLAGS) -DWITH_DMFMIB=0 -DWITH_DMF_LUA=0 -DWITH_DMF_FUNCTIONS=0 +snmp_ups_CFLAGS += -DWITH_DMFMIB=0 -DWITH_DMF_LUA=0 -DWITH_DMF_FUNCTIONS=0 # DMF SNMP - ok to define this in the open, it is only built if enabled above snmp_ups_dmf_SOURCES = snmp-ups.c @@ -222,6 +223,7 @@ snmp_ups_dmf_LDADD = $(LDADD_DRIVERS) $(LIBNETSNMP_LIBS) \ $(top_builddir)/common/libcommon.la snmp_ups_dmf_CFLAGS = $(AM_CFLAGS) \ -I$(top_srcdir)/tools/nut-scanner -DWITH_DMFMIB=1 +snmp_ups_dmf_CFLAGS += $(LIBNETSNMP_CFLAGS) if WITH_DMF_LUA LUA_INCLUDE ?= -I/usr/include/lua5.1 snmp_ups_dmf_CFLAGS += -DWITH_DMF_LUA=1 -DWITH_DMF_FUNCTIONS=1 $(LUA_INCLUDE) @@ -299,7 +301,7 @@ nutdrv_qx_SOURCES += $(NUTDRV_QX_SUBDRIVERS) dist_noinst_HEADERS = apc-mib.h apc-iem-mib.h apc-hid.h baytech-mib.h bcmxcp.h \ bcmxcp_io.h belkin.h belkin-hid.h bestpower-mib.h blazer.h cps-hid.h dstate.h \ - dummy-ups.h eaton-mib.h explore-hid.h gamatronic.h genericups.h \ + dummy-ups.h explore-hid.h gamatronic.h genericups.h \ hidparser.h hidtypes.h ietf-mib.h libhid.h libshut.h libusb.h liebert-hid.h \ main.h mge-hid.h mge-mib.h mge-utalk.h \ mge-xml.h microdowell.h netvision-mib.h netxml-ups.h nut-ipmi.h oneac.h \ @@ -311,7 +313,8 @@ dist_noinst_HEADERS = apc-mib.h apc-iem-mib.h apc-hid.h baytech-mib.h bcmxcp.h \ nutdrv_qx_megatec.h nutdrv_qx_megatec-old.h nutdrv_qx_mustek.h nutdrv_qx_q1.h \ nutdrv_qx_voltronic.h nutdrv_qx_voltronic-qs.h nutdrv_qx_voltronic-qs-hex.h nutdrv_qx_zinto.h \ xppc-mib.h huawei-mib.h eaton-ats16-mib.h apc-ats-mib.h raritan-px2-mib.h eaton-ats30-mib.h \ - apc-pdu-mib.h + apc-pdu-mib.h eaton-pdu-genesis2-mib.h eaton-pdu-marlin-mib.h eaton-pdu-marlin-helpers.h \ + eaton-pdu-pulizzi-mib.h eaton-pdu-revelation-mib.h # Define a dummy library so that Automake builds rules for the # corresponding object files. This library is not actually built, diff --git a/drivers/apcupsd-ups.c b/drivers/apcupsd-ups.c index 1cfc39b32b..9b5350b1d1 100644 --- a/drivers/apcupsd-ups.c +++ b/drivers/apcupsd-ups.c @@ -26,7 +26,7 @@ #include "apcupsd-ups.h" #define DRIVER_NAME "apcupsd network client UPS driver" -#define DRIVER_VERSION "0.04" +#define DRIVER_VERSION "0.5" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -54,9 +54,8 @@ static void process(char *item,char *data) { case DU_FLAG_STATUS: status_init(); - if(!strcmp(data,"COMMLOST")||!strcmp(data,"SHUTTING DOWN")|| - !strcmp(data,"NETWORK ERROR")||!strcmp(data,"ERROR")) - status_set("OFF"); + if(!strcmp(data,"COMMLOST")||!strcmp(data,"NETWORK ERROR")|| + !strcmp(data,"ERROR"))status_set("OFF"); else if(!strcmp(data,"SELFTEST"))status_set("OB"); else for(;(data=strtok(data," "));data=NULL) { @@ -66,7 +65,8 @@ static void process(char *item,char *data) else if(!strcmp(data,"ONLINE"))status_set("OL"); else if(!strcmp(data,"ONBATT"))status_set("OB"); else if(!strcmp(data,"OVERLOAD"))status_set("OVER"); - else if(!strcmp(data,"LOWBATT"))status_set("LB"); + else if(!strcmp(data,"SHUTTING DOWN")|| + !strcmp(data,"LOWBATT"))status_set("LB"); else if(!strcmp(data,"REPLACEBATT"))status_set("RB"); else if(!strcmp(data,"NOBATT"))status_set("BYPASS"); } diff --git a/drivers/cps-hid.c b/drivers/cps-hid.c index 78c952f165..e28afe2f8c 100644 --- a/drivers/cps-hid.c +++ b/drivers/cps-hid.c @@ -28,7 +28,7 @@ #include "cps-hid.h" #include "usb-common.h" -#define CPS_HID_VERSION "CyberPower HID 0.4" +#define CPS_HID_VERSION "CyberPower HID 0.5" /* Cyber Power Systems */ #define CPS_VENDORID 0x0764 @@ -193,12 +193,14 @@ static hid_info_t cps_hid2nut[] = { { "BOOL", 0, 0, "UPS.Output.Overload", NULL, NULL, 0, overload_info }, /* Input page */ + { "input.frequency", 0, 0, "UPS.Input.Frequency", NULL, "%.1f", 0, NULL }, { "input.voltage.nominal", 0, 0, "UPS.Input.ConfigVoltage", NULL, "%.0f", 0, NULL }, { "input.voltage", 0, 0, "UPS.Input.Voltage", NULL, "%.1f", 0, NULL }, { "input.transfer.low", ST_FLAG_RW | ST_FLAG_STRING, 10, "UPS.Input.LowVoltageTransfer", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, { "input.transfer.high", ST_FLAG_RW | ST_FLAG_STRING, 10, "UPS.Input.HighVoltageTransfer", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, /* Output page */ + { "output.frequency", 0, 0, "UPS.Output.Frequency", NULL, "%.1f", 0, NULL }, { "output.voltage", 0, 0, "UPS.Output.Voltage", NULL, "%.1f", 0, NULL }, { "output.voltage.nominal", 0, 0, "UPS.Output.ConfigVoltage", NULL, "%.0f", 0, NULL }, diff --git a/drivers/dstate.h b/drivers/dstate.h index f4e244afd8..dd1b920122 100644 --- a/drivers/dstate.h +++ b/drivers/dstate.h @@ -22,6 +22,7 @@ #ifndef DSTATE_H_SEEN #define DSTATE_H_SEEN 1 +#include "timehead.h" #include "state.h" #include "attribute.h" diff --git a/drivers/eaton-ats16-mib.c b/drivers/eaton-ats16-mib.c index 141dc24a03..4441c3241c 100644 --- a/drivers/eaton-ats16-mib.c +++ b/drivers/eaton-ats16-mib.c @@ -24,7 +24,7 @@ #include "eaton-ats16-mib.h" -#define EATON_ATS16_MIB_VERSION "0.13" +#define EATON_ATS16_MIB_VERSION "0.14" #define EATON_ATS16_SYSOID ".1.3.6.1.4.1.534.10" #define EATON_ATS16_MODEL ".1.3.6.1.4.1.534.10.2.1.2.0" @@ -128,6 +128,8 @@ static snmp_info_t eaton_ats16_mib[] = { { "input.source", ST_FLAG_STRING, 1, ".1.3.6.1.4.1.534.10.2.2.4.0", NULL, SU_FLAG_OK, eaton_ats16_source_info, NULL }, /* ats2ConfigPreferred.0 = INTEGER: source1(1) */ { "input.source.preferred", ST_FLAG_RW, 1, ".1.3.6.1.4.1.534.10.2.4.5.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputDephasing = INTEGER: 181 */ + { "input.phase.shift", 0, 1, ".1.3.6.1.4.1.534.10.2.2.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, /* Output collection */ /* ats2OutputVoltage.0 = INTEGER: 2304 0.1 V */ diff --git a/drivers/eaton-mib.h b/drivers/eaton-mib.h deleted file mode 100644 index d5223e6473..0000000000 --- a/drivers/eaton-mib.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef EATON_MIB_H -#define EATON_MIB_H - -#include "main.h" -#include "snmp-ups.h" - -extern mib2nut_info_t aphel_genesisII; -extern mib2nut_info_t aphel_revelation; -extern mib2nut_info_t eaton_marlin; -extern mib2nut_info_t pulizzi_switched1; -extern mib2nut_info_t pulizzi_switched2; - -#endif /* EATON_MIB_H */ diff --git a/drivers/eaton-pdu-genesis2-mib.c b/drivers/eaton-pdu-genesis2-mib.c new file mode 100644 index 0000000000..ae6037e609 --- /dev/null +++ b/drivers/eaton-pdu-genesis2-mib.c @@ -0,0 +1,89 @@ +/* eaton-pdu-genesis2-mib.c - data to monitor Eaton ePDUs branded as: + * G1 Aphel based ePDUs (Basic) - GenesisII + * + * Copyright (C) 2008 - 2017 + * Arnaud Quette + * Arnaud Quette + * Copyright (C) 2015 - 2017 + * Jim Klimov + * + * Supported by Eaton + * and previously MGE Office Protection Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "eaton-pdu-genesis2-mib.h" + +#define EATON_APHEL_GENESIS2_MIB_VERSION "0.49" + +/* APHEL-GENESIS-II-MIB (monitored ePDU) + * ************************************* + * Note: There is also a basic XML interface, but not worth + * implementing in netxml-ups! + */ + +#define APHEL1_OID_MIB ".1.3.6.1.4.1.17373" +#define APHEL1_SYSOID APHEL1_OID_MIB +#define APHEL1_OID_MODEL_NAME ".1.3.6.1.4.1.17373.3.1.1.0" +#define APHEL1_OID_FIRMREV ".1.3.6.1.4.1.17373.3.1.2.0" +#define APHEL1_OID_DEVICE_NAME ".1.3.6.1.4.1.17373.3.1.3.0" +#define APHEL1_OID_UNIT_MACADDR ".1.3.6.1.4.1.17373.3.1.4.0" +/* needs concat ..0 */ +#define APHEL1_OID_OUTLET_CURRENT ".1.3.6.1.4.1.17373.3.2" + +/* Snmp2NUT lookup table for GenesisII MIB */ +static snmp_info_t eaton_aphel_genesisII_mib[] = { + /* Device page */ + { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.model", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_MODEL_NAME, + "Eaton Powerware ePDU Monitored", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_UNIT_MACADDR, "unknown", + 0, NULL, NULL }, + + /* UPS page */ + { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_MODEL_NAME, + "Generic SNMP PDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_DEVICE_NAME, + "unknown", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_FIRMREV, "", + SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + + /* Outlet page */ + /* we can't use template since there is no counterpart to outlet.count */ + { "outlet.1.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".1.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.2.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".2.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.3.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".3.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.4.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".4.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.5.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".5.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.6.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".6.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.7.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".7.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "outlet.8.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".8.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } +}; + + +mib2nut_info_t aphel_genesisII = { "aphel_genesisII", EATON_APHEL_GENESIS2_MIB_VERSION, NULL, APHEL1_OID_MODEL_NAME, eaton_aphel_genesisII_mib, APHEL1_SYSOID }; diff --git a/drivers/eaton-pdu-genesis2-mib.h b/drivers/eaton-pdu-genesis2-mib.h new file mode 100644 index 0000000000..df9dc0c0a4 --- /dev/null +++ b/drivers/eaton-pdu-genesis2-mib.h @@ -0,0 +1,32 @@ +/* eaton-pdu-genesis2-mib.h - subdriver to monitor Eaton ePDU SNMP devices with NUT + * + * Copyright (C) + * 2010 Arjen de Korte + * 2011 - 2012 Arnaud Quette + * 2017 Arnaud Quette + * 2017 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EATON_EPDU_GENESIS_MIB_H +#define EATON_EPDU_GENESIS_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t aphel_genesisII; + +#endif /* EATON_EPDU_GENESIS_MIB_H */ diff --git a/drivers/eaton-pdu-marlin-helpers.c b/drivers/eaton-pdu-marlin-helpers.c new file mode 100644 index 0000000000..f11f0a02d3 --- /dev/null +++ b/drivers/eaton-pdu-marlin-helpers.c @@ -0,0 +1,67 @@ +/* eaton-pdu-marlin-helpers.c - helper routines for eaton-pdu-marlin-mib.c + * to monitor Eaton ePDUs branded as: + * G2 Marlin SW / MI / MO / MA + * G3 Shark SW / MI / MO / MA + * + * Copyright (C) 2017 + * Arnaud Quette + * Copyright (C) 2017 + * Jim Klimov + * + * Supported by Eaton + * and previously MGE Office Protection Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include + +#include "eaton-pdu-marlin-helpers.h" +#include "dstate.h" + +static char marlin_scratch_buf[20]; + +/* Compute the phase to which an outlet group is connected + * WRT the number of phase(s) and the outlet group number. + * Note that the group type (marlin_outlet_group_type_info) + * is not considered since this applies to any kind of group. + * This trick limits input phase to electrical groups only + * (not outlet-section nor user-defined!), and for now, there + * is a maximum of 6 gangs (electrical groups). + */ +const char *marlin_outlet_group_phase_fun(int outlet_group_nb) +{ + const char* str_phases_nb = dstate_getinfo("input.phases"); + int phases_nb = 1; + if (str_phases_nb) { + phases_nb = atoi(str_phases_nb); + if (phases_nb == 1) { + return "L1"; + } + else { /* 3ph assumed, 2ph PDU don't exist - at least not in Eaton Marlin lineup! */ + if (outlet_group_nb > 3) + snprintf(marlin_scratch_buf, 3, "L%i", (outlet_group_nb - 3)); /* FIXME: For more than 6 ports, maybe "nb % 3"? */ + else + snprintf(marlin_scratch_buf, 3, "L%i", outlet_group_nb); + + return marlin_scratch_buf; + } + } + return NULL; +} diff --git a/drivers/eaton-pdu-marlin-helpers.h b/drivers/eaton-pdu-marlin-helpers.h new file mode 100644 index 0000000000..d19f7d65c6 --- /dev/null +++ b/drivers/eaton-pdu-marlin-helpers.h @@ -0,0 +1,28 @@ +/* eaton-pdu-marlin-helpers.h - helper for subdriver to monitor certain + * Eaton ePDU SNMP devices with NUT + * + * Copyright (C) + * 2017 Arnaud Quette + * 2017 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EATON_EPDU_MARLIN_HELPERS_H +#define EATON_EPDU_MARLIN_HELPERS_H + +const char *marlin_outlet_group_phase_fun(int outlet_group_nb); + +#endif /* EATON_EPDU_MARLIN_HELPERS_H */ diff --git a/drivers/eaton-mib.c b/drivers/eaton-pdu-marlin-mib.c similarity index 69% rename from drivers/eaton-mib.c rename to drivers/eaton-pdu-marlin-mib.c index 6154da2a83..b188a898e5 100644 --- a/drivers/eaton-mib.c +++ b/drivers/eaton-pdu-marlin-mib.c @@ -1,12 +1,12 @@ -/* eaton-mib.c - data to monitor Eaton ePDUs: - * G1 Aphel based ePDUs (Basic and Complex) - * G1 Pulizzi Monitored and Switched ePDUs +/* eaton-pdu-marlin-mib.c - data to monitor Eaton ePDUs branded as: * G2 Marlin SW / MI / MO / MA * G3 Shark SW / MI / MO / MA * - * Copyright (C) 2008 - 2015 + * Copyright (C) 2008 - 2017 * Arnaud Quette * Arnaud Quette + * Copyright (C) 2015 - 2017 + * Jim Klimov * * Supported by Eaton * and previously MGE Office Protection Systems @@ -28,213 +28,15 @@ * */ -#include "eaton-mib.h" - -/* FIXME: split into multiple files (1 per snmp_info_t) and have XX_VERSION - * per file */ - -#define EATON_APHEL_MIB_VERSION "0.50" - -/* APHEL-GENESIS-II-MIB (monitored ePDU) - * ************************************* - * Note: There is also a basic XML interface, but not worth - * implementing in netxml-ups! - */ - -#define APHEL1_OID_MIB ".1.3.6.1.4.1.17373" -#define APHEL1_SYSOID APHEL1_OID_MIB -#define APHEL1_OID_MODEL_NAME ".1.3.6.1.4.1.17373.3.1.1.0" -#define APHEL1_OID_FIRMREV ".1.3.6.1.4.1.17373.3.1.2.0" -#define APHEL1_OID_DEVICE_NAME ".1.3.6.1.4.1.17373.3.1.3.0" -#define APHEL1_OID_UNIT_MACADDR ".1.3.6.1.4.1.17373.3.1.4.0" -/* needs concat ..0 */ -#define APHEL1_OID_OUTLET_CURRENT ".1.3.6.1.4.1.17373.3.2" - -/* Snmp2NUT lookup table for GenesisII MIB */ -static snmp_info_t eaton_aphel_genesisII_mib[] = { - /* Device page */ - { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "device.model", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_MODEL_NAME, - "Eaton Powerware ePDU Monitored", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_UNIT_MACADDR, "unknown", - 0, NULL, NULL }, - - /* UPS page */ - { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_MODEL_NAME, - "Generic SNMP PDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_DEVICE_NAME, - "unknown", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_FIRMREV, "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - - /* Outlet page */ - /* we can't use template since there is no counterpart to outlet.count */ - { "outlet.1.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".1.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.2.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".2.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.3.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".3.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.4.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".4.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.5.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".5.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.6.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".6.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.7.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".7.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - { "outlet.8.current", 0, 0.1, APHEL1_OID_OUTLET_CURRENT ".8.0", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, - - /* end of structure. */ - { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } -}; - - -/* APHEL PDU-MIB - Revelation MIB (Managed ePDU) - * ********************************************* */ - -#define AR_BASE_OID ".1.3.6.1.4.1.534.6.6.6" -#define APHEL2_SYSOID AR_BASE_OID -#define APHEL2_OID_MODEL_NAME AR_OID_MODEL_NAME - -#define AR_OID_MODEL_NAME AR_BASE_OID ".1.1.12.0" -#define AR_OID_DEVICE_NAME AR_BASE_OID ".1.1.13.0" -#define AR_OID_FIRMREV AR_BASE_OID ".1.1.1.0" -#define AR_OID_SERIAL AR_BASE_OID ".1.1.2.0" -#define AR_OID_UNIT_MACADDR AR_BASE_OID ".1.1.6.0" - -#define AR_OID_UNIT_CURRENT AR_BASE_OID ".1.3.1.1" -#define AR_OID_UNIT_VOLTAGE AR_BASE_OID ".1.3.1.2" -#define AR_OID_UNIT_ACTIVEPOWER AR_BASE_OID ".1.3.1.3" -#define AR_OID_UNIT_APPARENTPOWER AR_BASE_OID ".1.3.1.4" -#define AR_OID_UNIT_CPUTEMPERATURE AR_BASE_OID ".1.3.1.5.0" - -#define AR_OID_OUTLET_INDEX AR_BASE_OID ".1.2.2.1.1" -#define AR_OID_OUTLET_NAME AR_BASE_OID ".1.2.2.1.2" -#define AR_OID_OUTLET_STATUS AR_BASE_OID ".1.2.2.1.3" - -static info_lkp_t eaton_outlet_status_info[] = { - { -1, "error" }, - { 0, "off" }, - { 1, "on" }, - { 2, "cycling" }, /* transitional status */ - { 0, NULL } -}; - -/* Ugly hack: having the matching OID present means that the outlet is - * switchable. So, it should not require this value lookup */ -static info_lkp_t revelation_outlet_switchability_info[] = { - { -1, "yes" }, - { 0, "yes" }, - { 1, "yes" }, - { 2, "yes" }, - { 0, NULL } -}; - -#define DO_OFF 0 -#define DO_ON 1 -#define DO_CYCLE 2 - -#define AR_OID_OUTLET_COUNT AR_BASE_OID ".1.2.1.0" -#define AR_OID_OUTLET_CURRENT AR_BASE_OID ".1.2.2.1.4" -#define AR_OID_OUTLET_MAXCURRENT AR_BASE_OID ".1.2.2.1.5" -#define AR_OID_OUTLET_VOLTAGE AR_BASE_OID ".1.2.2.1.6" -#define AR_OID_OUTLET_ACTIVEPOWER AR_BASE_OID ".1.2.2.1.7" -#define AR_OID_OUTLET_APPARENTPOWER AR_BASE_OID ".1.2.2.1.8" -#define AR_OID_OUTLET_POWERFACTOR AR_BASE_OID ".1.2.2.1.9" - -/* Snmp2NUT lookup table for Eaton Revelation MIB */ -static snmp_info_t eaton_aphel_revelation_mib[] = { - /* Device collection */ - { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "device.model", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_MODEL_NAME, - "Eaton Powerware ePDU Managed", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "device.serial", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_SERIAL, "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_UNIT_MACADDR, "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - /* hardwareRev.0 = Integer: 26 */ - /* FIXME: not compliant! to be RFC'ed */ - { "device.revision", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.6.1.1.7.0", - "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - - /* UPS collection */ - { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_MODEL_NAME, - "Generic SNMP PDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_DEVICE_NAME, - "unknown", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.serial", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_SERIAL, "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_FIRMREV, "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL }, - { "ups.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "ups.temperature", 0, 1, AR_OID_UNIT_CPUTEMPERATURE, NULL, 0, NULL, NULL }, - - /* Outlet collection */ - { "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, - { "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "All outlets", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, - { "outlet.count", 0, 1, AR_OID_OUTLET_COUNT, "0", 0, NULL }, - { "outlet.current", 0, 0.001, AR_OID_UNIT_CURRENT ".0", NULL, 0, NULL, NULL }, - { "outlet.voltage", 0, 0.001, AR_OID_UNIT_VOLTAGE ".0", NULL, 0, NULL, NULL }, - { "outlet.realpower", 0, 1.0, AR_OID_UNIT_ACTIVEPOWER ".0", NULL, 0, NULL, NULL }, - { "outlet.power", 0, 1.0, AR_OID_UNIT_APPARENTPOWER ".0", NULL, 0, NULL, NULL }, - - /* outlet template definition - * Caution: the index of the data start at 0, while the name is +1 - * ie outlet.1 => .0 */ - { "outlet.%i.switchable", 0, 1, AR_OID_OUTLET_STATUS ".%i", "yes", SU_FLAG_STATIC | SU_OUTLET, &revelation_outlet_switchability_info[0], NULL }, - { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, - { "outlet.%i.desc", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, AR_OID_OUTLET_NAME ".%i", NULL, SU_OUTLET, NULL, NULL }, - { "outlet.%i.status", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_OUTLET_STATUS ".%i", NULL, SU_FLAG_OK | SU_OUTLET, &eaton_outlet_status_info[0], NULL }, - { "outlet.%i.current", 0, 0.001, AR_OID_OUTLET_CURRENT ".%i", NULL, SU_OUTLET, NULL, NULL }, - { "outlet.%i.current.maximum", 0, 0.001, AR_OID_OUTLET_MAXCURRENT ".%i", NULL, SU_OUTLET, NULL, NULL }, - { "outlet.%i.realpower", 0, 1.0, AR_OID_OUTLET_ACTIVEPOWER ".%i", NULL, SU_OUTLET, NULL, NULL }, - { "outlet.%i.voltage", 0, 1.0, AR_OID_OUTLET_VOLTAGE ".%i", NULL, SU_OUTLET, NULL, NULL }, - { "outlet.%i.powerfactor", 0, 0.01, AR_OID_OUTLET_POWERFACTOR ".%i", NULL, SU_OUTLET, NULL, NULL }, - { "outlet.%i.power", 0, 1.0, AR_OID_OUTLET_APPARENTPOWER ".%i", NULL, SU_OUTLET, NULL, NULL }, - - /* FIXME: - * - delay for startup/shutdown sequence - * - support for multiple Ambient sensors ( max. 8), starting at index '0' - * ambient.%i.temperature => .1.3.6.1.4.1.534.6.6.6.2.2.1.3.%i - * ambient.%i.humidity => .1.3.6.1.4.1.534.6.6.6.2.4.1.3.%i - */ - - /* Ambient collection */ - /* We use critical levels, for both temperature and humidity, - * since warning levels are also available! */ - { "ambient.temperature", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.2.1.3.0", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.temperature.low", 0, 1.0, "1.3.6.1.4.1.534.6.6.6.2.2.1.6.0", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.temperature.high", 0, 1.0, "1.3.6.1.4.1.534.6.6.6.2.2.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.humidity", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.4.1.3.0", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.humidity.low", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.4.1.6.0", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.humidity.high", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.4.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, - - /* instant commands. */ - /* Note that load.cycle might be replaced by / mapped on shutdown.reboot */ - /* no counterpart found! - { "outlet.load.off", 0, DO_OFF, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, - { "outlet.load.on", 0, DO_ON, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, - { "outlet.load.cycle", 0, DO_CYCLE, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, */ - { "outlet.%i.load.off", 0, DO_OFF, AR_OID_OUTLET_STATUS ".%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, - { "outlet.%i.load.on", 0, DO_ON, AR_OID_OUTLET_STATUS ".%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, - { "outlet.%i.load.cycle", 0, DO_CYCLE, AR_OID_OUTLET_STATUS ".%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, - - /* end of structure. */ - { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } -}; +#include "eaton-pdu-marlin-mib.h" +#if WITH_SNMP_LKP_FUN +#include "eaton-pdu-marlin-helpers.h" +#endif /* Eaton PDU-MIB - Marlin MIB * ************************** */ -#define EATON_MARLIN_MIB_VERSION "0.42" +#define EATON_MARLIN_MIB_VERSION "0.44" #define EATON_MARLIN_SYSOID ".1.3.6.1.4.1.534.6.6.7" #define EATON_MARLIN_OID_MODEL_NAME ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0" @@ -256,14 +58,14 @@ static info_lkp_t marlin_outletgroups_status_info[] = { /* Ugly hack: having the matching OID present means that the outlet is * switchable. So, it should not require this value lookup */ -static info_lkp_t eaton_outlet_switchability_info[] = { +static info_lkp_t marlin_outlet_switchability_info[] = { { -1, "yes" }, { 0, "yes" }, { 0, NULL } }; /* The physical type of outlet */ -static info_lkp_t eaton_outlet_type_info[] = { +static info_lkp_t marlin_outlet_type_info[] = { { 0, "unknown" }, { 1, "iecC13" }, { 2, "iecC19" }, @@ -372,6 +174,22 @@ static info_lkp_t marlin_input_type_info[] = { { 4, "3" }, /* threePhaseWye */ { 0, NULL } }; + +#if WITH_SNMP_LKP_FUN +/* Note: marlin_outlet_group_phase_fun() is defined in eaton-pdu-marlin-helpers.c + * Future work for DMF might provide a same-named routine via LUA-C gateway. + */ +static info_lkp_t marlin_outlet_group_phase_info[] = { + { 1, "dummy", marlin_outlet_group_phase_fun }, + { 0, NULL } +}; + +#else // if not WITH_SNMP_LKP_FUN: + +/* FIXME: For now, DMF codebase falls back to old implementation with static + * lookup/mapping tables for this, which can easily go into the DMF XML file. + */ + /* Ugly trick which limits input phase to electrical groups */ static info_lkp_t marlin_outlet_group_phase1_info[] = { /* { 0, NULL }, unknown */ @@ -398,9 +216,11 @@ static info_lkp_t marlin_outlet_group_phase3_info[] = { { 3, "L3" }, /* breaker3pole */ /* { 4, NULL }, outlet-section */ /* { 5, NULL }, user-defined */ - { 0, NULL } }; +#endif // WITH_SNMP_LKP_FUN + + /* Snmp2NUT lookup table for Eaton Marlin MIB */ static snmp_info_t eaton_marlin_mib[] = { @@ -441,7 +261,7 @@ static snmp_info_t eaton_marlin_mib[] = { SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, /* FIXME: needs a date reformating callback * 2011-8-29,16:27:25.0,+1:0 - * Hex-STRING: 07 DB 08 1D 10 0C 36 00 2B 01 00 00 + * Hex-STRING: 07 DB 08 1D 10 0C 36 00 2B 01 00 00 * { "ups.date", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.8.0", "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, * { "ups.time", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.8.0", @@ -457,10 +277,6 @@ static snmp_info_t eaton_marlin_mib[] = { /* inputCount.0; Value (Integer): 1 { "input.phases", 0, 1, ".1.3.6.1.4.1.534.6.6.7.1.2.1.20.0", NULL, SU_FLAG_STATIC | SU_FLAG_SETINT, NULL, &input_phases }, */ /* Note: for daisychain mode, we must handle phase(s) per device, not as a whole */ - /* OLDER FIXME: to be implemented - * inputType.0.1 iso.3.6.1.4.1.534.6.6.7.3.1.1.2.0.1 - * singlePhase (1), ... split phase, three phase delta, or three phase wye - */ /* inputType.%i.1 = INTEGER: singlePhase (1) */ { "input.phases", 0, 1, ".1.3.6.1.4.1.534.6.6.7.3.1.1.2.%i.1", NULL, SU_FLAG_STATIC, &marlin_input_type_info[0], NULL }, @@ -608,12 +424,15 @@ static snmp_info_t eaton_marlin_mib[] = { /* outlet template definition * Indexes start from 1, ie outlet.1 => .1 */ /* Note: the first definition is used to determine the base index (ie 0 or 1) */ + /* outletName: Outlet friendly name, which can be modified by the user */ { "outlet.%i.desc", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.1.1.3.%i.%i", NULL, SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET | SU_TYPE_DAISY_1, NULL, NULL }, { "outlet.%i.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.6.1.2.%i.%i", NULL, SU_FLAG_OK | SU_OUTLET | SU_TYPE_DAISY_1, &marlin_outlet_status_info[0], NULL }, - - /* FIXME: or use ".1.3.6.1.4.1.534.6.6.7.6.1.1.2.0.1", though it's related to groups! */ + /* Numeric identifier of the outlet, tied to the whole unit */ { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET | SU_TYPE_DAISY_1, NULL, NULL }, + /* outletID: Outlet physical name, related to its number in the group + ex: 1rst outlet of the second group (B) is B1 */ + { "outlet.%i.name", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.1.1.2.%i.%i", NULL, SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET | SU_TYPE_DAISY_1, NULL, NULL }, /* FIXME: the last part of the OID gives the group number (i.e. %i.1 means "group 1") * Need to address that, without multiple declaration (%i.%i, SU_OUTLET | SU_OUTLET_GROUP)? */ { "outlet.%i.groupid", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.2.1.3.%i.%i.1", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET | SU_TYPE_DAISY_1, NULL, NULL }, @@ -639,8 +458,8 @@ static snmp_info_t eaton_marlin_mib[] = { { "outlet.%i.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.7.%i.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET | SU_TYPE_DAISY_1, NULL, NULL }, { "outlet.%i.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.6.5.1.2.%i.%i", NULL, SU_OUTLET | SU_TYPE_DAISY_1, NULL, NULL }, /* FIXME: handle non switchable units (only measurements), which do not expose this OID */ - { "outlet.%i.switchable", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.6.1.3.%i.%i", "no", SU_FLAG_STATIC | SU_OUTLET | SU_FLAG_OK | SU_TYPE_DAISY_1, &eaton_outlet_switchability_info[0], NULL }, - { "outlet.%i.type", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.1.1.5.%i.%i", "unknown", SU_FLAG_STATIC | SU_OUTLET | SU_TYPE_DAISY_1, &eaton_outlet_type_info[0], NULL }, + { "outlet.%i.switchable", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.6.1.3.%i.%i", "no", SU_FLAG_STATIC | SU_OUTLET | SU_FLAG_OK | SU_TYPE_DAISY_1, &marlin_outlet_switchability_info[0], NULL }, + { "outlet.%i.type", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.1.1.5.%i.%i", "unknown", SU_FLAG_STATIC | SU_OUTLET | SU_TYPE_DAISY_1, &marlin_outlet_type_info[0], NULL }, /* TODO: handle statistics * outletWh.0.1 @@ -648,7 +467,7 @@ static snmp_info_t eaton_marlin_mib[] = { */ /* Outlet groups collection */ - { "outlet.group.count", 0, 1, ".1.3.6.1.4.1.534.6.6.7.1.2.1.21.%i", "0", SU_FLAG_STATIC, NULL, NULL }, + { "outlet.group.count", 0, 1, ".1.3.6.1.4.1.534.6.6.7.1.2.1.21.%i", "0", SU_FLAG_STATIC | SU_TYPE_DAISY_1, NULL, NULL }, /* outlet groups template definition * Indexes start from 1, ie outlet.group.1 => .1 */ /* Note: the first definition is used to determine the base index (ie 0 or 1) */ @@ -659,6 +478,9 @@ static snmp_info_t eaton_marlin_mib[] = { { "outlet.group.%i.name", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.3.%i.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP | SU_TYPE_DAISY_1, NULL, NULL }, /* groupType.0.1 = Integer: outletSection (4) */ { "outlet.group.%i.type", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.4.%i.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP | SU_TYPE_DAISY_1, &marlin_outlet_group_type_info[0], NULL }, +#if WITH_SNMP_LKP_FUN + { "outlet.group.%i.phase", 0, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.2.%i.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP | SU_TYPE_DAISY_1, &marlin_outlet_group_phase_info[0], NULL }, +#else // not WITH_SNMP_LKP_FUN /* ugly trick which limits input phase to electrical groups only (not outlet-section nor user-defined!) * For now, there is a maximum of 6 gangs (electrical groups) */ { "outlet.group.1.phase", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.4.%i.1", NULL, SU_FLAG_STATIC | SU_TYPE_DAISY_1, &marlin_outlet_group_phase1_info[0], NULL }, @@ -667,6 +489,7 @@ static snmp_info_t eaton_marlin_mib[] = { { "outlet.group.4.phase", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.4.%i.4", NULL, SU_FLAG_STATIC | SU_TYPE_DAISY_1, &marlin_outlet_group_phase1_info[0], NULL }, { "outlet.group.5.phase", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.4.%i.5", NULL, SU_FLAG_STATIC | SU_TYPE_DAISY_1, &marlin_outlet_group_phase2_info[0], NULL }, { "outlet.group.6.phase", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.4.%i.6", NULL, SU_FLAG_STATIC | SU_TYPE_DAISY_1, &marlin_outlet_group_phase3_info[0], NULL }, +#endif // WITH_SNMP_LKP_FUN /* groupControlStatus.0.1 = Integer: on (1) */ { "outlet.group.%i.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.6.1.2.%i.%i", NULL, SU_FLAG_OK | SU_OUTLET_GROUP | SU_TYPE_DAISY_1, &marlin_outletgroups_status_info[0], NULL }, @@ -705,7 +528,7 @@ static snmp_info_t eaton_marlin_mib[] = { /* instant commands. */ /* Notes: - * - load.cycle might be replaced by / mapped on shutdown.reboot + * - load.cycle might be replaced by / mapped on shutdown.reboot * - outletControl{Off,On,Reboot}Cmd values: * 0-n : Timer * -1 : Cancel @@ -736,112 +559,5 @@ static snmp_info_t eaton_marlin_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } }; -/* Pulizzi Monitored ePDU (Basic model, SNMP only) - * FIXME: to be completed - * - * Warning: there are 2 versions: - * - SA built MI.mib (old MIB) - * #define PULIZZI1_OID_MIB ".1.3.6.1.4.1.20677.3.1.1" - * #define PULIZZI1_OID_MODEL_NAME ".1.3.6.1.4.1.20677.3.1.1.1.2.0" - * - Eaton-Powerware-Monitored-ePDU_1.0.E.mib (new MIB) Vertical SW - */ - -/* Pulizzi Switched ePDU */ - -#define EATON_PULIZZI_SW_MIB_VERSION "0.2" - -#define PULIZZI_SW_OID_MIB ".1.3.6.1.4.1.20677.3.1.1" -#define PULIZZI_SW_OID_MODEL_NAME ".1.3.6.1.4.1.20677.2.1.1.0" - -/* Some buggy FW also report sysOID = ".1.3.6.1.4.1.20677.1" */ -#define EATON_PULIZZI_SWITCHED1_SYSOID ".1.3.6.1.4.1.20677.1" -#define EATON_PULIZZI_SWITCHED2_SYSOID ".1.3.6.1.4.1.20677.2" - - -static info_lkp_t pulizzi_sw_outlet_status_info[] = { - { 1, "on" }, - { 2, "off" }, - { 0, NULL } -}; - -/* simply remap the above status to "yes" */ -static info_lkp_t pulizzi_sw_outlet_switchability_info[] = { - { 1, "yes" }, - { 2, "yes" }, - { 0, NULL } -}; - -/* Snmp2NUT lookup table for Eaton Pulizzi Switched ePDU MIB */ -static snmp_info_t eaton_pulizzi_switched_mib[] = { - /* Device page */ - { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "device.model", ST_FLAG_STRING, SU_INFOSIZE, PULIZZI_SW_OID_MODEL_NAME, - "Switched ePDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.2.6.0", - "unknown", 0, NULL, NULL }, - - /* UPS page */ - { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, - { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, PULIZZI_SW_OID_MODEL_NAME, - "Switched ePDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - /* FIXME: to be moved to the device collection! */ - { "ups.date", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.1.4.0", - "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - { "ups.time", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.1.3.0", - "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - - /* Outlet page */ - /* Note: outlet.count is deduced, with guestimate_outlet_count() */ - { "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, - { "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "All outlets", - SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, - - { "outlet.current", 0, 1.0, ".1.3.6.1.4.1.20677.2.8.6.4.2.0", NULL, 0, NULL, NULL }, - { "outlet.voltage", 0, 1.0, ".1.3.6.1.4.1.20677.2.8.6.4.1.0", NULL, 0, NULL, NULL }, - { "outlet.power", 0, 1.0, ".1.3.6.1.4.1.20677.2.8.6.4.3.0", NULL, 0, NULL, NULL }, - - /* outlet template definition - * Notes: - * - indexes start from 1, ie outlet.1 => .1 - * - the first definition is used to determine the base index (ie 0 or 1) - * - outlet.count is estimated, based on the below OID iteration capabilities */ - { "outlet.%i.desc", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.1.%i.1.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, - { "outlet.%i.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.3.%i.0", - NULL, SU_FLAG_OK | SU_OUTLET, &pulizzi_sw_outlet_status_info[0], NULL }, - { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, - /* we use the same OID as outlet.n.status..., to expose switchability */ - { "outlet.%i.switchable", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.3.%i.0", "yes", SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET, &pulizzi_sw_outlet_switchability_info[0], NULL }, - /* FIXME: need to be added to the namespace! */ - { "outlet.%i.delay.reboot", ST_FLAG_RW, 1, ".1.3.6.1.4.1.20677.2.6.1.%i.5.0", NULL, SU_OUTLET, NULL, NULL }, - /* "outlet1SequenceTime" is used for global sequence */ - { "outlet.%i.delay.start", ST_FLAG_RW, 1, ".1.3.6.1.4.1.20677.2.6.1.%i.4.0", NULL, SU_OUTLET, NULL, NULL }, - - /* instant commands. */ - /* FIXME: not exposed as "outlet.load...", or otherwise specific processing applies (template instanciation) */ - { "load.on", 0, 1, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, - { "load.off", 0, 2, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, - { "load.on.delay", 0, 3, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, - { "load.off.delay", 0, 4, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, - - /* WARNING: outlet 1 => index 2! */ - { "outlet.%i.load.on", 0, 1, ".1.3.6.1.4.1.20677.2.6.2.%i.0", NULL, SU_TYPE_CMD | SU_OUTLET | SU_CMD_OFFSET, NULL, NULL }, - { "outlet.%i.load.off", 0, 2, ".1.3.6.1.4.1.20677.2.6.2.%i.0", NULL, SU_TYPE_CMD | SU_OUTLET | SU_CMD_OFFSET, NULL, NULL }, - { "outlet.%i.load.cycle", 0, 3, ".1.3.6.1.4.1.20677.2.6.2.%i.0", NULL, SU_TYPE_CMD | SU_OUTLET | SU_CMD_OFFSET, NULL, NULL }, - - /* end of structure. */ - { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } -}; - - -mib2nut_info_t aphel_genesisII = { "aphel_genesisII", EATON_APHEL_MIB_VERSION, NULL, APHEL1_OID_MODEL_NAME, eaton_aphel_genesisII_mib, APHEL1_SYSOID }; -mib2nut_info_t aphel_revelation = { "aphel_revelation", EATON_APHEL_MIB_VERSION, NULL, APHEL2_OID_MODEL_NAME, eaton_aphel_revelation_mib, APHEL2_SYSOID }; mib2nut_info_t eaton_marlin = { "eaton_epdu", EATON_MARLIN_MIB_VERSION, NULL, EATON_MARLIN_OID_MODEL_NAME, eaton_marlin_mib, EATON_MARLIN_SYSOID }; - -/*mib2nut_info_t pulizzi_monitored = { "pulizzi_monitored", EATON_PULIZZI_MIB_VERSION, NULL, PULIZZI1_OID_MODEL_NAME, eaton_pulizzi_monitored_mib, PULIZZI1_OID_MIB };*/ -mib2nut_info_t pulizzi_switched1 = { "pulizzi_switched1", EATON_PULIZZI_SW_MIB_VERSION, NULL, EATON_PULIZZI_SWITCHED1_SYSOID, eaton_pulizzi_switched_mib, EATON_PULIZZI_SWITCHED1_SYSOID }; -mib2nut_info_t pulizzi_switched2 = { "pulizzi_switched2", EATON_PULIZZI_SW_MIB_VERSION, NULL, EATON_PULIZZI_SWITCHED1_SYSOID, eaton_pulizzi_switched_mib, EATON_PULIZZI_SWITCHED2_SYSOID }; diff --git a/drivers/eaton-pdu-marlin-mib.h b/drivers/eaton-pdu-marlin-mib.h new file mode 100644 index 0000000000..9014bb7cf8 --- /dev/null +++ b/drivers/eaton-pdu-marlin-mib.h @@ -0,0 +1,32 @@ +/* eaton-pdu-marlin-mib.h - subdriver to monitor Eaton ePDU SNMP devices with NUT + * + * Copyright (C) + * 2010 Arjen de Korte + * 2011 - 2012 Arnaud Quette + * 2017 Arnaud Quette + * 2017 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EATON_EPDU_MARLIN_MIB_H +#define EATON_EPDU_MARLIN_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t eaton_marlin; + +#endif /* EATON_EPDU_MARLIN_MIB_H */ diff --git a/drivers/eaton-pdu-pulizzi-mib.c b/drivers/eaton-pdu-pulizzi-mib.c new file mode 100644 index 0000000000..114d2bfd86 --- /dev/null +++ b/drivers/eaton-pdu-pulizzi-mib.c @@ -0,0 +1,136 @@ +/* eaton-pdu-pulizzi-mib.c - data to monitor Eaton ePDUs branded as: + * G1 Pulizzi Monitored and Switched ePDUs + * + * Copyright (C) 2008 - 2017 + * Arnaud Quette + * Arnaud Quette + * Copyright (C) 2015 - 2017 + * Jim Klimov + * + * Supported by Eaton + * and previously MGE Office Protection Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "eaton-pdu-pulizzi-mib.h" + +/* Pulizzi Monitored ePDU (Basic model, SNMP only) + * FIXME: to be completed + * + * Warning: there are 2 versions: + * - SA built MI.mib (old MIB) + * #define PULIZZI1_OID_MIB ".1.3.6.1.4.1.20677.3.1.1" + * #define PULIZZI1_OID_MODEL_NAME ".1.3.6.1.4.1.20677.3.1.1.1.2.0" + * - Eaton-Powerware-Monitored-ePDU_1.0.E.mib (new MIB) Vertical SW + */ + + +/* Pulizzi Switched ePDU */ + +#define EATON_PULIZZI_SW_MIB_VERSION "0.2" + +#define PULIZZI_SW_OID_MIB ".1.3.6.1.4.1.20677.3.1.1" +#define PULIZZI_SW_OID_MODEL_NAME ".1.3.6.1.4.1.20677.2.1.1.0" + +/* Some buggy FW also report sysOID = ".1.3.6.1.4.1.20677.1" */ +#define EATON_PULIZZI_SWITCHED1_SYSOID ".1.3.6.1.4.1.20677.1" +#define EATON_PULIZZI_SWITCHED2_SYSOID ".1.3.6.1.4.1.20677.2" + + +static info_lkp_t pulizzi_sw_outlet_status_info[] = { + { 1, "on" }, + { 2, "off" }, + { 0, NULL } +}; + +/* simply remap the above status to "yes" */ +static info_lkp_t pulizzi_sw_outlet_switchability_info[] = { + { 1, "yes" }, + { 2, "yes" }, + { 0, NULL } +}; + +/* Snmp2NUT lookup table for Eaton Pulizzi Switched ePDU MIB */ +static snmp_info_t eaton_pulizzi_switched_mib[] = { + /* Device page */ + { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.model", ST_FLAG_STRING, SU_INFOSIZE, PULIZZI_SW_OID_MODEL_NAME, + "Switched ePDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.2.6.0", + "unknown", 0, NULL, NULL }, + + /* UPS page */ + { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, PULIZZI_SW_OID_MODEL_NAME, + "Switched ePDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* FIXME: to be moved to the device collection! */ + { "ups.date", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.1.4.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.time", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.1.3.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + + /* Outlet page */ + /* Note: outlet.count is deduced, with guestimate_outlet_count() */ + { "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, + { "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "All outlets", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, + + { "outlet.current", 0, 1.0, ".1.3.6.1.4.1.20677.2.8.6.4.2.0", NULL, 0, NULL, NULL }, + { "outlet.voltage", 0, 1.0, ".1.3.6.1.4.1.20677.2.8.6.4.1.0", NULL, 0, NULL, NULL }, + { "outlet.power", 0, 1.0, ".1.3.6.1.4.1.20677.2.8.6.4.3.0", NULL, 0, NULL, NULL }, + + /* outlet template definition + * Notes: + * - indexes start from 1, ie outlet.1 => .1 + * - the first definition is used to determine the base index (ie 0 or 1) + * - outlet.count is estimated, based on the below OID iteration capabilities */ + { "outlet.%i.desc", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.1.%i.1.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, + { "outlet.%i.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.3.%i.0", + NULL, SU_FLAG_OK | SU_OUTLET, &pulizzi_sw_outlet_status_info[0], NULL }, + { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, + /* we use the same OID as outlet.n.status..., to expose switchability */ + { "outlet.%i.switchable", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.3.%i.0", "yes", SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET, &pulizzi_sw_outlet_switchability_info[0], NULL }, + /* FIXME: need to be added to the namespace! */ + { "outlet.%i.delay.reboot", ST_FLAG_RW, 1, ".1.3.6.1.4.1.20677.2.6.1.%i.5.0", NULL, SU_OUTLET, NULL, NULL }, + /* "outlet1SequenceTime" is used for global sequence */ + { "outlet.%i.delay.start", ST_FLAG_RW, 1, ".1.3.6.1.4.1.20677.2.6.1.%i.4.0", NULL, SU_OUTLET, NULL, NULL }, + + /* instant commands. */ + /* FIXME: not exposed as "outlet.load...", or otherwise specific processing applies (template instanciation) */ + { "load.on", 0, 1, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "load.off", 0, 2, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "load.on.delay", 0, 3, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "load.off.delay", 0, 4, ".1.3.6.1.4.1.20677.2.6.2.1.0", NULL, SU_TYPE_CMD, NULL, NULL }, + + /* WARNING: outlet 1 => index 2! */ + { "outlet.%i.load.on", 0, 1, ".1.3.6.1.4.1.20677.2.6.2.%i.0", NULL, SU_TYPE_CMD | SU_OUTLET | SU_CMD_OFFSET, NULL, NULL }, + { "outlet.%i.load.off", 0, 2, ".1.3.6.1.4.1.20677.2.6.2.%i.0", NULL, SU_TYPE_CMD | SU_OUTLET | SU_CMD_OFFSET, NULL, NULL }, + { "outlet.%i.load.cycle", 0, 3, ".1.3.6.1.4.1.20677.2.6.2.%i.0", NULL, SU_TYPE_CMD | SU_OUTLET | SU_CMD_OFFSET, NULL, NULL }, + + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } +}; + + +/*mib2nut_info_t pulizzi_monitored = { "pulizzi_monitored", EATON_PULIZZI_MIB_VERSION, NULL, PULIZZI1_OID_MODEL_NAME, eaton_pulizzi_monitored_mib, PULIZZI1_OID_MIB };*/ +mib2nut_info_t pulizzi_switched1 = { "pulizzi_switched1", EATON_PULIZZI_SW_MIB_VERSION, NULL, EATON_PULIZZI_SWITCHED1_SYSOID, eaton_pulizzi_switched_mib, EATON_PULIZZI_SWITCHED1_SYSOID }; +mib2nut_info_t pulizzi_switched2 = { "pulizzi_switched2", EATON_PULIZZI_SW_MIB_VERSION, NULL, EATON_PULIZZI_SWITCHED1_SYSOID, eaton_pulizzi_switched_mib, EATON_PULIZZI_SWITCHED2_SYSOID }; diff --git a/drivers/eaton-pdu-pulizzi-mib.h b/drivers/eaton-pdu-pulizzi-mib.h new file mode 100644 index 0000000000..5c08fb6e55 --- /dev/null +++ b/drivers/eaton-pdu-pulizzi-mib.h @@ -0,0 +1,33 @@ +/* eaton-pdu-pulizzi-mib.h - subdriver to monitor Eaton ePDU SNMP devices with NUT + * + * Copyright (C) + * 2010 Arjen de Korte + * 2011 - 2012 Arnaud Quette + * 2017 Arnaud Quette + * 2017 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EATON_EPDU_PULIZZI_MIB_H +#define EATON_EPDU_PULIZZI_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t pulizzi_switched1; +extern mib2nut_info_t pulizzi_switched2; + +#endif /* EATON_EPDU_PULIZZI_MIB_H */ diff --git a/drivers/eaton-pdu-revelation-mib.c b/drivers/eaton-pdu-revelation-mib.c new file mode 100644 index 0000000000..9f96724b49 --- /dev/null +++ b/drivers/eaton-pdu-revelation-mib.c @@ -0,0 +1,176 @@ +/* eaton-pdu-revelation-mib.c - data to monitor Eaton ePDUs branded as: + * G1 Aphel based ePDUs (Complex) - Revelation + * + * Copyright (C) 2008 - 2017 + * Arnaud Quette + * Arnaud Quette + * Copyright (C) 2015 - 2017 + * Jim Klimov + * + * Supported by Eaton + * and previously MGE Office Protection Systems + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "eaton-pdu-revelation-mib.h" + +#define EATON_APHEL_REVELATION_MIB_VERSION "0.49" + +/* APHEL PDU-MIB - Revelation MIB (Managed ePDU) + * ********************************************* */ + +#define AR_BASE_OID ".1.3.6.1.4.1.534.6.6.6" +#define APHEL2_SYSOID AR_BASE_OID +#define APHEL2_OID_MODEL_NAME AR_OID_MODEL_NAME + +#define AR_OID_MODEL_NAME AR_BASE_OID ".1.1.12.0" +#define AR_OID_DEVICE_NAME AR_BASE_OID ".1.1.13.0" +#define AR_OID_FIRMREV AR_BASE_OID ".1.1.1.0" +#define AR_OID_SERIAL AR_BASE_OID ".1.1.2.0" +#define AR_OID_UNIT_MACADDR AR_BASE_OID ".1.1.6.0" + +#define AR_OID_UNIT_CURRENT AR_BASE_OID ".1.3.1.1" +#define AR_OID_UNIT_VOLTAGE AR_BASE_OID ".1.3.1.2" +#define AR_OID_UNIT_ACTIVEPOWER AR_BASE_OID ".1.3.1.3" +#define AR_OID_UNIT_APPARENTPOWER AR_BASE_OID ".1.3.1.4" +#define AR_OID_UNIT_CPUTEMPERATURE AR_BASE_OID ".1.3.1.5.0" + +#define AR_OID_OUTLET_INDEX AR_BASE_OID ".1.2.2.1.1" +#define AR_OID_OUTLET_NAME AR_BASE_OID ".1.2.2.1.2" +#define AR_OID_OUTLET_STATUS AR_BASE_OID ".1.2.2.1.3" + +static info_lkp_t revelation_outlet_status_info[] = { + { -1, "error" }, + { 0, "off" }, + { 1, "on" }, + { 2, "cycling" }, /* transitional status */ + { 0, NULL } +}; + +/* Ugly hack: having the matching OID present means that the outlet is + * switchable. So, it should not require this value lookup */ +static info_lkp_t revelation_outlet_switchability_info[] = { + { -1, "yes" }, + { 0, "yes" }, + { 1, "yes" }, + { 2, "yes" }, + { 0, NULL } +}; + +#define DO_OFF 0 +#define DO_ON 1 +#define DO_CYCLE 2 + +#define AR_OID_OUTLET_COUNT AR_BASE_OID ".1.2.1.0" +#define AR_OID_OUTLET_CURRENT AR_BASE_OID ".1.2.2.1.4" +#define AR_OID_OUTLET_MAXCURRENT AR_BASE_OID ".1.2.2.1.5" +#define AR_OID_OUTLET_VOLTAGE AR_BASE_OID ".1.2.2.1.6" +#define AR_OID_OUTLET_ACTIVEPOWER AR_BASE_OID ".1.2.2.1.7" +#define AR_OID_OUTLET_APPARENTPOWER AR_BASE_OID ".1.2.2.1.8" +#define AR_OID_OUTLET_POWERFACTOR AR_BASE_OID ".1.2.2.1.9" + +/* Snmp2NUT lookup table for Eaton Revelation MIB */ +static snmp_info_t eaton_aphel_revelation_mib[] = { + /* Device collection */ + { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.model", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_MODEL_NAME, + "Eaton Powerware ePDU Managed", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.serial", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_SERIAL, "", + SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_UNIT_MACADDR, "", + SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* hardwareRev.0 = Integer: 26 */ + /* FIXME: not compliant! to be RFC'ed */ + { "device.revision", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.6.1.1.7.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + + /* UPS collection */ + { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON | Powerware", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_MODEL_NAME, + "Generic SNMP PDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_DEVICE_NAME, + "unknown", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.serial", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_SERIAL, "", + SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_FIRMREV, "", + SU_FLAG_STATIC | SU_FLAG_OK, NULL }, + { "ups.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "ups.temperature", 0, 1, AR_OID_UNIT_CPUTEMPERATURE, NULL, 0, NULL, NULL }, + + /* Outlet collection */ + { "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, + { "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "All outlets", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, + { "outlet.count", 0, 1, AR_OID_OUTLET_COUNT, "0", 0, NULL }, + { "outlet.current", 0, 0.001, AR_OID_UNIT_CURRENT ".0", NULL, 0, NULL, NULL }, + { "outlet.voltage", 0, 0.001, AR_OID_UNIT_VOLTAGE ".0", NULL, 0, NULL, NULL }, + { "outlet.realpower", 0, 1.0, AR_OID_UNIT_ACTIVEPOWER ".0", NULL, 0, NULL, NULL }, + { "outlet.power", 0, 1.0, AR_OID_UNIT_APPARENTPOWER ".0", NULL, 0, NULL, NULL }, + + /* outlet template definition + * Caution: the index of the data start at 0, while the name is +1 + * ie outlet.1 => .0 */ + { "outlet.%i.switchable", 0, 1, AR_OID_OUTLET_STATUS ".%i", "yes", SU_FLAG_STATIC | SU_OUTLET, &revelation_outlet_switchability_info[0], NULL }, + { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, + { "outlet.%i.desc", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, AR_OID_OUTLET_NAME ".%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.status", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_OUTLET_STATUS ".%i", NULL, SU_FLAG_OK | SU_OUTLET, &revelation_outlet_status_info[0], NULL }, + { "outlet.%i.current", 0, 0.001, AR_OID_OUTLET_CURRENT ".%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.current.maximum", 0, 0.001, AR_OID_OUTLET_MAXCURRENT ".%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.realpower", 0, 1.0, AR_OID_OUTLET_ACTIVEPOWER ".%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.voltage", 0, 1.0, AR_OID_OUTLET_VOLTAGE ".%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.powerfactor", 0, 0.01, AR_OID_OUTLET_POWERFACTOR ".%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.power", 0, 1.0, AR_OID_OUTLET_APPARENTPOWER ".%i", NULL, SU_OUTLET, NULL, NULL }, + + /* FIXME: + * - delay for startup/shutdown sequence + * - support for multiple Ambient sensors ( max. 8), starting at index '0' + * ambient.%i.temperature => .1.3.6.1.4.1.534.6.6.6.2.2.1.3.%i + * ambient.%i.humidity => .1.3.6.1.4.1.534.6.6.6.2.4.1.3.%i + */ + + /* Ambient collection */ + /* We use critical levels, for both temperature and humidity, + * since warning levels are also available! */ + { "ambient.temperature", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.2.1.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.low", 0, 1.0, "1.3.6.1.4.1.534.6.6.6.2.2.1.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.high", 0, 1.0, "1.3.6.1.4.1.534.6.6.6.2.2.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.4.1.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.low", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.4.1.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.high", 0, 1.0, ".1.3.6.1.4.1.534.6.6.6.2.4.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* instant commands. */ + /* Note that load.cycle might be replaced by / mapped on shutdown.reboot */ + /* no counterpart found! + { "outlet.load.off", 0, DO_OFF, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "outlet.load.on", 0, DO_ON, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "outlet.load.cycle", 0, DO_CYCLE, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, */ + { "outlet.%i.load.off", 0, DO_OFF, AR_OID_OUTLET_STATUS ".%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + { "outlet.%i.load.on", 0, DO_ON, AR_OID_OUTLET_STATUS ".%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + { "outlet.%i.load.cycle", 0, DO_CYCLE, AR_OID_OUTLET_STATUS ".%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } +}; + + +mib2nut_info_t aphel_revelation = { "aphel_revelation", EATON_APHEL_REVELATION_MIB_VERSION, NULL, APHEL2_OID_MODEL_NAME, eaton_aphel_revelation_mib, APHEL2_SYSOID }; diff --git a/drivers/eaton-pdu-revelation-mib.h b/drivers/eaton-pdu-revelation-mib.h new file mode 100644 index 0000000000..3cd2645f17 --- /dev/null +++ b/drivers/eaton-pdu-revelation-mib.h @@ -0,0 +1,32 @@ +/* eaton-pdu-revelation-mib.h - subdriver to monitor Eaton ePDU SNMP devices with NUT + * + * Copyright (C) + * 2010 Arjen de Korte + * 2011 - 2012 Arnaud Quette + * 2017 Arnaud Quette + * 2017 Jim Klimov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EATON_EPDU_REVELATION_MIB_H +#define EATON_EPDU_REVELATION_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t aphel_revelation; + +#endif /* EATON_EPDU_REVELATION_MIB_H */ diff --git a/drivers/snmp-ups.c b/drivers/snmp-ups.c index 3e20a5d875..ed4054f83c 100644 --- a/drivers/snmp-ups.c +++ b/drivers/snmp-ups.c @@ -5,14 +5,13 @@ * * Copyright (C) * 2002 - 2014 Arnaud Quette - * 2015 - 2016 Eaton (author: Arnaud Quette ) - * 2017 Eaton (author: Jim Klimov ) + * 2015 - 2017 Eaton (author: Arnaud Quette ) + * 2016 - 2017 Eaton (author: Jim Klimov ) + * 2016 Eaton (author: Carlos Dominguez ) * 2002 - 2006 Dmitry Frolov * J.W. Hoogervorst * Niels Baggesen * 2009 - 2010 Arjen de Korte - * 2016 Jim Klimov - * 2016 Carlos Dominguez * * Sponsored by Eaton * and originally by MGE UPS SYSTEMS @@ -53,7 +52,10 @@ #include "mge-mib.h" #include "netvision-mib.h" #include "powerware-mib.h" -#include "eaton-mib.h" +#include "eaton-pdu-genesis2-mib.h" +#include "eaton-pdu-marlin-mib.h" +#include "eaton-pdu-pulizzi-mib.h" +#include "eaton-pdu-revelation-mib.h" #include "raritan-pdu-mib.h" #include "raritan-px2-mib.h" #include "baytech-mib.h" @@ -159,7 +161,7 @@ const char *mibvers; #else # define DRIVER_NAME "Generic SNMP UPS driver" #endif /* WITH_DMFMIB */ -#define DRIVER_VERSION "1.00" +#define DRIVER_VERSION "1.02" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -1199,7 +1201,7 @@ void su_setinfo(snmp_info_t *su_info_p, const char *value) /* FIXME: Replace hardcoded 128 with a macro above (use {SU_}LARGEBUF?), *and same macro or sizeof(info_type) below? */ - upsdebugx(1, "entering %s(%s)", __func__, su_info_p->info_type); + upsdebugx(1, "entering %s(%s, %s)", __func__, su_info_p->info_type, (value)?value:""); /* FIXME: This 20 seems very wrong (should be "128", macro or sizeof? see above) */ memset(info_type, 0, 20); @@ -1584,6 +1586,17 @@ const char *su_find_infoval(info_lkp_t *oid2info, long value) { info_lkp_t *info_lkp; +#if WITH_SNMP_LKP_FUN + /* First test if we have a generic lookup function */ + if ( (oid2info != NULL) && (oid2info->fun != NULL) ) { + upsdebugx(2, "%s: using generic lookup function", __func__); + const char * retvalue = oid2info->fun(value); + upsdebugx(2, "%s: got value '%s'", __func__, retvalue); + return retvalue; + } +#endif // WITH_SNMP_LKP_FUN + + /* Otherwise, use the simple values mapping */ for (info_lkp = oid2info; (info_lkp != NULL) && (info_lkp->info_value != NULL) && (strcmp(info_lkp->info_value, "NULL")); info_lkp++) { @@ -2538,6 +2551,7 @@ bool_t su_ups_get(snmp_info_t *su_info_p) static char buf[SU_INFOSIZE]; bool_t status; long value; + double dvalue; const char *strValue = NULL; struct snmp_pdu ** pdu_array; struct snmp_pdu * current_pdu; @@ -2734,11 +2748,11 @@ bool_t su_ups_get(snmp_info_t *su_info_p) /* Check if there is a need to publish decimal too, * i.e. if switching to integer does not cause a * loss of precision */ - value = value * su_info_p->info_len; - if ((int)value == value) - snprintf(buf, sizeof(buf), "%i", (int)value); + dvalue = value * su_info_p->info_len; + if ((int)dvalue == dvalue) + snprintf(buf, sizeof(buf), "%i", (int)dvalue); else - snprintf(buf, sizeof(buf), "%.2f", (float)value); + snprintf(buf, sizeof(buf), "%.2f", (float)dvalue); } } } diff --git a/drivers/snmp-ups.h b/drivers/snmp-ups.h index e1e373248a..4b93b85ad2 100644 --- a/drivers/snmp-ups.h +++ b/drivers/snmp-ups.h @@ -3,8 +3,11 @@ * Based on NET-SNMP API (Simple Network Management Protocol V1-2) * * Copyright (C) - * 2002-2010 Arnaud Quette - * 2002-2006 Dmitry Frolov + * 2002 - 2010 Arnaud Quette + * 2015 - 2017 Eaton (author: Arnaud Quette ) + * 2016 - 2017 Eaton (author: Jim Klimov ) + * 2016 Eaton (author: Carlos Dominguez ) + * 2002 - 2006 Dmitry Frolov * J.W. Hoogervorst * Niels Baggesen * @@ -143,10 +146,33 @@ typedef int bool_t; /* typedef void (*interpreter)(char *, char *, int); */ +#ifndef WITH_SNMP_LKP_FUN +/* Recent addition of fun/nuf hooks in info_lkp_t is not well handled by + * all corners of the codebase, e.g. not by DMF. So at least until that + * is fixed, (TODO) we enable those bits of code only optionally during + * a build for particular usage. Conversely, experimenters can define + * this macro to a specific value while building the codebase and see + * what happens under different conditions ;) + */ +# if WITH_DMFMIB +# define WITH_SNMP_LKP_FUN 0 +# else +# define WITH_SNMP_LKP_FUN 1 +# endif +#endif + /* for lookup between OID values and INFO_ value */ typedef struct { - int oid_value; /* OID value */ - const char *info_value; /* INFO_* value */ + int oid_value; /* SNMP OID value */ + const char *info_value; /* NUT INFO_* value */ +#if WITH_SNMP_LKP_FUN +/* FIXME: Currently we do not have a way to provide custom C code + * via DMF - keep old approach until we get the ability, e.g. by + * requiring a LUA implementation to be passed alongside C lookups. + */ + const char *(*fun)(int snmp_value); /* optional SNMP to NUT mapping function */ + int (*nuf)(const char *nut_value); /* optional NUT to SNMP mapping function */ +#endif } info_lkp_t; /* Structure containing info about one item that can be requested diff --git a/scripts/DMF/Makefile.am b/scripts/DMF/Makefile.am index 4d5dce5585..11f3156527 100644 --- a/scripts/DMF/Makefile.am +++ b/scripts/DMF/Makefile.am @@ -9,8 +9,8 @@ DMFTOOLS_INCLUDE_FLAGS = -I$(abs_top_builddir) -I$(abs_top_srcdir) \ -I$(abs_top_builddir)/include -I$(abs_top_srcdir)/include \ -I$(abs_top_builddir)/drivers -I$(abs_top_srcdir)/drivers \ -I$(abs_top_builddir)/tools/nut-scanner -I$(abs_top_srcdir)/tools/nut-scanner -DMFTOOLS_CFLAGS = $(DMFTOOLS_INCLUDE_FLAGS) -DMFTOOLS_CPPFLAGS = $(DMFTOOLS_INCLUDE_FLAGS) +DMFTOOLS_CFLAGS = $(DMFTOOLS_INCLUDE_FLAGS) -DWITH_DMFMIB=1 +DMFTOOLS_CPPFLAGS = $(DMFTOOLS_INCLUDE_FLAGS) -DWITH_DMFMIB=1 DISTCLEANFILES = DISTCLEANDIRS = CLEANFILES = @@ -176,11 +176,16 @@ if WITH_REGENERATE_DMF_SNMP if test -f "$(DMFGEN_SANITY_VALIDATED)" ; then \ ( cd "$(@D)" && \ CFLAGS="$(DMFTOOLS_CFLAGS) $(AM_CFLAGS)" \ + LDFLAGSx="$(abs_top_builddir)/common/libcommon.la $(abs_top_builddir)/drivers/dstate.o" \ CPPFLAGS="$(DMFTOOLS_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS)" \ $(abs_srcdir)/dmfify-mib.sh --skip-sanity-check "$$CMIBFILE" \ ) || exit; \ fi ; \ - if test ! -s "$@" -a ! -s "$(abs_top_builddir)/$@" -a ! -s "$(abs_top_srcdir)/$@"; then echo "ERROR: Generated file $@ is missing" >&2; ls -la "$@" "$(abs_top_builddir)/$@" "$(abs_top_srcdir)/$@"; exit 2; fi; \ + if test ! -s "$@" -a ! -s "$(abs_top_builddir)/$@" -a ! -s "$(abs_top_srcdir)/$@"; then \ + echo "ERROR: Generated file $@ is missing" >&2; \ + ls -la "$@" "$(abs_top_builddir)/$@" "$(abs_top_srcdir)/$@"; \ + exit 2; \ + fi; \ ) dmfgen-sanity: $(abs_srcdir)/dmfify-mib.sh @@ -408,6 +413,7 @@ noinst_PROGRAMS += dmf-test dmf_test_SOURCES = $(DMFTEST_SRC) dmf_test_LDADD = $(top_builddir)/common/libnutdmfsnmp.la $(LIBS_dmfsnmp_ltdlXneon) \ $(top_builddir)/common/libcommonstr.la +# $(top_builddir)/common/libcommon.la $(top_builddir)/drivers/dstate.o dmf_test_CFLAGS = $(DMFTESTS_COMMON_CFLAGS) $(CFLAGS_DMF_LUA) dmf_test_LDFLAGS = $(LDFLAGS_DMF_LUA) endif @@ -458,6 +464,7 @@ noinst_PROGRAMS += dmf-lua-test dmf_lua_test_SOURCES = $(DMFTEST_SRC) dmf_lua_test_LDADD = $(top_builddir)/common/libnutdmfsnmp.la $(LIBS_dmfsnmp_ltdlXneon) \ $(top_builddir)/common/libcommonstr.la +# $(top_builddir)/common/libcommon.la $(top_builddir)/drivers/dstate.o dmf_lua_test_CFLAGS = $(DMFTESTS_COMMON_CFLAGS) $(CFLAGS_LUA) dmf_lua_test_LDFLAGS = $(LDFLAGS_LUA) diff --git a/scripts/DMF/dmf-test.c b/scripts/DMF/dmf-test.c index ed6a054fd0..78899693c5 100644 --- a/scripts/DMF/dmf-test.c +++ b/scripts/DMF/dmf-test.c @@ -27,10 +27,16 @@ #include #include +/* For experiments in development of DMF+lookup function support, + * uncomment this line; for currently stable codebase keep it off... + */ +//#define WITH_SNMP_LKP_FUN 1 + #include "dmf.h" /* The test involves generation of DMF and comparison to existing data. - As a random pick, we use eaton-mib.c "as is" (with structures). + As a random pick, we use eaton-pdu-marlin-mib.c "as is" (with structures + and referenced conversion/lookup functions, if enabled by macros). This causes macro-redefinition conflict (and -Werror dies on it) - so we undefine a few macros... */ @@ -39,7 +45,10 @@ #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_BUGREPORT -#include "eaton-mib.c" +#include "eaton-pdu-marlin-mib.c" + +// Replicate what drivers/main.c exports +int do_synchronous = 0; int main () diff --git a/scripts/DMF/dmfsnmp/eaton-ats16-mib.dmf b/scripts/DMF/dmfsnmp/eaton-ats16-mib.dmf index c3d69e3b41..3d59a7e8de 100644 --- a/scripts/DMF/dmfsnmp/eaton-ats16-mib.dmf +++ b/scripts/DMF/dmfsnmp/eaton-ats16-mib.dmf @@ -57,6 +57,7 @@ + @@ -69,6 +70,6 @@ - + diff --git a/scripts/DMF/dmfsnmp/eaton-pdu-genesis2-mib.dmf b/scripts/DMF/dmfsnmp/eaton-pdu-genesis2-mib.dmf new file mode 100644 index 0000000000..a68ddbddc1 --- /dev/null +++ b/scripts/DMF/dmfsnmp/eaton-pdu-genesis2-mib.dmf @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/DMF/dmfsnmp/eaton-mib.dmf b/scripts/DMF/dmfsnmp/eaton-pdu-marlin-mib.dmf similarity index 72% rename from scripts/DMF/dmfsnmp/eaton-mib.dmf rename to scripts/DMF/dmfsnmp/eaton-pdu-marlin-mib.dmf index 2fbda72c1f..f58579d75e 100644 --- a/scripts/DMF/dmfsnmp/eaton-mib.dmf +++ b/scripts/DMF/dmfsnmp/eaton-pdu-marlin-mib.dmf @@ -1,51 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + - + - - - - + + + + - - - + + + + + + + - - - - - + + + + + - + + + + + + + + + + + @@ -64,39 +60,23 @@ - + - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - + + + - + - + + + + @@ -105,24 +85,20 @@ - - - - + + + + - + - + - - - - - - + + @@ -137,6 +113,10 @@ + + + + @@ -262,6 +242,7 @@ + @@ -284,9 +265,9 @@ - - - + + + @@ -323,98 +304,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/scripts/DMF/dmfsnmp/eaton-pdu-pulizzi-mib.dmf b/scripts/DMF/dmfsnmp/eaton-pdu-pulizzi-mib.dmf new file mode 100644 index 0000000000..bbf835079a --- /dev/null +++ b/scripts/DMF/dmfsnmp/eaton-pdu-pulizzi-mib.dmf @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/DMF/dmfsnmp/eaton-pdu-revelation-mib.dmf b/scripts/DMF/dmfsnmp/eaton-pdu-revelation-mib.dmf new file mode 100644 index 0000000000..d6226e21b5 --- /dev/null +++ b/scripts/DMF/dmfsnmp/eaton-pdu-revelation-mib.dmf @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/DMF/jsonify-mib.py b/scripts/DMF/jsonify-mib.py index 1bda96eeb9..99aef31ea4 100644 --- a/scripts/DMF/jsonify-mib.py +++ b/scripts/DMF/jsonify-mib.py @@ -337,6 +337,9 @@ def s_json2c (fout, MIB_name, js): #endif #include "%s.c" +// Replicate what drivers/main.c exports +int do_synchronous = 0; + static inline bool streq (const char* x, const char* y) { if (!x && !y) @@ -495,7 +498,12 @@ def s_mkparser (): except KeyError: gcc_cflags = [] - cmd = [gcc, "-std=c99", "-ggdb", "-I"+drivers_dir, "-I"+include_dir] + gcc_cflags + ["-o", prog_file, test_file] + try: + gcc_ldflags = os.environ["LDFLAGS"].split() + except KeyError: + gcc_ldflags = [] + + cmd = [gcc, "-std=c99", "-ggdb", "-I"+drivers_dir, "-I"+include_dir] + gcc_cflags + ["-o", prog_file, test_file] + gcc_ldflags info ("COMPILE: " + " ".join (cmd)) try: subprocess.check_call (cmd)