diff --git a/ChangeLog b/ChangeLog index 96dc998..2a1df65 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,1090 @@ +2016-03-09 Arnaud Quette + + * configure.ac: Fix autoreconf on Debian For some reason, Automake + doesn't search the current directory correctly when searching for + helper scripts, when 'nut' is running as a git-submodule, as it is + the case with the website repository + * configure.ac: update version to 2.7.4 + * drivers/apc-ats-mib.c: snmp-ups: add APC ATS input.source + * drivers/snmp-ups.c: snmp-ups: fix the matching OID tests For both + sysOID and classic methods, we used to test one of the two OIDs + provided in the mib2nut structures. However, these two OIDs + (oid_pwr_status and oid_auto_check) tend to be redundant and + confusing. Replace these matching by an extraction of + {ups,device}.model + * drivers/nut-libfreeipmi.c: nut-ipmipsu: fix compilation warnings + * NEWS, UPGRADING, docs/FAQ.txt, docs/net-protocol.txt, docs/new- + drivers.txt, docs/nut-names.txt, docs/nutdrv_qx-subdrivers.txt, + docs/packager-guide.txt, docs/snmp-subdrivers.txt, lib/README, + scripts/augeas/README: Fix spelling and typo errors Following the + spell-checking scope expansion, do a spell-checking pass + * docs/documentation.txt: Update documentation as per the new devices + scope + * docs/features.txt, docs/user-manual.txt: Update documentation as + per the new devices scope + * docs/Makefile.am: Expand spell-checking scope Add more documents, + outside of the docs/ directory Closes: + https://github.com/networkupstools/nut/issues/222 + +2016-03-08 Arnaud Quette + + * configure.ac, tools/Makefile.am, tools/driver-list-format.sh: Check + driver.list[.in] format at make dist time Instead of checking + driver.list.in at configure time, move the checking and + modification into a script that is called at make dist time. The + script can also be called manually, and will try to fix both + driver.list.in and driver.list + +2016-03-07 Arnaud Quette + + * drivers/powerware-mib.c: Remove an erroneous test This was made + test the enumerated values registration in snmp-ups, and should not + have been committed + * data/driver.list.in: HCL: APC ATS AP7724 supported by snmp-ups + These Automatic Transfer Switch should be supported by snmp-ups, + however this was not tested at all Reference: + https://github.com/networkupstools/nut/issues/260 + * NEWS, UPGRADING: Update for release 2.7.4 + * drivers/Makefile.am, drivers/apc-ats-mib.c, drivers/apc-ats-mib.h, + drivers/snmp-ups.c: snmp-ups: support APC Automatic Transfer Switch + Following the recent extension of NUT scope and variable namespace, + to support Automatic Transfer Switch (ATS), implement SNMP support + for APC ATS (with help from "maaboo" through github) Reference: + https://github.com/networkupstools/nut/issues/260 + +2016-03-04 Arnaud Quette + + * drivers/baytech-mib.c, drivers/bestpower-mib.c, drivers/compaq- + mib.c, drivers/cyberpower-mib.c, drivers/eaton-mib.c, drivers/mge- + mib.c, drivers/netvision-mib.c, drivers/powerware-mib.c, drivers + /raritan-pdu-mib.c: snmp-ups: fix mib2nut structures Non existent + OIDs, for testing MIB selection, must be expressed as NULL and not + as empty string ("") for the algorithm to work + +2016-03-03 Daniele Pezzini + + * docs/download.txt: docs: update several download links + +2016-03-03 Arnaud Quette + + * docs/man/upsrw.txt, docs/net-protocol.txt: Clarification on NUMBER + type float values Clarify a bit more documentation on how to + express float values, when using upsrw. That is to say, using + decimal (base 10) english-based representation, so using a dot, in + non-scientific notation. So hexadecimal, exponents, and comma for + thousands separator are forbiden + * clients/upsrw.c, docs/net-protocol.txt, server/netget.c: Prefer + NUMBER to NUMERIC for variable type As per discussion on the + Github pull request, NUMBER would be more suitable than NUMERIC + +2015-11-22 Daniele Pezzini + + * drivers/nutdrv_qx.c: nutdrv_qx: increase timeouts in 'sgs' USB + subdriver Apparently the previously used timeouts in the 'sgs' USB + subdriver were not always enough, so increase them. + +2015-11-11 Daniele Pezzini + + * data/driver.list.in: HCL: various TS Shara UPSes supported by + nutdrv_qx Protocol: 'megatec' USB subdriver: 'sgs' + * drivers/nutdrv_qx.c: nutdrv_qx: make sure 'sgs' USB subdriver uses + only what it reads Since, in 'sgs' USB subdriver, we read only 8 + bytes at a time and we expect the first byte to tell us the length + of the data that follows, make sure we don't use more than what we + read from the device in case the first byte is not what we expect + it to be. + +2015-03-04 Daniele Pezzini + + * drivers/nutdrv_qx.c: nutdrv_qx: increase verbosity of 'sgs' USB + subdriver In 'sgs' USB subdriver: - be more verbose when + debugging, - always print the return code when dealing with an + error. + +2014-01-31 Daniele Pezzini + + * docs/man/nutdrv_qx.txt: nutdrv_qx: update man page for new 'sgs' + USB subdriver + +2014-01-31 Ronaldo Yamada + + * drivers/nutdrv_qx.c: nutdrv_qx: add new 'sgs' USB subdriver to + support TS Shara units + +2016-03-02 Arnaud Quette + + * data/driver.list.in: HCL: added Eaton Powerware 9125-5000g + Supported with the additional USB card, with the bcmxcp_usb driver + * docs/man/upsrw.txt, docs/net-protocol.txt: Clarification on NUMERIC + type float values Clarify documentation on how to express float + values, when using upsrw. That is to say, using decimal english- + based representation, so using a dot + * drivers/mge-xml.c: netxml-ups: fix Eaton XML published data Some + raw protocol data were wrongly published, and are now commented. + Also add some R/W flags to ambient thresholds Closes: + https://github.com/networkupstools/nut/issues/201 + * tools/nut-scanner/nut-scanner.c: nut-scanner: fix thread attachment + Add a test to have the right thread waiting for the scan to be + complete (patch from Michal Hlavinka, Red Hat) + * configure.ac, tools/nut-scanner/nutscan-init.c, tools/nut- + scanner/scan_avahi.c, tools/nut-scanner/scan_ipmi.c, tools/nut- + scanner/scan_nut.c, tools/nut-scanner/scan_snmp.c, tools/nut- + scanner/scan_usb.c, tools/nut-scanner/scan_xml_http.c: nut-scanner: + don't depend on development libraries nut-scanner was previously + trying to use directly libXXX.so (libusb-0.1, libfreeipmi, + libnetsnmp, libavahi-client, libneon, libupsclient}. However, these + files are generally provided by the development packages. nut- + scanner now tries to look at some known paths, including the one + provided through --libdir, to find the correct libraries Closes: + https://github.com/networkupstools/nut/issues/233 + +2016-03-01 Arnaud Quette + + * clients/upsrw.c, docs/net-protocol.txt, server/netget.c: Default to + type NUMERIC for variables Any variable that is not STRING, RANGE + or ENUM is just a simple numeric value. The protocol documentation + (net-protocol.txt) was previously stating that "The default , + when omitted, is integer." which was not fully true, since a + variable could also be a float. Hence, the wording was changed to + advertise this, and that each driver is then responsible for + handling values as either integer or float. Moreover, instead of + returning a TYPE "UNKNOWN", return "NUMERIC", which is more + suitable, and aligned with the NUT protocol specification + * tools/nut-snmpinfo.py: SNMP subdriver generator: fix output + formatting + * tools/nut-snmpinfo.py: SNMP subdriver generator: discard commented + lines Discard any commented mib2nut_info_t declaration, which + should thus not be taken into account + +2016-02-26 Arnaud Quette + + * data/driver.list.in, drivers/Makefile.am, drivers/eaton-ats-mib.c, + drivers/eaton-ats-mib.h, drivers/snmp-ups.c: snmp-ups: support + Eaton Automatic Transfer Switch Following the recent extension of + NUT scope and variable namespace, to support Automatic Transfer + Switch (ATS), implement SNMP support for Eaton ATS. Note that this + device can also be supported through Eaton XML/PDC (XML over HTTP) + protocol, supported by the NUT netxml-ups driver + * data/cmdvartab, docs/nut-names.txt: Extend namespace for Automatic + Transfer Switch (ATS) Extend NUT namespace to support a new type + of power device: ATS - Automatic Transfer Switch. These devices + are used to setup 2 power systems, such as UPS, to power a single + power supply system, and be able to automatically transfer between + the input sources in case of failure of the primary one. The added + variable are for now limited to 'input.source' and + 'input.source.preferred', but may be extended if needed + +2016-02-25 C Fraire + + * docs/scheduling.txt: Fix docs location of upssched to sbin + +2016-02-25 Arnaud Quette + + * scripts/subdriver/gen-snmp-subdriver.sh: snmp-ups: add the last + missing element in the structure + * drivers/apc-mib.c, drivers/bestpower-mib.c, drivers/compaq-mib.c, + drivers/cyberpower-mib.c, drivers/delta_ups-mib.c, drivers/huawei- + mib.c, drivers/ietf-mib.c, drivers/mge-mib.c, drivers/netvision- + mib.c, drivers/powerware-mib.c, drivers/xppc-mib.c, + scripts/subdriver/gen-snmp-subdriver.sh: snmp-ups: fix values + lookup terminating element The terminating element should really + be NULL, and not the string "NULL", as it was originally done, back + in 2002 + * drivers/snmp-ups.c: snmp-ups: revert order of the NULL/"NULL" test + Fix a segfault when doing first the string comparison test + * drivers/snmp-ups.c: snmp-ups: register values enumerations + Whenever there is a values lookup structure for read/write data, + push the values as enumerations for upsrw + * drivers/snmp-ups.c: snmp-ups: try to lookup values for numeric + elements Numeric elements can also use the value resolution + mechanism + * drivers/snmp-ups.c: snmp-ups: counter test sysOID with a test OID + Some devices have buggy sysOID exposed. Allow to counter test + another OID, to be able to select between different mapping + structures + +2016-02-24 Arnaud Quette + + * scripts/subdriver/gen-snmp-subdriver.sh: SNMP subdriver creation + script: allow sysOID override Allow to use -s to override buggy + sysOID in some device FW. In this case, the sysOID entry in the + mib2nut structure should be set to NULL + +2016-02-11 Arnaud Quette + + * drivers/raritan-pdu-mib.c: snmp-ups: fix macaddr support for + Raritan PDU Raritan MIB was fixed to expose macaddr on + device.macaddr instead of ups.macaddr + * drivers/baytech-mib.c: snmp-ups: fix macaddr support for Baytech + PDU Baytech MIB was fixed to expose macaddr on device.macaddr + instead of ups.macaddr + * drivers/eaton-mib.c: snmp-ups: fix and complete macaddr support for + Eaton Eaton G2 and G3 can now expose the MAC address of the + device, using device.macaddr. Eaton G1 Aphel was fixed to expose + this data on device.macaddr instead of ups.macaddr + * drivers/snmp-ups.c: snmp-ups: add support for hexadecimal octet + strings + * drivers/snmp-ups.c: snmp-ups: fallback for classic MIB detection + If the sysOID matching has failed, then snmp-ups uses ups.model to + get an OID to test. In case ups.model is not available, fallback to + trying to use device.model instead + * docs/images/nut_layering.png, docs/images/nut_layering.svg: Refresh + and complete NUT architecture diagram + +2016-02-08 Arnaud Quette + + * drivers/powerware-mib.c: snmp-ups: extend Eaton 3ph outputSource + values map Add the new status values for xupsOutputSource + (.1.3.6.1.4.1.534.1.4.5.0), that maps to both ups.status and + ups.type + +2016-02-03 Arnaud Quette + + * drivers/powerware-mib.c: snmp-ups: improve support for Eaton 3ph + Improve support for temperature and humidity data, including: - + ups.temperature now available - fixing ambient.temperature + (previously pointing at a wrong OID) - ambient.humidity now + available - the following settings now available: * + ups.temperature.low * ups.temperature.high * ambient.humidity.high + * ambient.humidity.low * ambient.temperature.high * + ambient.temperature.low + +2016-02-01 Daniele Pezzini + + * data/driver.list.in: HCL: various APCUPSD-controlled APC devices + via apcupsd-ups Originally reported by GitHub user @Thermionix. + Reference: https://github.com/networkupstools/nut/pull/215 + +2016-01-31 Charles Lepple + + * docs/man/nutdrv_atcl_usb.txt: man/nutdrv_atcl_usb: point to + nutdrv_qx (fuji) for 0001:0000 Also update best guess for the USB- + to-serial converter situation. + * docs/FAQ.txt: FAQ: udevadm for fixing permissions + +2016-01-30 Charles Lepple + + * drivers/nut-libfreeipmi.c: FreeIPMI: do not split function + arguments with a conditional Alternate approach to suggestion by + Romero B. de S. Malaquias Closes: + https://github.com/networkupstools/nut/pull/250 + +2016-01-24 Charles Lepple + + * docs/config-notes.txt: Documentation: fix formatting Put syntax + examples in verbatim mode, and remove spaces from ends of lines. + * drivers/apc-hid.c: usbhid-ups: handle missing USB strings in APC + code Closes: https://github.com/networkupstools/nut/issues/258 + Might fix: + https://bugs.launchpad.net/ubuntu/+source/nut/+bug/1483615 + +2016-01-23 Charles Lepple + + * data/driver.list.in: HCL: added NHS Laser Senoidal 5000VA Source: + http://article.gmane.org/gmane.comp.monitoring.nut.devel/7123 + Closes: https://github.com/networkupstools/nut/issues/254 + +2016-01-14 Arnaud Quette + + * drivers/snmp-ups.c: snmp-ups: fix staleness detection With some + ePDUs or devices using template for outlet and outlet.group, + communication loss with the device were not detected, due to the + handling mechanism. Simply skipping commands for templates, after + the init time, is sufficient to avoid this issue + +2016-01-05 Arnaud Quette + + * drivers/snmp-ups.c: snmp-ups: improve stale communication recovery + Disable the 10 iterations to retry communicating with stale device. + This was leading up to 10 x 30 seconds, so 5mn, before being able + to get data again + * docs/new-drivers.txt, docs/nut-names.txt: Document + battery.charger.status This will in time replace the historic CHRG + and DISCHRG flags published in ups.status. Closes + https://github.com/networkupstools/nut/issues/196 + +2016-01-03 Charles Lepple + + * data/driver.list.in: HCL: Sweex model P220 via blazer_usb + Reference: https://github.com/networkupstools/nut/issues/251 + +2016-01-04 Arnaud Quette + + * drivers/ietf-mib.c, drivers/ietf-mib.h, drivers/snmp-ups.c: snmp- + ups: add support for Tripplite units on IETF mib These devices + expose ".1.3.6.1.4.1.850.1", which could be supported through this + specific MIB. For now, just link that to the IETF MIB, to provide + a first level of support Reference: + https://github.com/networkupstools/nut/issues/171 + +2015-12-30 Arnaud Quette + + * configure.ac: First stab at checking driver.list.in format + +2015-12-29 Charles Lepple + + * scripts/upower/95-upower-hid.rules: upower: update for AEG + +2015-12-29 Arnaud Quette + + * drivers/powercom.c: Fix the processing of output voltage for KIN + units The processing of output voltage requires to also take into + account the line voltage, as reported by Patrik Dufresne. This may + still need some further adjustments Reference: + https://github.com/networkupstools/nut/issues/187 + * drivers/powercom.c: Fix the processing of input voltage for KIN + units The processing of input voltage requires to also take into + account the line voltage, as reported by Patrik Dufresne. Also bump + the driver version to 0.16, since 0.15 was already used, but not + set Reference: https://github.com/networkupstools/nut/issues/187 + * drivers/mge-hid.c: Fix letter case for AEG USB VendorID The letter + case of this VendorID may be important for generated files, such as + the udev ones (reported by Charles Lepple) + +2015-12-28 Arnaud Quette + + * data/driver.list.in, drivers/mge-hid.c: HCL: AEG PROTECT B / NAS + supported by usbhid-ups Reference: + https://github.com/networkupstools/nut/issues/249 + +2015-12-17 Daniele Pezzini + + * data/driver.list.in: HCL: Legrand Keor Multiplug supported by + nutdrv_qx Reference: + https://github.com/networkupstools/nut/issues/248 + +2015-12-09 Andrey Jr. Melnikov + + * drivers/bcmxcp_usb.c: Don't call usb_close() after reset + +2015-12-08 Andrey Jr. Melnikov + + * drivers/bcmxcp_usb.c: Call usb_reset() when driver unable to claim + device + * drivers/bcmxcp.h, drivers/bcmxcp_usb.c: Refactor get_answer() + routine, make it properly deal with multi-packets responses. Lower + stack usage. + +2015-07-27 Daniele Pezzini + + * common/common.c, common/str.c, drivers/bcmxcp.c, drivers/blazer.c, + drivers/blazer_ser.c, drivers/blazer_usb.c, drivers/libhid.c, + drivers/mge-xml.c, drivers/nutdrv_qx.c, drivers/powerp-bin.c, + drivers/powerp-txt.c, drivers/powerpanel.c, drivers/tripplitesu.c, + drivers/upscode2.c, include/common.h, include/str.h, server/upsd.c, + tools/nut-scanner/scan_usb.c: common: consolidate some string- + related functions Move *trim*() functions from common to str. + Prepend the 'str_' common prefix. Bailout early if string is NULL + or empty. In *trim_m() functions, make sure the string containing + characters to be removed is not NULL and bailout early if empty. + Add new str_trim[_m]() functions to remove both leading and + trailing characters at the same time. Update all the tree + accordingly; versioning where appropriate. + * common/Makefile.am, common/str.c, include/Makefile.am, + include/common.h, include/str.h: common: add some string-related + functions + +2015-11-10 Charles Lepple + + * data/driver.list.in: HCL: Electrys UPS 2500 (nutdrv_qx and + blazer_ser) Closes + https://github.com/networkupstools/nut/issues/241 + * data/driver.list.in: HCL: Eaton E Series DX UPS 1-20 kVA uses + blazer_ser Closes + https://github.com/networkupstools/nut/issues/238 + +2015-11-09 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: add number of outlets in Eaton ePDU + groups + * docs/nut-names.txt: Add a variable for the number of outlets in a + group Added 'outlet.group.n.count' which provides the number of + outlets in the outlet group 'n' + +2015-11-06 Daniele Pezzini + + * drivers/nutdrv_qx_voltronic-qs.c: nutdrv_qx: update 'voltronic-qs' + subdriver Since, for devices supported by 'voltronic-qs' + subdriver, in reality: - invalid commands or queries are echoed + back, - accepted commands are followed by action without any + further reply, update the subdriver interface accordingly. Also: - + change slightly the way we publish protocol as ups.firmware.aux, - + update F's reply examples and some info_type (ratings; + output.frequency) in QX to NUT table to reflect reality, - increase + version number. + +2015-10-19 Daniele Pezzini + + * drivers/nutdrv_qx_voltronic-qs-hex.c: nutdrv_qx: improve 'T' + protocol support in 'voltronic-qs-hex' subdriver Since the last + byte of the reply to the QS query (before the trailing CR) of + devices that implement the 'T' protocol holds in reality ratings + informations (nominal output frequency/voltage and nominal battery + voltage) in its bits, change the 'voltronic-qs-hex' subdriver + accordingly. Also: - change slightly the way we publish protocol as + ups.firmware.aux, - increase version number. + * drivers/nutdrv_qx_voltronic-qs-hex.c: nutdrv_qx: simplify + {in,out}put voltage conversion in 'voltronic-qs-hex' In + 'voltronic-qs-hex' subdriver, instead of calculating separately the + fractional and integer part of input and output voltage, do it at + once. Also, increase version number. + * drivers/nutdrv_qx_voltronic-qs-hex.c: nutdrv_qx: improve protocol + identification in 'voltronic-qs-hex' Since 'V' protocol, in + reality, never happens to use the encoded version of the reply to + the QS query, but it always uses the plain version already + implemented in 'voltronic-qs' subdriver, remove it from the + identification process of 'voltronic-qs-hex' subdriver. Also, + remove some non-significant entries from the testing table and + increase version number. + * drivers/nutdrv_qx_voltronic-qs-hex.c: nutdrv_qx: harmonize + declarations/definitions in 'voltronic-qs-hex' In 'voltronic-qs- + hex' subdriver, the scope of support functions is limited to the + subdriver as rightly stated in forward declarations, so correct + their definitions to reflect that. Also, increase version number. + +2015-10-09 Arnaud Quette + + * docs/nut-qa.txt: Reference Black Duck OpenHUB in QA documentation + Closes networkupstools/nut#192 + +2015-10-08 Arnaud Quette + + * drivers/snmp-ups.c: snmp-ups: also use __func__ for additional + traces + * drivers/powerware-mib.c: powerware-mib: more comments for RFC + device.event Add more comments on the need to RFC device.event for + some data that are currently published under ups.alarm + * drivers/powerware-mib.c: snmp-ups: improve Eaton 3-phase UPS alarms + reporting Eaton 3phase UPS, using the Powerware MIB, can expose + many new alarms. Also use the standard driver "X.YY" versioning, + and bump subdriver release to "0.85" + * drivers/snmp-ups.c, drivers/snmp-ups.h: snmp-ups: fix and improve + the ups.alarms mechanism This mechanism allows to walk a subtree + (array) of alarms, composed of OID references. The object + referenced should not be accessible, but rather when present, this + means that the alarm condition is TRUE. Both ups.status and/or + ups.alarm values can be provided + * drivers/snmp-ups.c: snmp-ups: fix on some snprintf calls Some + snprintf calls are using dynamically allocated variables, which + doesn't work with sizeof + * drivers/snmp-ups.c: snmp-ups: use __func__ in debug messages + * drivers/snmp-ups.c: snmp-ups: nut_snmp_get_oid() returns TRUE on + success + * drivers/snmp-ups.c: snmp-ups: only use snprintf calls instead of + sprintf + * drivers/eaton-mib.c, drivers/snmp-ups.c: snmp-ups: simplify + handling of other alarms outlet, outlet groups and phase alarms + are now using a simplified approach that does not require specific + lookup structure to adapt alarm messages. This applies to Eaton + ePDU G2/G3 + +2015-09-22 Arnaud Quette + + * drivers/snmp-ups.c: snmp-ups: fix a typo error in debug message + Unknown is spelled with an ending N (reported by Evgeny "Jim" + Klimov, from Eaton) + * drivers/snmp-ups.c: snmp-ups: optimize phase number extraction + efficiency Since we know that we are processing an alarm for a + phase "Lx", don't use strchr, but simply index (reported by Evgeny + "Jim" Klimov, from Eaton) + * docs/nut-names.txt, drivers/eaton-mib.c: snmp-ups: use dash- + separator for out-of-range For the sake of coherence with other + status relative to thresholds, "out of range" frequency status now + also use dash as separator, instead of space + * drivers/eaton-mib.c: Fix a spelling error in comments + * drivers/eaton-mib.c: snmp-ups: fix a typo error on Eaton ePDU G2/G3 + MIB Critical is really spelled critical, and not cricital, as used + in the various status thresholds value-lookup structures (reported + by Evgeny "Jim" Klimov, from Eaton) + * data/cmdvartab: Mention the unit for ambient humidity information + Add an explicit mention that ambient information related to + humidity use the "(percent)" unit + * data/cmdvartab, docs/nut-names.txt: Mention the unit for input + voltage information Add an explicit mention that input information + related to voltage use the "Volts (V)" unit + * data/cmdvartab: Mention the unit for ambient temperature + information Add an explicit mention that ambient information + related to temperature use the "degrees C" unit + +2015-09-18 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: add outlet group identifier for + Eaton ePDU Eaton ePDU can now publish the parent group of each + outlet + * docs/nut-names.txt: Extend outlet collection namespace with group + ID An outlet can now publish the group to which it belongs to + * drivers/snmp-ups.c: snmp-ups: complete nut_snmp_get_{str,int} + These methods now allow to get the value of an OID returned by the + source OID (as for the sysOID). In case of failure (non existent + OID), the functions return the last part of the returned OID (ex: + 1.2.3 => 3) + * drivers/snmp-ups.c: snmp-ups: create a nut_snmp_get_oid() function + This method allows to get the value of an OID which is also an OID + (as for the sysOID), without trying to get the value of the pointed + OID. This will allow to use nut_snmp_get_{int,str}() the get the + value of the pointed OID + +2015-09-17 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: outlet groups type handling for + Eaton ePDU Eaton ePDU can now publish the type of outlet group + * docs/nut-names.txt: Extend outlet group collection namespace with + type The type of outlet group can now be published, part of the + new outlet.group data collection + * drivers/eaton-mib.c: snmp-ups: outlet groups commands for Eaton + ePDU Eaton ePDU can now handle commands outlet groups, including + on, off and reboot (cycle) + * drivers/snmp-ups.c: snmp-ups: fix commands handling for outlet + groups The su_instcmd() function of snmp-ups is now adapted to + support outlet groups + * drivers/eaton-mib.c: Advanced outlets groups alarm handling for + Eaton ePDU Eaton ePDU can now handle alarms on outlets groups, for + voltage and current, relative to the configured thresholds + * drivers/snmp-ups.c: snmp-ups: improvements for outlet groups and + alarms Improve the code for general template management, including + outlets and outlets groups for now, and add alarm management for + outlet groups, the same way as for outlets + +2015-09-16 Arnaud Quette + + * drivers/snmp-ups.c: snmp-ups: fix set variable for outlet groups + The setvar() function of snmp-ups is now adapted to support outlet + groups + * drivers/eaton-mib.c: snmp-ups: outlet groups handling for Eaton + ePDU Eaton ePDU can now handle outlet groups, including voltage + and current (with thresholds and status relative to the configured + thresholds), along with power and realpower. A subsequent commit + will address the alarms, settings and commands. Bump subdriver + version to 0.30 + * drivers/snmp-ups.c: snmp-ups: update debug message The template + guestimation function name was changed, but the debug message was + left with the old function name + +2015-09-15 Arnaud Quette + + * docs/nut-names.txt: Extend NUT namespace with outlet.group + collection A new data collection, called "outlet.group", is now + available. It provides grouped management for a set of outlets. The + same principles and data than the outlet collection apply to + outlet.group + * drivers/snmp-ups.c, drivers/snmp-ups.h: snmp-ups: adapt template + mechanisms for outlet groups The template handling mechanisms, + originally created for outlets, is now adapted to also manage + outlet groups + +2015-09-14 root + + * docs/nut-names.txt: Add a note on the outlet.count variable + +2015-09-14 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: add nominal input current for Eaton + ePDU snmp-ups now provides input.[Lx.]current.nominal for Eaton + ePDU G2/G3, both for 1phase and 3phase + * drivers/eaton-mib.c: snmp-ups: better input.power handling for + Eaton ePDUs Improve the way we declare and process input.power, as + previously done for input.realpower, in order to address the + variations between Eaton ePDUs G2 and G3 + +2015-09-11 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: publish part number for Eaton ePDU + device.part was standardized in NUT namespace, so enable the + declaration for Eaton ePDU + * drivers/eaton-mib.c: snmp-ups: 3-phase alarm handling for Eaton + ePDU Eaton ePDU can now handle alarms on 3-phase, currently + limited to voltage and current, relative to the configured + thresholds + * drivers/snmp-ups.c: snmp-ups: implement 3-phase alarm handling + snmp-ups now allows to publish 3-phase alarms in ups.alarm, the + same way as with outlet. Declaration of such alarms are done using + "Lx.alarm". info_lkp_t structures messages are shared templates + with outlets, and use the string formats to include the context + (outlet or phase) and the number (of the outlet or phase) in alarm + messages. These alarms are then published in "ups.alarm", with the + standard mechanism for alarm publication + * docs/nut-names.txt: Extend 3-phase collection namespace with alarms + 3-phase data collection now allows to specify alarms, the same way + than with the outlet collection ("outlet.n.alarm"), but using + "Lx.alarm" (for example "L1.alarm"). These alarms are then + published in "ups.alarm", with the standard mechanism for alarm + publication + * drivers/eaton-mib.c: Advanced threshold handling for Eaton 3-phase + ePDU Eaton ePDU can now handle warning and critical thresholds + settings and status for input voltage and current on 3-phase units. + Alarms are however still to be implement + * docs/nut-names.txt: Extend 3-phase collection namespace with + threshold 3-phase data collection now allows to specify low / high + warning and critical thresholds for voltage and current. Status + relative to the thresholds also exist for these data + +2015-09-07 Arnaud Quette + + * drivers/snmp-ups.c, drivers/snmp-ups.h: snmp-ups: fix loss of + precision when setting values su_setvar() was losing precision + when converting and casting the provided values to send to the SNMP + agent. As an example, with an OID in millivolt (multiplier set to + 0.001), when providing 238 (V) using upsrw, the value sent to the + SNMP agent was 237999, so leaking 0.1 volt + +2015-09-04 Arnaud Quette + + * drivers/dstate.c: Extend ups.alarm internal buffer to 1024 chars + Currently, ups.alarm can hold up to 256 chars to expose alarms. + With the recent outlet alarms handling addition, the buffer may + quickly be to small. Thus, increase to 1024, which may still not + be sufficient but already provides a bit more room + * drivers/eaton-mib.c: snmp-ups: outlet alarm handling for Eaton ePDU + Eaton ePDU can now handle alarms on outlets, currently limited to + outlet voltage and current, relative to the configured thresholds + * drivers/snmp-ups.c: snmp-ups: implement outlets / PDU alarm + handling snmp-ups now allows to publish outlets and PDU alarms in + ups.alarm, the same way as with ups.status. Declaration of such + alarms are done using the outlet template mechanism + ("outlet.%i.alarm"). info_lkp_t structures messages can also use + the string formats to include the outlet number in alarm messages. + These alarms are then published in "ups.alarm", with the standard + mechanism for alarm publication + * docs/nut-names.txt: Extend outlet collection namespace with alarms + Outlet data collection now allows to specify alarms, using the + template definitions ("outlet.n.alarm"). These alarms are then + published in "ups.alarm", with the standard mechanism for alarm + publication + +2015-09-02 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: outlet threshold handling for Eaton + ePDU Eaton ePDU can now handle warning and critical thresholds + settings and status for outlet voltage and current + * docs/nut-names.txt: Extend outlet collection namespace with + threshold Outlet data collection now allows to specify low / high + warning and critical thresholds for voltage and current. Status + relative to the thresholds also exist for these data + +2015-09-01 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: alarms handling for Eaton ePDU + Eaton ePDU can now publish alarms, related to input status + (voltage, frequency and current) and ambient status (temperature + and humidity). Note that alarms are still published under + ups.alarms, though these should belong to either pdu.alarms or + better device.alarms + * drivers/eaton-mib.c: Advanced input threshold handling for Eaton + ePDU Eaton ePDU can now handle warning and critical thresholds + settings and status for input voltage and current, along with the + frequency status + * data/cmdvartab, docs/nut-names.txt: Extend input collection + namespace with threshold Input data collection now allows to + specify low / high warning and critical thresholds for voltage and + current. Status relative to the thresholds also exist for these + data, and for the frequency + +2015-08-31 Arnaud Quette + + * drivers/eaton-mib.c: snmp-ups: ambient dry contacts support for + Eaton ePDU Eaton ambient modules, connected on ePDU, now publish + the status of the connected dry contacts sensors + * data/cmdvartab, docs/nut-names.txt: Extend ambient collection + namespace with dry contacts Ambient data collection now allow to + specify dry contacts sensor status + * drivers/eaton-mib.c: snmp-ups: fix Eaton Pulizzi Switched PDU + multiplier As per the previous commit, to well handle integer RW + variables + * drivers/eaton-mib.c: snmp-ups: ambient threshold handling for Eaton + ePDU Eaton ePDU can now handle warning and critical thresholds and + status for both humidity and temperature + * data/cmdvartab, docs/nut-names.txt: Extend ambient collection + namespace with threshold Ambient data collection now allow to + specify warning and critical thresholds + * drivers/eaton-mib.c: snmp-ups: publish presence of Eaton ambient + sensor Publish the actual presence of ambient sensor for Eaton + ePDU G2 and G3 + * data/cmdvartab, docs/nut-names.txt: Publish the actual presence of + an ambient sensor A new data was created (ambient.present) to + publish the actual presence of an ambient sensor + +2015-10-06 Charles Lepple + + * data/driver.list.in: HCL: Asium P700, Micropower LCD 1000 and Eaton + 5E1100iUSB + +2015-10-06 Daniele Pezzini + + * data/driver.list.in: HCL: LYONN CTB-800V supported by nutdrv_qx + Protocol: 'voltronic-qs-hex' Reference: + https://github.com/networkupstools/nut/pull/230 + +2015-08-22 Mariano + + * drivers/nutdrv_qx_voltronic-qs-hex.c: nutdrv_qx: add support for + LYONN CTB-800V Small protocol validation change in 'voltronic-qs- + hex' subdriver to add support for the protocol used by the LYONN + CTB-800V UPS. + +2015-09-28 Arnaud Quette + + * docs/new-drivers.txt: Fix spacing error + +2015-09-22 Charles Lepple + + * drivers/solis.c, drivers/solis.h: solis: remove additional warnings + The "Waiting" flag is always zero, and several other variables were + not used. + * drivers/solis.c, drivers/solis.h: solis: clean up warnings Comment + out unused constants, and add 'static' and 'const' wherever + possible. + +2015-09-20 Charles Lepple + + * drivers/Makefile.am, drivers/solis.c: solis: math fixes As + mentioned here: https://github.com/networkupstools/nut/pull/235 + +2015-09-19 bsalvador + + * drivers/solis.c, drivers/solis.h: solis: patch for Microsol Back- + Ups BZ1200-BR patch for correct reading for Microsol Back-Ups + BZ1200-BR (rebased onto solis_debug branch, and cleaned up + whitespace. -- CFL) Closes + https://github.com/networkupstools/nut/pull/235 and Closes + https://github.com/networkupstools/nut/pull/236 + +2015-09-16 Arnaud Quette + + * data/driver.list.in, docs/man/snmp-ups.txt, drivers/powerware- + mib.c, drivers/powerware-mib.h, drivers/snmp-ups.c: snmp-ups: add + Eaton Power Xpert Gateway UPS Card This newer generation of SNMP + card is used for BladeUPS or other UPS, and is serving the same + XUPS MIB, as in the "pw" subdriver + * scripts/subdriver/gen-snmp-subdriver.sh: Update SNMP subdriver + generation script Complete the documentation, by adding some notes + and examples ; Fix the MIBs directories list and the "keep + temporary files" option + +2015-09-11 Arnaud Quette + + * drivers/snmp-ups.c: Improve log/debug output trace + +2015-09-08 Charles Lepple + + * drivers/solis.c: solis: resync with end-of-packet character (0.64) + Suggested by @rpvelloso in https://github.com/networkupstools/nut/i + ssues/231#issuecomment-134795747 Note that the driver could + possibly get out-of-sync after initial detection. + +2015-09-07 Charles Lepple + + * docs/man/macosx-ups.txt, drivers/macosx-ups.c: macosx-ups: + gracefully handle disconnection of UPS Tested on 10.9.5 and + 10.10.5. Returns "data stale" when UPS disappears. + +2015-09-07 Arnaud Quette + + * drivers/powerware-mib.c: Bump Powerware SNMP subdriver version + +2015-09-04 Charles Lepple + + * Makefile.am, docs/configure.txt, docs/new-clients.txt, tools/nut- + scanner/README: doc: correct remaining `--with-lib` references + Credit: Paul Vermeer + +2015-09-01 Arnaud Quette + + * drivers/snmp-ups.h: Minor updates to TODO comments + * drivers/snmp-ups.c: Implement ups.alarm for SNMP snmp-ups now + allows to publish alarms in ups.alarm, the same way as with + ups.status + +2015-08-31 Arnaud Quette + + * drivers/snmp-ups.c: Proper handling of integer RW variables RW + variables were previously supposed to always be strings. Thus, the + multiplier (using the info_len field) was not applied. Also allow + setting float values, not only integer + * drivers/snmp-ups.c, drivers/snmp-ups.h: Fix default SNMP retries + and timeout The previous patch was using the default values from + Net-SNMP, which are set to -1. When the user was not providing + overriden values, this was causing the driver to not be able to + establish the communication with the device. The default values are + now fixed, as per documented (i.e. 5 retries and timeout of 1 + second). Also bump the driver version to 0.74 + * docs/man/ups.conf.txt, drivers/dstate.c: Make more obvious the + socket write failure Document the error that require the use of + the 'synchronous' flag. Also use debug level 1 instead of 2 for the + debug message + +2015-08-23 Charles Lepple + + * drivers/solis.c: solis: Add upsdebug*() and upslogx() calls for + diagnostics + +2015-08-18 Kenny Root + + * drivers/powerware-mib.c: Add ups.start.auto for Powerware SNMP Use + the IETF UPS MIB to indicate to Powerware devices that it should + restart when mains power is applied. + * drivers/powerware-mib.c: Fix some indentation problems in PowerWare + SNMP + * drivers/powerware-mib.c: Add shutdown.return for Powerware SNMP + The Powerware MIB supports the concept of shutting down with a + delay and then returning when line power is restored. The delay is + set to 0 seconds currently. + * drivers/powerware-mib.c: Add load.{off,on}.delay for Powerware SNMP + The commands to shut down with delay have existed since the first + version of the Powerware MIB so add the newer commands + "load.off.delay" and "load.on.delay" to aid in shutdown scripts. + +2015-08-07 Arnaud Quette + + * drivers/dummy-ups.c, drivers/dummy-ups.h: Fix dummy-ups for + external value changes dummy-ups allow to change the values of the + publicated variables through the standard upsrw tool. This method + is handy to script value changes, in a controlled way, compared to + the dynamic version (using the TIMER keyword in .dev files), which + changes the values in a non controlled way. Bump driver version to + 0.14 + * m4/nut_check_libnss.m4: Fully check for a working Mozilla NSS + Rework the NSS tests so that just having runtime libraries + installed is not enough. Moreover, since GNU libc6 also provides a + nss.h header, the test now checks for both nss.h and ssl.h Closes + networkupstools/nut#184 + * docs/download.txt: Fix Red Hat / Fedora packages repository URL + +2015-08-03 Tomas Halman + + * clients/nutclient.cpp: Problem: nutclient library sometimes reads + socket closed by server. Solution: proper read return value + evaluation + +2015-08-04 Arnaud Quette + + * tools/nut-scanner/scan_snmp.c: Fix a crash on a 2nd call to + libnutscan on behalf of Tomas Halman, from Eaton Opensource Team + +2015-07-24 Nash Kaminski + + * drivers/tripplitesu.c: tripplitesu: Fix initialization when + tripplite firmware is buggy With some Tripplite SU1000RT2U (and + possibly more) UPS's, a firmware bug causes a malformed response to + the very first command that is sent after the serial port is opened + following a warm or cold boot of the system. My theory is that this + related to either the RS232 data lines or handshaking lines being + pulled high once the server's UART is powered however I have not + determined precisely if this is related to the data line being + pulled high or the handshaking lines being asserted. However, I + have been able to consistently reproduce the issue where the driver + fails to start on the first attempt after a cold/warm boot across 3 + different machines and 2 SU1000RT2U UPS's. To workaround this, the + initial enumeration is repeated a 2nd time after 300ms(to allow all + garbage data to arrive) if the first attempt fails, which allows + the driver to consistently startup successfully on the 1st attempt. + Closes networkupstools/nut#220 + +2015-07-24 Tim Smith + + * INSTALL.nut: Spelling fixes Spelling fixes and capitalization of + SUSE + +2015-07-23 Arnaud Quette + + * scripts/augeas/nutupsconf.aug.tpl: Update Augeas lens for ups.conf + Add the various missing global directives and ups fields + +2015-07-20 Daniele Pezzini + + * data/driver.list.in: HCL: fix case and spacing + +2015-07-18 Daniele Pezzini + + * drivers/nutdrv_qx.c: nutdrv_qx: when targeting 'UPS No Ack' + consider also the trailing CR In 'fabula' and 'krauler' USB + subdrivers, take into account also the trailing CR in the reply + while looking for a 'UPS No Ack'. + * drivers/nutdrv_qx.c: nutdrv_qx: stay true to return code in + 'fabula' USB subdriver In 'fabula' USB subdriver, when reading + 'UPS No Ack' from device, since we already mimic a timeout, also + empty the reply. + +2015-07-11 Charles Lepple + + * data/driver.list.in: HCL: Fideltronic INIGO Viper 1200 supported by + nutdrv_qx + +2015-07-02 Charles Lepple + + * drivers/usbhid-ups.c: usbhid-ups: bump version to 0.41 Both the + eaton_dual_reportdesc and usbhid_ups_input_vs_feature branches + claimed version 0.40, so let's disambiguate the merged version. + +2015-07-02 Arnaud Quette + + * drivers/libhid.c: Add a debug trace for the number of HID objects + found + * drivers/hidtypes.h: Fix testing typo MAX_REPORT is really 500 (HID + objects), not 50! + * drivers/hidparser.c: Report when there are further unprocessed HID + objects Following the last commits, and especially the MAX_REPORT + one, warn whenever there are remaining HID objects that were not + processed. This may serve + * drivers/hidtypes.h: Increase the maximum number of HID objects The + previous value (300) was causing a trim of the remaining objects. + Increase the value to 500, which should give a bit of time + * drivers/libshut.c, drivers/libshut.h, drivers/libusb.c, drivers + /usb-common.h, drivers/usbhid-ups.c: Add support for Eaton dual HID + report descriptor All devices use HID descriptor at index 0. + However, some newer Eaton units have a light HID descriptor at + index 0, and the full version is at index 1 (in which case, + bcdDevice == 0x0202). This dual report descriptor approach is due + to the fact that the main report descriptor is now too heavy, and + cause some BIOS to hang. A light version is thus provided at the + default index, solving this BIOS issues + +2015-06-27 Charles Lepple + + * drivers/macosx-ups.c: macosx-ups: fix for 10.10 (Yosemite); v1.1 + In OS X 10.9 and earlier, IOPSGetPowerSourcesInfo() returned a + CFDictionary. In 10.10 it returns a CFArray. Programmers are + supposed to use IOPSGetPowerSourceDescription() to gloss over this + distinction. However, this does not make it easy to distinguish + between a laptop battery and an UPS. So the "port" driver option no + longer has any effect. https://developer.apple.com/library/mac/doc + umentation/IOKit/Reference/IOPowerSources_header_reference/#//apple + _ref/c/func/IOPSGetPowerSourceDescription + +2015-06-22 Arnaud Quette + + * scripts/upower/95-upower-hid.rules, tools/nut-usbinfo.pl: Update + UPower HID rules and generator + +2015-06-11 Charles Lepple + + * drivers/usbhid-ups.c: usbhid-ups.c: fall back to HID Input type if + not a Feature + +2015-06-07 Charles Lepple + + * drivers/tripplite-hid.c: tripplite-hid.c: device.part is static + (version 0.82) + +2015-06-04 Daniele Pezzini + + * drivers/nutdrv_qx.c: nutdrv_qx: make sure processed item's + boundaries are not wrong + +2015-04-26 Nick Mayerhofer + + * docs/nutdrv_qx-subdrivers.txt, drivers/nutdrv_qx.c, + drivers/nutdrv_qx.h: nutdrv_qx: improve documentation for some + methods + +2015-06-04 Daniele Pezzini + + * docs/nutdrv_qx-subdrivers.txt, drivers/nutdrv_qx.c, + drivers/nutdrv_qx.h: nutdrv_qx: remove redundant comments and + update docs + +2015-04-28 Nick Mayerhofer + + * drivers/nutdrv_qx_voltronic.c: nutdrv_qx: move var declaration in + 'voltronic' subdriver Move variable declaration to fulfill + condition '3.3. Portability' of the developer guide. Bump version. + * drivers/libhid.c: libhid: replace "flush loop" with memset Move to + the C way of setting memory (memset), replacing a for loop with a + few anti-patterns in it: - for (...; ; i++) - for (...; i < + MAGIC_NUMBER; ...) - for (...) array[i] = 0 + +2015-05-18 Daniele Pezzini + + * docs/nutdrv_qx-subdrivers.txt, drivers/nutdrv_qx.c, + drivers/nutdrv_qx.h, drivers/nutdrv_qx_bestups.c, + drivers/nutdrv_qx_mecer.c, drivers/nutdrv_qx_megatec-old.c, + drivers/nutdrv_qx_megatec.c, drivers/nutdrv_qx_mustek.c, + drivers/nutdrv_qx_q1.c, drivers/nutdrv_qx_voltronic-qs-hex.c, + drivers/nutdrv_qx_voltronic-qs.c, drivers/nutdrv_qx_voltronic.c, + drivers/nutdrv_qx_zinto.c: nutdrv_qx: give subdrivers a last chance + to process the command Add (and document) a new function + ('preprocess_command()') to preprocess the command to be sent to + the device, just before the actual sending and, in case of instant + commands/setvars, after the 'preprocess()' function has been + triggered (if appropriate). As an example, this function can be + useful to add to all commands (both queries and instant + commands/setvars) a CRC or to fill the command of a query with some + data. Also, in qx_process(), address buf size vs item->answer size + earlier. Update all subdrivers accordingly, bump versions. + +2015-06-01 Arnaud Quette + + * docs/man/snmp-ups.txt, drivers/snmp-ups.c, drivers/snmp-ups.h: + Provide access to Net-SNMP timeout and retries Two new extra + arguments are now available to allow overriding Net-SNMP number of + retries (snmp_retries) and timeout per retry (snmp_timeout). These + respectively maps to snmpcmd "-r retries" and "-t timeout" + +2015-05-29 Arnaud Quette + + * scripts/upower/95-upower-hid.rules: Update UPower HID rules + * tools/nut-usbinfo.pl: Fix UPower device matching for recent kernels + As per the UPower patch below referenced, hiddev* devices now have + class "usbmisc", rather than "usb". See + http://cgit.freedesktop.org/upower/commit/rules/95-upower- + hid.rules?id=9f31068707fc79744961cea7258b0eb262effbf1 + +2015-05-28 Arnaud Quette + + * tools/nut-scanner/nut-scan.h, tools/nut-scanner/nut-scanner.c, + tools/nut-scanner/nutscan-device.c, tools/nut-scanner/nutscan- + device.h, tools/nut-scanner/nutscan-display.c, tools/nut-scanner + /nutscan-init.c, tools/nut-scanner/nutscan-init.h, tools/nut- + scanner/nutscan-ip.c, tools/nut-scanner/nutscan-ip.h, tools/nut- + scanner/nutscan-serial.c, tools/nut-scanner/nutscan-serial.h, tools + /nut-scanner/scan_avahi.c, tools/nut-scanner/scan_eaton_serial.c, + tools/nut-scanner/scan_ipmi.c, tools/nut-scanner/scan_nut.c, tools + /nut-scanner/scan_snmp.c, tools/nut-scanner/scan_usb.c, tools/nut- + scanner/scan_xml_http.c: Fix legal information on source-code + headers Copyright and author were not mentioned as it should be. + Most of the nut-scanner copyright belongs to EATON, apart from few + parts. Files descriptions are now also in Doxygen format + +2015-05-18 Daniele Pezzini + + * docs/nutdrv_qx-subdrivers.txt, drivers/nutdrv_qx.c, + drivers/nutdrv_qx.h, drivers/nutdrv_qx_bestups.c, drivers + /nutdrv_qx_blazer-common.c, drivers/nutdrv_qx_blazer-common.h, + drivers/nutdrv_qx_mecer.c, drivers/nutdrv_qx_megatec-old.c, + drivers/nutdrv_qx_megatec.c, drivers/nutdrv_qx_mustek.c, + drivers/nutdrv_qx_q1.c, drivers/nutdrv_qx_voltronic-qs-hex.c, + drivers/nutdrv_qx_voltronic-qs.c, drivers/nutdrv_qx_voltronic.c, + drivers/nutdrv_qx_zinto.c: nutdrv_qx: make preprocessed value's + size_t a const There's no need to intervene on the passed-to-the- + function value of a preprocessed value's size_t, so clarify it is a + const. Update all subdrivers accordingly, bump versions. + * drivers/nutdrv_qx.c: nutdrv_qx: make sure an answer is not reused + if preprocess_answer() fails If an item's preprocess_answer() + function fails, the answer should not be considered valid and + inherited by the following items with the same command. Therefore, + on failure, clear the answer so that the following items are forced + to query the device and preprocess the answer anew, if appropriate. + +2015-05-13 Arnaud Quette + + * docs/download.txt: Update NUT packages for Windows to 2.6.5-6 + +2015-05-07 Arnaud Quette + + * scripts/systemd/nut-server.service.in: Restore systemd relationship + with nut-driver service The Requires directive from nut-server to + nut-driver was previously removed, since it was preventing upsd + from starting whenever one or more drivers, among several, was + failing to start. Use the Wants directive, a weaker version of + Requires, which will start upsd even if the nut-driver unit fails + to start. closes https://github.com/networkupstools/nut/issues/200 + +2015-04-23 Arnaud Quette + + * Makefile.am: Cleanup GPG signature before generation + 2015-04-22 Arnaud Quette + * configure.ac: bump version back to 2.7.3.1 * configure.ac: Restore version 2.7.3 for release * docs/security.txt: Missing link reference update The filename of the previous GPG release key was not updated, leading to pointing @@ -146,6 +1231,17 @@ historic CHRG and DISCHRG flags are not published anymore in ups.status +2015-03-26 Stuart Henderson + + * data/driver.list.in, docs/man/snmp-ups.txt, docs/snmp- + subdrivers.txt, drivers/Makefile.am, drivers/huawei-mib.c, drivers + /huawei-mib.h, drivers/snmp-ups.c: snmp-ups: new subdriver for + Huawei "Hi, the [commit] below adds a new subdriver for snmp-ups + to support Huawei UPS, based on an observed walk from a UPS5000-E + with a few bits filled in from the MIBs (copy at + http://junkpile.org/HUAWEI_UPS_MIB/)." http://news.gmane.org/find- + root.php?message_id=slrnmh6npf.tg7.stu%40naiad.spacehopper.org + 2015-03-25 Daniele Pezzini * drivers/nutdrv_qx_voltronic.c: nutdrv_qx: add support in @@ -1051,6 +2147,10 @@ * NEWS, UPGRADING, configure.ac: Update for release 2.7.2 Complete the release information for NUT 2.7.2 +2014-04-17 Stephen J. Butler + + * drivers/tripplite-hid.c: Scale for SMART1500LCDT + 2014-04-07 Arnaud Quette * drivers/compaq-mib.c: Fix erroneous status in HP/Compaq SNMP MIB diff --git a/INSTALL.nut b/INSTALL.nut index 160b558..202d1af 100644 --- a/INSTALL.nut +++ b/INSTALL.nut @@ -207,8 +207,8 @@ Debian, Ubuntu and other derivatives NOTE: NUT is packaged and well maintained in these systems. The official Debian packager is part of the NUT Team. -Using your prefered method (apt-get, aptitude, Synaptic, ...), install -the 'nut' package, and optionaly the following: +Using your preferred method (apt-get, aptitude, Synaptic, ...), install +the 'nut' package, and optionally the following: - 'nut-cgi', if you need the CGI (HTML) option, - 'nut-snmp', if you need the snmp-ups driver, @@ -233,32 +233,32 @@ Mandriva NOTE: NUT is packaged and well maintained in these systems. The official Mandriva packager is part of the NUT Team. -Using your prefered method (urpmi, RPMdrake, ...), install one of the two below +Using your preferred method (urpmi, RPMdrake, ...), install one of the two below packages: - 'nut-server' if you have a 'standalone' or 'netserver' installation, - 'nut' if you have a 'netclient' installation. -Optionaly, you can also install the following: +Optionally, you can also install the following: - 'nut-cgi', if you need the CGI (HTML) option, - 'nut-devel', if you need the development files. -[[Suse]] -Suse / Opensuse +[[SUSE]] +SUSE / openSUSE ~~~~~~~~~~~~~~~ NOTE: NUT is packaged and well maintained in these systems. -The official Suse packager is part of the NUT Team. +The official SUSE packager is part of the NUT Team. -Install the 'nut-classic' package, and optionaly the following: +Install the 'nut-classic' package, and optionally the following: - 'nut-drivers-net', if you need the snmp-ups or the netxml-ups drivers, - 'nut-cgi', if you need the CGI (HTML) option, - 'nut-devel', if you need the development files, -NOTE: Suse and Opensuse users can use the +NOTE: SUSE and openSUSE users can use the link:http://software.opensuse.org/search?baseproject=ALL&p=1&q=nut[one-click install method] to install NUT. @@ -270,13 +270,13 @@ Red Hat, Fedora and CentOS NOTE: NUT is packaged and well maintained in these systems. The official Red Hat packager is part of the NUT Team. -Using your prefered method (yum, Add/Remove Software, ...), install one of the +Using your preferred method (yum, Add/Remove Software, ...), install one of the two below packages: - 'nut' if you have a 'standalone' or 'netserver' installation, - 'nut-client' if you have a 'netclient' installation. -Optionaly, you can also install the following: +Optionally, you can also install the following: - 'nut-cgi', if you need the CGI (HTML) option, - 'nut-xml', if you need the netxml-ups driver, @@ -306,7 +306,7 @@ To install it, use the following command: You have to define WITH_NUT_CGI to build the optional CGI scripts. -Optionaly, you can also install the following ports: +Optionally, you can also install the following ports: - sysutils/nut-snmp, for the SNMP driver, - sysutils/nut-usb, for the USB drivers, diff --git a/Makefile.am b/Makefile.am index aebe618..dd9ec33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -56,6 +56,7 @@ ChangeLog: tools/gitlog2changelog.py dummy-stamp # ---------------------------------------------------------------------- # Maintainers targets: distribution signature and hashes dist-sig: + rm -f nut-@PACKAGE_VERSION@.tar.gz.sig gpg --detach-sign nut-@PACKAGE_VERSION@.tar.gz dist-hash: @@ -107,7 +108,7 @@ install-cgi-man install-cgi-conf install-cgi-html: @echo "Use './configure --with-cgi' instead." install-lib: @echo "Error: 'make $@' no longer exists." - @echo "Use './configure --with-lib' instead." + @echo "Use './configure --with-dev' instead." usb build-usb install-usb: @echo "Error: 'make $@' no longer exists." @echo "Use './configure --with-usb' instead." diff --git a/Makefile.in b/Makefile.in index 44ffd6b..6b39990 100644 --- a/Makefile.in +++ b/Makefile.in @@ -273,6 +273,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ @@ -931,6 +932,7 @@ ChangeLog: tools/gitlog2changelog.py dummy-stamp # ---------------------------------------------------------------------- # Maintainers targets: distribution signature and hashes dist-sig: + rm -f nut-@PACKAGE_VERSION@.tar.gz.sig gpg --detach-sign nut-@PACKAGE_VERSION@.tar.gz dist-hash: @@ -976,7 +978,7 @@ install-cgi-man install-cgi-conf install-cgi-html: @echo "Use './configure --with-cgi' instead." install-lib: @echo "Error: 'make $@' no longer exists." - @echo "Use './configure --with-lib' instead." + @echo "Use './configure --with-dev' instead." usb build-usb install-usb: @echo "Error: 'make $@' no longer exists." @echo "Use './configure --with-usb' instead." diff --git a/NEWS b/NEWS index 1e6fbde..216c835 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,124 @@ If you're upgrading from an earlier version, see the UPGRADING file. For a complete and more detailed list of changes, please refer to the ChangeLog file. +--------------------------------------------------------------------------- +Release notes for NUT 2.7.4 - what's new since 2.7.3: + + - New class of device supported: ATS - Automatic Transfer Switch are now + supported in NUT. Eaton ATS are supported, and APC ones should be too. Users + are welcomed to test and provide feedback + + - NUT command and variable naming scheme: + * Document battery.charger.status, which will in time replace the historic + CHRG and DISCHRG flags published in ups.status + * Many extensions to support outlets groups, thresholds / alarms (ambient, + input, output, outlet and outlet.group) + + - support for new devices: + AEG PROTECT B / NAS + APC ATS AP7724 (should be supported) + Asium P700 + Eaton ATS + Eaton 5E 1100iUSB + Eaton E Series DX UPS 1-20 kVA + Eaton Powerware 9125-5000g + Electrys UPS 2500 + Fideltronic INIGO Viper 1200 + Legrand Keor Multiplug + LYONN CTB-800V + Micropower LCD 1000 + NHS Laser Senoidal 5000VA + Sweex model P220 + TS Shara + Various APCUPSD-controlled APC devices + + - snmp-ups: + * Improve automatic detection algorithm + * Provide access to Net-SNMP timeout and retries + * Proper handling of integer RW variables + * Implement support for alarms, through ups.alarm and outlet.n.alarm + * Improve log/debug output trace + * Fix loss of precision when setting values, using upsrw + * Support for outlets group management + * Many improvements and simplification + * Add support for Tripplite units using IETF mib + * Improve communication staleness detection and recovery + * Add devices MAC address publication + * Register values enumerations, when available + * Many improvements and fixes to the SNMP subdriver creation script + + - Eaton: + * 3ph SNMP: + Many improvements to Powerware / XUPS MIB, for data and commands + Add support for Eaton Power Xpert Gateway UPS Card + Improve support for temperature and humidity, including low / high values + Alarms handling + * ePDU (G2 and G3): + Improve support for ambient sensor, including thresholds and dry contacts + Outlet groups handling, including data, thresholds, settings and commands + Alarms handling + * XML/PDC (netxml-ups): + Fix Eaton XML published data + Add some settings (R/W flags) on ambient thresholds + + - bcmxcp_usb: improvements for device claiming and multi-packets responses + + - dummy-ups: allow any variable to be modified + + - libnutclient: Fix for reads when the socket was closed by NUT server + + - macosx-ups: + * fix for 10.10 (Yosemite), v1.1 + * gracefully handle disconnection of UPS (return "data stale") + + - nutdrv_atcl_usb: point to nutdrv_qx (fuji) for 0001:0000 + + - nutdrv_qx: + * Add new 'sgs' USB subdriver to support TS Shara units + * various improvements and simplification, to the code and documentation + + - nut-ipmipsu: improve FreeIPMI support + + - nut-scanner: + * Don't depend on development libraries, by looking at some known paths, + including the one provided through --libdir, to find the correct libraries + * Fix a crash on a 2nd call to libnutscan with SNMP method + + - powercom: fix the processing of input and output voltage for KIN units + + - solis: + * many improvements and cleanup + * resync with end-of-packet character + * fixes for Microsol Back-Ups BZ1200-BR + + - tripplitesu: Fix initialization when tripplite firmware is buggy (for + Tripplite SU1000RT2U and possibly more) + + - usbhid-ups: + * various minor improvements + * support for Eaton UPS with dual HID report descriptor in HID Parser + * handle missing USB strings in APC code + + - SSL support through Mozilla NSS: Rework the NSS tests to ensure that NSS is + actually installed and usable for enabling SSL support in NUT + + - Augeas support: Augeas lens for ups.conf was updated to add various missing + global directives and ups fields + + - scripts/systemd/nut-server.service.in: Restore systemd relationship since it + was preventing upsd from starting whenever one or more drivers, among several, + was failing to start + + - Fix UPower device matching for recent kernels, since hiddev* devices now have + class "usbmisc", rather than "usb" + + - Network protocol information: default to type NUMBER for variables that are + not flagged as STRING . This point is subject to improvements or change in + the next release 2.7.5. Refer to docs/net-protocol.txt for more information + + - As usual, more bugfixes, cleanup and improvements, on both source code + and documentation. + --------------------------------------------------------------------------- Release notes for NUT 2.7.3 - what's new since 2.7.2: @@ -323,7 +441,7 @@ Release notes for NUT 2.6.4 - what's new since 2.6.3: - bestups has also received some care, though users are encouraged to switch to blazer_ser, since bestups will soon be deprecated. - - newmge-shut has been heavilly improved. However, replacement of the + - newmge-shut has been heavily improved. However, replacement of the current mge-shut has been postponed to the next release, due to the CVE issue. diff --git a/UPGRADING b/UPGRADING index 3b14a40..03cf410 100644 --- a/UPGRADING +++ b/UPGRADING @@ -7,6 +7,22 @@ This file lists changes that affect users who installed older versions of this software. When upgrading from an older version, be sure to check this file to see if you need to make changes to your system. +Changes from 2.7.3 to 2.7.4 +--------------------------- + +- scripts/systemd/nut-server.service.in: Restore systemd relationship since it + was preventing upsd from starting whenever one or more drivers, among several, + was failing to start + +- Fix UPower device matching for recent kernels, since hiddev* devices now have + class "usbmisc", rather than "usb" + +- macosx-ups: the "port" driver option no longer has any effect + +- Network protocol information: default to type NUMBER for variables that are + not flagged as STRING . This point is subject to improvements or change in + the next release 2.7.5. Refer to docs/net-protocol.txt for more information + Changes from 2.7.2 to 2.7.3 --------------------------- @@ -191,7 +207,7 @@ automake). Refer to packaging/debian/ for an example of migration. ie not using upsdrvctl. - Developers of external client application using libupsclient are encouraged to rename the "UPSCONN" client structure to "UPSCONN_t" -since the former will disapear by the release of NUT 2.4. +since the former will disappear by the release of NUT 2.4. Changes from 2.0.4 to 2.0.5 --------------------------- diff --git a/clients/Makefile.in b/clients/Makefile.in index 7e58b62..0a7949e 100644 --- a/clients/Makefile.in +++ b/clients/Makefile.in @@ -366,6 +366,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/clients/nutclient.cpp b/clients/nutclient.cpp index dcf0c2d..8304473 100644 --- a/clients/nutclient.cpp +++ b/clients/nutclient.cpp @@ -374,6 +374,11 @@ std::string Socket::read()throw(nut::IOException) // Read new buffer size_t sz = read(&buff, 256); + if(sz==0) + { + disconnect(); + throw nut::IOException("Server closed connection unexpectedly"); + } _buffer.assign(buff, sz); } } diff --git a/clients/upsrw.c b/clients/upsrw.c index 8113690..3a0efb4 100644 --- a/clients/upsrw.c +++ b/clients/upsrw.c @@ -366,6 +366,11 @@ static void do_type(const char *varname) } + if (!strcasecmp(answer[i], "NUMBER")) { + printf("Type: NUMBER\n"); + return; + } + /* ignore this one */ if (!strcasecmp(answer[i], "RW")) { continue; diff --git a/common/Makefile.am b/common/Makefile.am index f85244c..2bfc6e0 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -9,8 +9,8 @@ libparseconf_la_SOURCES = parseconf.c # 'dist', and is only required for actual build, in which case # BUILT_SOURCES (in ../include) will ensure nut_version.h will # be built before anything else -libcommon_la_SOURCES = common.c state.c upsconf.c -libcommonclient_la_SOURCES = common.c state.c +libcommon_la_SOURCES = common.c state.c str.c upsconf.c +libcommonclient_la_SOURCES = common.c state.c str.c # ensure inclusion of local implementation of missing systems functions # using LTLIBOBJS. Refer to configure.in -> AC_REPLACE_FUNCS libcommon_la_LIBADD = libparseconf.la @LTLIBOBJS@ diff --git a/common/Makefile.in b/common/Makefile.in index 6a5149e..8710560 100644 --- a/common/Makefile.in +++ b/common/Makefile.in @@ -82,8 +82,8 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = common -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am strerror.c \ - atexit.c setenv.c snprintf.c $(top_srcdir)/depcomp +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am atexit.c \ + snprintf.c setenv.c strerror.c $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ @@ -114,14 +114,14 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcommon_la_DEPENDENCIES = libparseconf.la @LTLIBOBJS@ -am_libcommon_la_OBJECTS = common.lo state.lo upsconf.lo +am_libcommon_la_OBJECTS = common.lo state.lo str.lo upsconf.lo libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libcommonclient_la_DEPENDENCIES = libparseconf.la @LTLIBOBJS@ -am_libcommonclient_la_OBJECTS = common.lo state.lo +am_libcommonclient_la_OBJECTS = common.lo state.lo str.lo libcommonclient_la_OBJECTS = $(am_libcommonclient_la_OBJECTS) libparseconf_la_LIBADD = am_libparseconf_la_OBJECTS = parseconf.lo @@ -241,6 +241,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ @@ -382,8 +383,8 @@ libparseconf_la_SOURCES = parseconf.c # 'dist', and is only required for actual build, in which case # BUILT_SOURCES (in ../include) will ensure nut_version.h will # be built before anything else -libcommon_la_SOURCES = common.c state.c upsconf.c -libcommonclient_la_SOURCES = common.c state.c +libcommon_la_SOURCES = common.c state.c str.c upsconf.c +libcommonclient_la_SOURCES = common.c state.c str.c # ensure inclusion of local implementation of missing systems functions # using LTLIBOBJS. Refer to configure.in -> AC_REPLACE_FUNCS libcommon_la_LIBADD = libparseconf.la @LTLIBOBJS@ @@ -456,6 +457,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parseconf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsconf.Plo@am__quote@ .c.o: diff --git a/common/common.c b/common/common.c index d7c74d3..6637113 100644 --- a/common/common.c +++ b/common/common.c @@ -584,47 +584,6 @@ char *xstrdup(const char *string) return p; } -/* modify in - strip all trailing instances of */ -char *rtrim(char *in, const char sep) -{ - char seps[2] = { sep, '\0' }; - - return rtrim_m(in, seps); -} - -/* modify in - strip all trailing instances of each char in */ -char *rtrim_m(char *in, const char *seps) -{ - char *p; - - if (in && strlen(in)) { - p = &in[strlen(in) - 1]; - - while ((p >= in) && (strchr(seps, *p) != NULL)) - *p-- = '\0'; - } - return in; -} - -/* modify in - strip all leading instances of */ -char* ltrim(char *in, const char sep) -{ - char seps[2] = { sep, '\0' }; - - return ltrim_m(in, seps); -} - -/* modify in - strip all leading instances of each char in */ -char* ltrim_m(char *in, const char *seps) -{ - if (in && strlen(in)) { - while ((*in != '\0') && (strchr(seps, *in) != NULL)) - memmove(in, in + 1, strlen(in)); - } - - return in; -} - /* Read up to buflen bytes from fd and return the number of bytes read. If no data is available within d_sec + d_usec, return 0. On error, a value < 0 is returned (errno indicates error). */ diff --git a/common/str.c b/common/str.c new file mode 100644 index 0000000..092efcf --- /dev/null +++ b/common/str.c @@ -0,0 +1,607 @@ +/* str.c - Common string-related functions + * + * Copyright (C) + * 2000 Russell Kroll + * 2015 Daniele Pezzini + * + * 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 +#include + +#include "str.h" + +char *str_trim(char *string, const char character) +{ + return str_rtrim(str_ltrim(string, character), character); +} + +char *str_trim_m(char *string, const char *characters) +{ + return str_rtrim_m(str_ltrim_m(string, characters), characters); +} + +char *str_ltrim(char *string, const char character) +{ + char characters[2] = { character, '\0' }; + + return str_ltrim_m(string, characters); +} + +char *str_ltrim_m(char *string, const char *characters) +{ + if ( + string == NULL || + *string == '\0' || + characters == NULL || + *characters == '\0' + ) + return string; + + while ( + *string != '\0' && + strchr(characters, *string) != NULL + ) + memmove(string, string + 1, strlen(string)); + + return string; +} + +char *str_rtrim(char *string, const char character) +{ + char characters[2] = { character, '\0' }; + + return str_rtrim_m(string, characters); +} + +char *str_rtrim_m(char *string, const char *characters) +{ + char *ptr; + + if ( + string == NULL || + *string == '\0' || + characters == NULL || + *characters == '\0' + ) + return string; + + ptr = &string[strlen(string) - 1]; + + while ( + ptr >= string && + strchr(characters, *ptr) != NULL + ) + *ptr-- = '\0'; + + return string; +} + +char *str_trim_space(char *string) +{ + return str_rtrim_space(str_ltrim_space(string)); +} + +char *str_ltrim_space(char *string) +{ + if ( + string == NULL || + *string == '\0' + ) + return string; + + while ( + *string != '\0' && + isspace(*string) + ) + memmove(string, string + 1, strlen(string)); + + return string; +} + +char *str_rtrim_space(char *string) +{ + char *ptr; + + if ( + string == NULL || + *string == '\0' + ) + return string; + + ptr = &string[strlen(string) - 1]; + + while ( + ptr >= string && + isspace(*ptr) + ) + *ptr-- = '\0'; + + return string; +} + +int str_is_short(const char *string, const int base) +{ + short number; + + return str_to_short(string, &number, base); +} + +int str_is_short_strict(const char *string, const int base) +{ + short number; + + return str_to_short_strict(string, &number, base); +} + +int str_is_ushort(const char *string, const int base) +{ + unsigned short number; + + return str_to_ushort(string, &number, base); +} + +int str_is_ushort_strict(const char *string, const int base) +{ + unsigned short number; + + return str_to_ushort_strict(string, &number, base); +} + +int str_is_int(const char *string, const int base) +{ + int number; + + return str_to_int(string, &number, base); +} + +int str_is_int_strict(const char *string, const int base) +{ + int number; + + return str_to_int_strict(string, &number, base); +} + +int str_is_uint(const char *string, const int base) +{ + unsigned int number; + + return str_to_uint(string, &number, base); +} + +int str_is_uint_strict(const char *string, const int base) +{ + unsigned int number; + + return str_to_uint_strict(string, &number, base); +} + +int str_is_long(const char *string, const int base) +{ + long number; + + return str_to_long(string, &number, base); +} + +int str_is_long_strict(const char *string, const int base) +{ + long number; + + return str_to_long_strict(string, &number, base); +} + +int str_is_ulong(const char *string, const int base) +{ + unsigned long number; + + return str_to_ulong(string, &number, base); +} + +int str_is_ulong_strict(const char *string, const int base) +{ + unsigned long number; + + return str_to_ulong_strict(string, &number, base); +} + +int str_is_double(const char *string, const int base) +{ + double number; + + return str_to_double(string, &number, base); +} + +int str_is_double_strict(const char *string, const int base) +{ + double number; + + return str_to_double_strict(string, &number, base); +} + +int str_to_short(const char *string, short *number, const int base) +{ + long num; + + *number = 0; + + if (!str_to_long(string, &num, base)) + return 0; + + if ( + num < SHRT_MIN || + num > SHRT_MAX + ) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_short_strict(const char *string, short *number, const int base) +{ + long num; + + *number = 0; + + if (!str_to_long_strict(string, &num, base)) + return 0; + + if ( + num < SHRT_MIN || + num > SHRT_MAX + ) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_ushort(const char *string, unsigned short *number, const int base) +{ + unsigned long num; + + *number = 0; + + if (!str_to_ulong(string, &num, base)) + return 0; + + if (num > USHRT_MAX) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_ushort_strict(const char *string, unsigned short *number, const int base) +{ + unsigned long num; + + *number = 0; + + if (!str_to_ulong_strict(string, &num, base)) + return 0; + + if (num > USHRT_MAX) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_int(const char *string, int *number, const int base) +{ + long num; + + *number = 0; + + if (!str_to_long(string, &num, base)) + return 0; + + if ( + num < INT_MIN || + num > INT_MAX + ) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_int_strict(const char *string, int *number, const int base) +{ + long num; + + *number = 0; + + if (!str_to_long_strict(string, &num, base)) + return 0; + + if ( + num < INT_MIN || + num > INT_MAX + ) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_uint(const char *string, unsigned int *number, const int base) +{ + unsigned long num; + + *number = 0; + + if (!str_to_ulong(string, &num, base)) + return 0; + + if (num > UINT_MAX) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_uint_strict(const char *string, unsigned int *number, const int base) +{ + unsigned long num; + + *number = 0; + + if (!str_to_ulong_strict(string, &num, base)) + return 0; + + if (num > UINT_MAX) { + errno = ERANGE; + return 0; + } + + *number = num; + return 1; +} + +int str_to_long(const char *string, long *number, const int base) +{ + char *str; + + *number = 0; + + if ( + string == NULL || + *string == '\0' + ) { + errno = EINVAL; + return 0; + } + + str = strdup(string); + if (str == NULL) + return 0; + + str_trim_space(str); + + if (!str_to_long_strict(str, number, base)) { + free(str); + return 0; + } + + free(str); + return 1; +} + +int str_to_long_strict(const char *string, long *number, const int base) +{ + char *ptr = NULL; + + *number = 0; + + if ( + string == NULL || + *string == '\0' || + isspace(*string) + ) { + errno = EINVAL; + return 0; + } + + errno = 0; + *number = strtol(string, &ptr, base); + + if ( + errno == EINVAL || + *ptr != '\0' + ) { + *number = 0; + errno = EINVAL; + return 0; + } + + if (errno == ERANGE) { + *number = 0; + return 0; + } + + return 1; +} + +int str_to_ulong(const char *string, unsigned long *number, const int base) +{ + char *str; + + *number = 0; + + if ( + string == NULL || + *string == '\0' + ) { + errno = EINVAL; + return 0; + } + + str = strdup(string); + if (str == NULL) + return 0; + + str_trim_space(str); + + if (!str_to_ulong_strict(str, number, base)) { + free(str); + return 0; + } + + free(str); + return 1; +} + +int str_to_ulong_strict(const char *string, unsigned long *number, const int base) +{ + char *ptr = NULL; + + *number = 0; + + if ( + string == NULL || + *string == '\0' || + *string == '+' || + *string == '-' || + isspace(*string) + ) { + errno = EINVAL; + return 0; + } + + errno = 0; + *number = strtoul(string, &ptr, base); + + if ( + errno == EINVAL || + *ptr != '\0' + ) { + *number = 0; + errno = EINVAL; + return 0; + } + + if (errno == ERANGE) { + *number = 0; + return 0; + } + + return 1; +} + +int str_to_double(const char *string, double *number, const int base) +{ + char *str; + + *number = 0; + + if ( + string == NULL || + *string == '\0' + ) { + errno = EINVAL; + return 0; + } + + str = strdup(string); + if (str == NULL) + return 0; + + str_trim_space(str); + + if (!str_to_double_strict(str, number, base)) { + free(str); + return 0; + } + + free(str); + return 1; +} + +int str_to_double_strict(const char *string, double *number, const int base) +{ + char *ptr = NULL; + + *number = 0; + + if ( + string == NULL || + *string == '\0' || + isspace(*string) + ) { + errno = EINVAL; + return 0; + } + + switch (base) + { + case 0: + break; + case 10: + if (strlen(string) != strspn(string, "-+.0123456789Ee")) { + errno = EINVAL; + return 0; + } + break; + case 16: + if (strlen(string) != strspn(string, "-+.0123456789ABCDEFabcdefXxPp")) { + errno = EINVAL; + return 0; + } + break; + default: + errno = EINVAL; + return 0; + } + + errno = 0; + *number = strtod(string, &ptr); + + if ( + errno == EINVAL || + *ptr != '\0' + ) { + *number = 0; + errno = EINVAL; + return 0; + } + + if (errno == ERANGE) { + *number = 0; + return 0; + } + + return 1; +} diff --git a/conf/Makefile.in b/conf/Makefile.in index 4afc1f8..cc5884c 100644 --- a/conf/Makefile.in +++ b/conf/Makefile.in @@ -220,6 +220,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/configure b/configure index 3210ecd..f70451d 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for nut 2.7.3. +# Generated by GNU Autoconf 2.69 for nut 2.7.4. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='nut' PACKAGE_TARNAME='nut' -PACKAGE_VERSION='2.7.3' -PACKAGE_STRING='nut 2.7.3' +PACKAGE_VERSION='2.7.4' +PACKAGE_STRING='nut 2.7.4' PACKAGE_BUGREPORT='https://github.com/networkupstools/nut/issues' PACKAGE_URL='' @@ -652,6 +652,7 @@ RUN_AS_USER PORT SBINDIR DRVPATH +LIBDIR BINDIR CONFPATH STATEPATH @@ -1511,7 +1512,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures nut 2.7.3 to adapt to many kinds of systems. +\`configure' configures nut 2.7.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1582,7 +1583,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of nut 2.7.3:";; + short | recursive ) echo "Configuration of nut 2.7.4:";; esac cat <<\_ACEOF @@ -1784,7 +1785,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -nut configure 2.7.3 +nut configure 2.7.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2374,7 +2375,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by nut $as_me 2.7.3, which was +It was created by nut $as_me 2.7.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3493,7 +3494,7 @@ fi # Define the identity of the package. PACKAGE='nut' - VERSION='2.7.3' + VERSION='2.7.4' cat >>confdefs.h <<_ACEOF @@ -10271,32 +10272,33 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBS}" >&5 $as_echo "${LIBS}" >&6; } - for ac_header in nss.h -do : - ac_fn_c_check_header_compile "$LINENO" "nss.h" "ac_cv_header_nss_h" "$ac_includes_default -" -if test "x$ac_cv_header_nss_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NSS_H 1 -_ACEOF - nut_have_libnss=yes -else - nut_have_libnss=no -fi - -done - - for ac_func in NSS_Init + for ac_func in NSS_Init do : ac_fn_c_check_func "$LINENO" "NSS_Init" "ac_cv_func_NSS_Init" if test "x$ac_cv_func_NSS_Init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NSS_INIT 1 +_ACEOF + nut_have_libnss=yes +else + nut_have_libnss=no +fi +done + + for ac_header in nss.h ssl.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else nut_have_libnss=no fi + done @@ -10601,32 +10603,33 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBS}" >&5 $as_echo "${LIBS}" >&6; } - for ac_header in nss.h -do : - ac_fn_c_check_header_compile "$LINENO" "nss.h" "ac_cv_header_nss_h" "$ac_includes_default -" -if test "x$ac_cv_header_nss_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NSS_H 1 -_ACEOF - nut_have_libnss=yes -else - nut_have_libnss=no -fi - -done - - for ac_func in NSS_Init + for ac_func in NSS_Init do : ac_fn_c_check_func "$LINENO" "NSS_Init" "ac_cv_func_NSS_Init" if test "x$ac_cv_func_NSS_Init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NSS_INIT 1 +_ACEOF + nut_have_libnss=yes +else + nut_have_libnss=no +fi +done + + for ac_header in nss.h ssl.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else nut_have_libnss=no fi + done @@ -23333,6 +23336,16 @@ cat >>confdefs.h <<_ACEOF _ACEOF +conftemp="${libdir}" +eval conftemp=\"${conftemp}\" +eval conftemp=\"${conftemp}\" +LIBDIR=${conftemp} + +cat >>confdefs.h <<_ACEOF +#define LIBDIR "${conftemp}" +_ACEOF + + now=`TZ=UTC date +%Y-%m-%d` @@ -23384,6 +23397,7 @@ now=`TZ=UTC date +%Y-%m-%d` + ac_config_files="$ac_config_files clients/Makefile common/Makefile conf/Makefile conf/upsmon.conf.sample conf/upssched.conf.sample data/html/header.html data/html/Makefile data/Makefile data/driver.list docs/Makefile docs/docinfo.xml docs/man/Makefile drivers/Makefile include/Makefile lib/libupsclient-config lib/libupsclient.pc lib/libnutclient.pc lib/libnutscan.pc lib/Makefile scripts/Aix/nut-aix.spec scripts/augeas/Makefile scripts/augeas/nutnutconf.aug scripts/augeas/nutupsconf.aug scripts/augeas/nutupsdconf.aug scripts/augeas/nutupsdusers.aug scripts/augeas/nutupsmonconf.aug scripts/augeas/nutupsschedconf.aug scripts/augeas/nuthostsconf.aug scripts/augeas/nutupssetconf.aug scripts/avahi/nut.service scripts/devd/Makefile scripts/devd/nut-usb.conf scripts/hotplug/Makefile scripts/hotplug/libhidups scripts/HP-UX/nut.psf scripts/HP-UX/postinstall scripts/python/Makefile scripts/systemd/Makefile scripts/systemd/nut-driver.service scripts/systemd/nut-monitor.service scripts/systemd/nut-server.service scripts/systemd/nutshutdown scripts/Solaris/Makefile scripts/Solaris/pkginfo scripts/Solaris/postinstall scripts/Solaris/preremove scripts/Solaris/nut scripts/udev/Makefile scripts/udev/nut-ipmipsu.rules scripts/udev/nut-usbups.rules scripts/ufw/nut.ufw.profile scripts/Makefile server/Makefile tools/Makefile tools/nut-scanner/Makefile tests/Makefile Makefile" @@ -24051,7 +24065,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by nut $as_me 2.7.3, which was +This file was extended by nut $as_me 2.7.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -24117,7 +24131,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -nut config.status 2.7.3 +nut config.status 2.7.4 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index f87be6d..41db8d3 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,8 @@ dnl | Network UPS Tools: configure.ac | dnl +------------------------------------------------------------------+ dnl NUT version number is defined here, with a Git suffix in include/nut_version.h -AC_INIT(nut, 2.7.3, [https://github.com/networkupstools/nut/issues]) +AC_INIT(nut, 2.7.4, [https://github.com/networkupstools/nut/issues]) +AC_CONFIG_AUX_DIR([.]) AC_CONFIG_SRCDIR(server/upsd.c) AC_CONFIG_MACRO_DIR([m4]) echo "Network UPS Tools version ${PACKAGE_VERSION}" @@ -1202,6 +1203,13 @@ eval conftemp=\"${conftemp}\" SBINDIR=${conftemp} AC_DEFINE_UNQUOTED(SBINDIR, "${conftemp}", [Default path for system executables]) +dnl same for libdir +conftemp="${libdir}" +eval conftemp=\"${conftemp}\" +eval conftemp=\"${conftemp}\" +LIBDIR=${conftemp} +AC_DEFINE_UNQUOTED(LIBDIR, "${conftemp}", [Default path for system libraries]) + dnl Current date now=`TZ=UTC date +%Y-%m-%d` @@ -1239,6 +1247,7 @@ AC_SUBST(PIDPATH) AC_SUBST(STATEPATH) AC_SUBST(CONFPATH) AC_SUBST(BINDIR) +AC_SUBST(LIBDIR) AC_SUBST(DRVPATH) AC_SUBST(SBINDIR) AC_SUBST(PORT) diff --git a/data/Makefile.in b/data/Makefile.in index 5a010e3..0bd8feb 100644 --- a/data/Makefile.in +++ b/data/Makefile.in @@ -274,6 +274,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/data/cmdvartab b/data/cmdvartab index ef68d70..3d091f2 100644 --- a/data/cmdvartab +++ b/data/cmdvartab @@ -47,6 +47,11 @@ VARDESC input.voltage "Input voltage (V)" VARDESC input.voltage.extended "Extended input voltage range" VARDESC input.voltage.maximum "Maximum incoming voltage seen (V)" VARDESC input.voltage.minimum "Minimum incoming voltage seen (V)" +VARDESC input.voltage.status "Voltage status relative to the thresholds" +VARDESC input.voltage.low.warning "Input voltage low warning threshold (V)" +VARDESC input.voltage.low.critical "Input voltage low critical threshold (V)" +VARDESC input.voltage.high.warning "Input voltage high warning threshold (V)" +VARDESC input.voltage.high.critical "Input voltage high critical threshold (V)" VARDESC input.voltage.nominal "Nominal input voltage (V)" VARDESC input.transfer.reason "Reason for last transfer to battery" VARDESC input.transfer.low "Low voltage transfer point (V)" @@ -59,8 +64,14 @@ VARDESC input.sensitivity "Input power sensitivity" VARDESC input.quality "Input power quality" VARDESC input.current "Input current (A)" VARDESC input.current.nominal "Nominal input current (A)" +VARDESC input.current.status "Current status relative to the thresholds" +VARDESC input.current.low.warning "Input current low warning threshold (A)" +VARDESC input.current.low.critical "Input current low critical threshold (A)" +VARDESC input.current.high.warning "Input current high warning threshold (A)" +VARDESC input.current.high.critical "Input current high critical threshold (A)" VARDESC input.frequency "Input line frequency (Hz)" VARDESC input.frequency.extended "Extended input frequency range" +VARDESC input.frequency.status "Frequency status" VARDESC input.frequency.nominal "Nominal input line frequency (Hz)" VARDESC input.frequency.low "Minimum input line frequency (Hz)" VARDESC input.frequency.high "Maximum input line frequency (Hz)" @@ -72,6 +83,8 @@ VARDESC input.transfer.delay "Delay before transfer to mains" VARDESC input.load "Load on (ePDU) input (percent of full)" VARDESC input.realpower "Current sum value of all (ePDU) phases real power (W)" VARDESC input.power "Current sum value of all (ePDU) phases apparent power (VA)" +VARDESC input.source "The current input power source" +VARDESC input.source.preferred "The prefered input power source" VARDESC output.voltage "Output voltage (V)" VARDESC output.voltage.nominal "Nominal output voltage (V)" @@ -106,14 +119,31 @@ VARDESC battery.charger.status "Battery charger status" VARDESC ambient.temperature "Ambient temperature (degrees C)" VARDESC ambient.temperature.alarm "Ambient temperature alarm is active" -VARDESC ambient.temperature.alarm.maximum "Maximum allowed ambient temperature" -VARDESC ambient.temperature.alarm.minimum "Minimum allowed ambient temperature" +VARDESC ambient.temperature.status "Ambient temperature status relative to the configured thresholds" +VARDESC ambient.temperature.alarm.maximum "Maximum allowed ambient temperature (degrees C)" +VARDESC ambient.temperature.alarm.minimum "Minimum allowed ambient temperature (degrees C)" VARDESC ambient.temperature.alarm.enable "Enable ambient temperature alarm" -VARDESC ambient.humidity "Ambient humidity" +VARDESC ambient.temperature.low "Temperature threshold low (degrees C)" +VARDESC ambient.temperature.low.warning "Temperature threshold low warning (degrees C)" +VARDESC ambient.temperature.low.critical "Temperature threshold low critical (degrees C)" +VARDESC ambient.temperature.high "Temperature threshold high (degrees C)" +VARDESC ambient.temperature.high.warning "Temperature threshold high warning (degrees C)" +VARDESC ambient.temperature.high.critical "Temperature threshold high critical (degrees C)" +VARDESC ambient.humidity "Ambient humidity (percent)" VARDESC ambient.humidity.alarm "Ambient humidity alarm is active" -VARDESC ambient.humidity.alarm.maximum "Maximum allowed ambient humidity" -VARDESC ambient.humidity.alarm.minimum "Minimum allowed ambient humidity" +VARDESC ambient.humidity.status "Ambient humidity status relative to the configured thresholds" +VARDESC ambient.humidity.alarm.maximum "Maximum allowed ambient humidity (percent)" +VARDESC ambient.humidity.alarm.minimum "Minimum allowed ambient humidity (percent)" VARDESC ambient.humidity.alarm.enable "Enable ambient humidity alarm" +VARDESC ambient.humidity.low "Ambient humidity threshold low (percent)" +VARDESC ambient.humidity.low.warning "Ambient humidity threshold low warning (percent)" +VARDESC ambient.humidity.low.critical "Ambient humidity threshold low critical (percent)" +VARDESC ambient.humidity.high "Ambient humidity threshold high (percent)" +VARDESC ambient.humidity.high.warning "Ambient humidity threshold high warning (percent)" +VARDESC ambient.humidity.high.critical "Ambient humidity threshold high critical (percent)" +VARDESC ambient.present "Ambient sensor presence" +VARDESC ambient.contacts.1.status "State of the dry contact sensor 1" +VARDESC ambient.contacts.2.status "State of the dry contact sensor 2" # FIXME: the outlet collection is indexed - solve with regexs? # diff --git a/data/driver.list.in b/data/driver.list.in index a0e82fb..50f23b8 100644 --- a/data/driver.list.in +++ b/data/driver.list.in @@ -18,6 +18,7 @@ # "ups" for Uninterruptible Power Supply # "pdu" for Power Distributions Unit # "scd" for Solar Controlers Device +# "ats" for Automatic Transfer Switch # # - support level: a number from "1" to "5" (stars) meaning: # * protocol based on reverse engineering @@ -47,6 +48,8 @@ "AEC" "ups" "1" "MiniGuard UPS 700" "Megatec M2501 cable" "genericups upstype=21" "AEG Power Solutions" "ups" "2" "PROTECT HOME" "" "blazer_ser or blazer_usb" +"AEG Power Solutions" "ups" "3" "PROTECT NAS" "" "usbhid-ups" +"AEG Power Solutions" "ups" "3" "PROTECT B" "" "usbhid-ups" "APC" "ups" "2" "Back-UPS 1200BR (Microsol)" "" "solis" "APC" "ups" "2" "Back-UPS BZ2200BI-BR (Microsol)" "" "solis" @@ -70,10 +73,12 @@ "APC" "ups" "3" "Smart-UPS RT XL" "AP9618 SNMP monitoring card" "snmp-ups" "APC" "ups" "3" "(various)" "AP9618 SNMP monitoring card" "snmp-ups" "APC" "ups" "3" "(various)" "AP9630 SNMP monitoring card" "snmp-ups privProtocol=AES" +"APC" "ups" "3" "(various)" "APCUPSD-controlled devices" "apcupsd-ups" "APC" "pdu" "1" "Masterswitch" "940-0020 cable" "genericups upstype=12" "APC" "pdu" "1" "AP9210" "8 outlets" "powerman-pdu (experimental)" "APC" "pdu" "1" "AP79xx" "8 to 24 outlets" "powerman-pdu (experimental)" "APC" "pdu" "3" "(various)" "SNMP monitoring card" "snmp-ups (experimental)" +"APC" "ats" "3" "ATS AP7724" "" "snmp-ups (experimental)" "Aphel" "pdu" "3" "various PDU" "" "snmp-ups (experimental)" @@ -93,7 +98,9 @@ "ARTronic" "ups" "2" "ARTon Platinium Combo 3.1 10/15/20 kVA" "USB" "blazer_usb" "ARTronic" "ups" "2" "ARTon Platinium RT 1/2/3/6/10 kVA" "USB" "blazer_usb" -"ASEM SPA" "UPS" "5" "PB1300 UPS" "i2c" "asem" +"ASEM SPA" "ups" "5" "PB1300 UPS" "i2c" "asem" + +"Asium" "ups" "3" "P700" "USB" "blazer_usb" # http://www.asiumpower.com/Asium-ASIUM-P700-650VA-360W/dp/B009SMEQ10 "ATEK" "ups" "2" "Defensor 1K Tower / Rack" "USB" "blazer_usb" "ATEK" "ups" "2" "Defensor 2K Tower / Rack" "USB" "blazer_usb" @@ -242,8 +249,8 @@ "Dell" "ups" "5" "Rack 3750W High Efficiency Online HV" "USB port" "usbhid-ups" "Dell" "ups" "5" "Rack 4200W High Efficiency Online HV" "USB port" "usbhid-ups" "Dell" "ups" "5" "Rack 5600W HV" "USB port" "usbhid-ups" -"Dell" "ups" "5" "Various (SNMP mode)" "UPS Network Management Card " "snmp-ups" -"Dell" "ups" "5" "Various (XML/HTTP mode)" "UPS Network Management Card " "netxml-ups (experimental)" +"Dell" "ups" "5" "Various (SNMP mode)" "UPS Network Management Card" "snmp-ups" +"Dell" "ups" "5" "Various (XML/HTTP mode)" "UPS Network Management Card" "netxml-ups (experimental)" "Delta" "ups" "1" "GES602N" "" "belkin" @@ -275,6 +282,8 @@ "Eaton" "ups" "5" "MX 5/8/10/15/20 kVA" "USB port" "usbhid-ups" "Eaton" "ups" "5" "5 PX" "USB port" "usbhid-ups" "Eaton" "ups" "5" "Nova AVR 625/1250" "USB" "usbhid-ups" +"Eaton" "ups" "5" "5E650iUSB" "USB port" "usbhid-ups" +"Eaton" "ups" "5" "5E1100iUSB" "USB port" "usbhid-ups" # http://powerquality.eaton.com/5E1100iUSB.aspx?CX&GUID=8D85FE66-3102-427C-8F33-B8D56BBDD4D3 "Eaton" "ups" "5" "5S" "USB port" "usbhid-ups" "Eaton" "ups" "5" "5SC" "USB port" "usbhid-ups" "Eaton" "ups" "5" "5P" "USB port" "usbhid-ups" @@ -296,9 +305,10 @@ "Eaton" "ups" "5" "EX RT (XML/HTTP)" "NMC Transverse card (ref 66074)" "netxml-ups (experimental)" "Eaton" "ups" "5" "EX RT (SNMP)" "NMC Transverse card (ref 66074)" "snmp-ups (experimental)" "Eaton" "ups" "5" "E Series NV UPS 400-2000 VA" "" "blazer_usb" -"Eaton" "ups" "5" "E Series DX UPS 1-20 kVA" "" "mge-utalk" +"Eaton" "ups" "5" "E Series DX UPS 1-20 kVA" "" "blazer_ser" # http://www.eaton.com/Eaton/ESeriesUPS/DXUPS/ "Eaton" "ups" "4" "NetUPS SE 450/700/1000/1500" "" "upscode2" "Eaton" "ups" "5" "BladeUPS (SNMP)" "ConnectUPS Web/SNMP Card" "snmp-ups (experimental)" +"Eaton" "ups" "5" "various models (SNMP mode)" "Power Xpert Gateway UPS Card" "snmp-ups (experimental)" "Eaton" "ups" "5" "various models (XML/HTTP mode)" "NMC Minislot (ref 66102)" "netxml-ups (experimental)" "Eaton" "ups" "5" "various models (SNMP mode)" "NMC Minislot (ref 66102)" "snmp-ups (experimental)" "Eaton" "ups" "5" "various models (XML/HTTP mode)" "SNMP/Web Minislot card (ref 66244)" "netxml-ups (experimental)" @@ -308,6 +318,7 @@ "Eaton" "pdu" "5" "ePDU Switched" "" "snmp-ups" "Eaton" "pdu" "5" "ePDU Monitored" "" "snmp-ups or netxml-ups" "Eaton" "ups" "5" "Powerware 3105" "USB" "bcmxcp_usb" # http://powerquality.eaton.com/Products-services/Backup-Power-UPS/3105-eol.aspx +"Eaton" "ups" "5" "Powerware 9125" "USB card" "bcmxcp_usb" "Eaton" "ups" "5" "Powerware 9130" "" "bcmxcp or usbhid-ups" "Eaton" "ups" "5" "Powerware 9140" "" "bcmxcp or usbhid-ups" "Eaton" "ups" "5" "Powerware 5130" "" "usbhid-ups" @@ -316,10 +327,13 @@ "Eaton" "ups" "5" "ConnectUPS X / BD / E Slot" "Serial Pass-through mode" "bcmxcp" "Eaton" "ups" "5" "ConnectUPS X / BD / E Slot" "Network port" "snmp-ups" "Eaton" "ups" "5" "Management Card Contact" "Config 3 - Cable 66033" "genericups upstype=7" +"Eaton" "ats" "5" "Eaton ATS16" "" "snmp-ups" "Effekta" "ups" "2" "MI/MT/MH" "2502 cable" "blazer_ser" "Effekta" "ups" "2" "RM2000MH" "" "blazer_ser" +"Electrys" "ups" "2" "UPS 2500" "" "nutdrv_qx or blazer_ser" + "Energy Sistem" "ups" "2" "(various)" "" "blazer_ser" "ETA" "ups" "1" "mini+UPS" "WinNT/Upsoft cable" "genericups upstype=7" @@ -351,6 +365,7 @@ "Fideltronik" "ups" "1" "Ares 700 and larger" "" "genericups upstype=6" "Fideltronik" "ups" "2" "LUPUS 500" "USB" "nutdrv_qx" "Fideltronik" "ups" "1" "Other Ares models" "" "genericups upstype=19" +"Fideltronik INIGO" "ups" "2" "Viper 1200" "USB" "nutdrv_qx" # http://fideltronikinigo.com/viper/viper-1200/ "Fiskars" "ups" "4" "PowerRite MAX" "" "upscode2" "Fiskars" "ups" "4" "PowerServer 10" "" "upscode2" @@ -414,9 +429,11 @@ "HP" "ups" "3" "R/T 2200 G2" "" "usbhid-ups" "HP" "ups" "3" "R/T3000" "USB port" "usbhid-ups" "HP" "ups" "3" "R5000 / R7000" "USB port" "usbhid-ups" -"HP" "ups" "4" "Various (SNMP mode)" "HP UPS Management Module " "snmp-ups" +"HP" "ups" "4" "Various (SNMP mode)" "HP UPS Management Module" "snmp-ups" "HP" "pdu" "1" "HP3488 Switch/Control Unit" "" "powerman-pdu (experimental)" +"Huawei" "ups" "4" "UPS5000-E" "" "snmp-ups" + "IBM" "pdu" "1" "Blade Center Management Module" "15 outlets" "powerman-pdu (experimental)" "ICS" "pdu" "1" "8064 Ethernet Relay Interface" "16 outlets" "powerman-pdu (experimental)" @@ -478,6 +495,8 @@ "LDLC" "ups" "2" "UPS-1200D" "" "blazer_usb langid_fix=0x4095" +"Legrand" "ups" "2" "Keor Multiplug" "" "nutdrv_qx" + "Lestar" "ups" "2" "MD-800E" "" "blazer_ser" "Lexis" "ups" "2" "X-Power Tigra 1kVA" "" "blazer_ser or bestups" @@ -491,6 +510,7 @@ "LNXI" "pdu" "1" "Icebox" "10 outlets" "powerman-pdu (experimental)" +"Lyonn" "ups" "2" "CTB-800V" "" "nutdrv_qx" "Lyonn" "ups" "2" "CTB-1200" "" "blazer_usb" "Masterguard" "ups" "1" "(various)" "" "masterguard" @@ -691,6 +711,8 @@ "Microline" "ups" "2" "C-Lion Innova Tower 6K/10K" "" "blazer_usb" "Microline" "ups" "2" "C-Lion Innova Combo 10K/20K (3/1)" "" "blazer_usb" +"Micropower" "ups" "2" "LCD 1000" "USB" "blazer_usb" + "Microsol" "ups" "4" "Solis 1.0" "1000VA" "solis" "Microsol" "ups" "4" "Solis 1.5" "1500VA" "solis" "Microsol" "ups" "4" "Solis 2.0" "2000VA" "solis" @@ -711,7 +733,7 @@ "Mustek" "ups" "2" "Powermust" "2000VA USB" "blazer_ser" "Mustek" "ups" "2" "Powermust Office 650" "USB" "blazer_usb" "Mustek" "ups" "2" "PowerMust 424 / 636 / 848" "USB" "blazer_usb" -"Mustek" "ups" "2" "Yukai PowerMust" "1000 USB (PID: 5161)" "blazer_usb" +"Mustek" "ups" "2" "Yukai PowerMust" "1000 USB (PID: 5161)" "blazer_usb" "Mustek" "ups" "2" "Various" "" "blazer_ser" "Neus" "ups" "2" "400va / 600va" "" "blazer_ser" @@ -723,6 +745,7 @@ "NHS Sistemas de Energia" "ups" "5" "Expert S Online 8000" "" "gamatronic" "NHS Sistemas de Energia" "ups" "5" "Expert S Online 10000" "" "gamatronic" "NHS Sistemas de Energia" "ups" "5" "Expert S Online 10000" "" "gamatronic" +"NHS Sistemas de Energia" "ups" "5" "Laser Senoidal 5000VA" "USB" "gamatronic" # http://www.nhs.com.br/produtos_interna/id/T0RrPQ== "Nitram" "ups" "1" "Elite 500" "" "genericups upstype=8" "Nitram" "ups" "1" "Elite 2002" "" "genericups upstype=16" @@ -936,6 +959,7 @@ "Sweex" "ups" "1" "500/1000" "" "genericups upstype=7" "Sweex" "ups" "1" "1000" "USB" "richcomm_usb" "Sweex" "ups" "2" "(various)" "" "blazer_ser" +"Sweex" "ups" "2" "INTELLIGENT UPS 1500VA P220" "USB" "blazer_usb (USB ID 0665:5161)" # http://www.sweex.com/en/notebook-pc-accessoires/ups/PP220/ "Syndome" "ups" "2" "Era 500VA" "USB" "blazer_usb" @@ -1077,6 +1101,8 @@ "Trust" "ups" "2" "UPS 1200VA Management PW-4120M" "" "blazer_ser" "Trust" "ups" "2" "UPS 1300VA Management PW-4130M" "" "blazer_ser" +"TS Shara" "ups" "4" "(various)" "" "nutdrv_qx" + "UNITEK" "ups" "2" "ALPHA 500 IC" "" "blazer_ser" "UNITEK" "ups" "2" "Alpha 1000is" "" "blazer_ser" "UNITEK" "ups" "2" "Alpha 500" "" "blazer_ser" diff --git a/data/html/Makefile.in b/data/html/Makefile.in index 8ec093f..f455c4a 100644 --- a/data/html/Makefile.in +++ b/data/html/Makefile.in @@ -213,6 +213,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/docs/FAQ.txt b/docs/FAQ.txt index 8ce0b14..81c93df 100644 --- a/docs/FAQ.txt +++ b/docs/FAQ.txt @@ -561,6 +561,8 @@ The most frequent issue is that udev has not actually applied the rule: - and if the device USB cord was already plugged when installing NUT. In this case, just unplug and plug back the USB cord, then restart NUT. +Instead of unplugging, you might also be able to run `udevadm trigger +--subsystem-match=usb --action=change` to fix permissions. There was a mistake in the naming of the NUT udev rules file which resulted in the rules being overridden by another udev configuration file. While this has @@ -590,7 +592,7 @@ will appear in dmesg: usbfs: process 29641 (usbhid-ups) did not claim interface 0 before use This can be a symptom of a source install conflicting with a package install. -There is a rudimetary locking mechanism in NUT, but there is a chance that the +There is a rudimentary locking mechanism in NUT, but there is a chance that the packages might not use the same directory as the NUT default, and the conflict will be reported by the kernel. diff --git a/docs/Makefile.am b/docs/Makefile.am index 8ca7afd..c587aa5 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -111,18 +111,21 @@ A2X_COMMON_OPTS = $(ASCIIDOC_VERBOSE) --attribute icons \ $(A2X) $(A2X_COMMON_OPTS) --attribute=pdf_format --format=pdf -a docinfo1 $< if HAVE_ASPELL -# FIXME: also check ../{NEWS,README,UPGRADING}+other dirs # Non-interactively spell check all documentation source files. # This is useful for Buildbot and automated QA processing # FIXME: how to present output (std{out,err}, single file or per target)? +SPELLCHECK_SRC = $(ALL_TXT_SRC) ../README ../INSTALL.nut ../UPGRADING ../NEWS \ + ../TODO ../scripts/ufw/README ../scripts/augeas/README ../lib/README \ + ../tools/nut-scanner/README + spellcheck: - @for docsrc in $(ALL_TXT_SRC); do \ + @for docsrc in $(SPELLCHECK_SRC); do \ echo "Spell checking on $$docsrc"; \ LANG=C $(ASPELL) -a -t -p $(NUT_SPELL_DICT) < $$docsrc | grep [^*]; \ done # Interactively spell check all documentation source files spellcheck-interactive: - @for docsrc in $(ALL_TXT_SRC); do\ + @for docsrc in $(SPELLCHECK_SRC); do\ echo "Spell checking on $$docsrc"; \ LANG=C $(ASPELL) check -p $(NUT_SPELL_DICT) $$docsrc; \ done diff --git a/docs/Makefile.in b/docs/Makefile.in index 037296f..1a28021 100644 --- a/docs/Makefile.in +++ b/docs/Makefile.in @@ -242,6 +242,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ @@ -464,6 +465,14 @@ A2X_COMMON_OPTS = $(ASCIIDOC_VERBOSE) --attribute icons \ --attribute tree_version=@TREE_VERSION@ \ -a toc -a numbered --destination-dir=. + +# Non-interactively spell check all documentation source files. +# This is useful for Buildbot and automated QA processing +# FIXME: how to present output (std{out,err}, single file or per target)? +@HAVE_ASPELL_TRUE@SPELLCHECK_SRC = $(ALL_TXT_SRC) ../README ../INSTALL.nut ../UPGRADING ../NEWS \ +@HAVE_ASPELL_TRUE@ ../TODO ../scripts/ufw/README ../scripts/augeas/README ../lib/README \ +@HAVE_ASPELL_TRUE@ ../tools/nut-scanner/README + all: all-recursive .SUFFIXES: @@ -802,18 +811,14 @@ packager-guide.html packager-guide.chunked packager-guide.pdf: packager-guide.tx .txt.pdf: docinfo.xml $(A2X) $(A2X_COMMON_OPTS) --attribute=pdf_format --format=pdf -a docinfo1 $< -# FIXME: also check ../{NEWS,README,UPGRADING}+other dirs -# Non-interactively spell check all documentation source files. -# This is useful for Buildbot and automated QA processing -# FIXME: how to present output (std{out,err}, single file or per target)? @HAVE_ASPELL_TRUE@spellcheck: -@HAVE_ASPELL_TRUE@ @for docsrc in $(ALL_TXT_SRC); do \ +@HAVE_ASPELL_TRUE@ @for docsrc in $(SPELLCHECK_SRC); do \ @HAVE_ASPELL_TRUE@ echo "Spell checking on $$docsrc"; \ @HAVE_ASPELL_TRUE@ LANG=C $(ASPELL) -a -t -p $(NUT_SPELL_DICT) < $$docsrc | grep [^*]; \ @HAVE_ASPELL_TRUE@ done # Interactively spell check all documentation source files @HAVE_ASPELL_TRUE@spellcheck-interactive: -@HAVE_ASPELL_TRUE@ @for docsrc in $(ALL_TXT_SRC); do\ +@HAVE_ASPELL_TRUE@ @for docsrc in $(SPELLCHECK_SRC); do\ @HAVE_ASPELL_TRUE@ echo "Spell checking on $$docsrc"; \ @HAVE_ASPELL_TRUE@ LANG=C $(ASPELL) check -p $(NUT_SPELL_DICT) $$docsrc; \ @HAVE_ASPELL_TRUE@ done diff --git a/docs/config-notes.txt b/docs/config-notes.txt index 021033b..62983b5 100644 --- a/docs/config-notes.txt +++ b/docs/config-notes.txt @@ -30,7 +30,7 @@ configuration directive. This may be something like MONITOR, NOTIFYCMD, or ACCESS. The case does matter here. "monitor" won't be recognized. Next, the parser does not care about whitespace between words. If you -like to indent things with tabs or spaces, feel free to do it here. +like to indent things with tabs or spaces, feel free to do it here. If you need to set a value to something containing spaces, it has to be contained within "quotes" to keep the parser from splitting up the line. @@ -45,46 +45,46 @@ configuration directive for some reason. You can do that too. NOTIFYCMD "/bin/notifyme -foo -bar \"hi there\" -baz" -In other words, *\* can be used to escape the *"*. +In other words, `\` can be used to escape the `"`. -Finally, for the situation where you need to put the *\* character into your +Finally, for the situation where you need to put the `\` character into your string, you just escape it. NOTIFYCMD "/bin/notifyme c:\\dos\\style\\path" -The *\* can actually be used to escape any character, but you only really -need it for *\*, *"*, and *#* as they have special meanings to the parser. +The `\` can actually be used to escape any character, but you only really +need it for `\`, `"`, and `#` as they have special meanings to the parser. When using file names with space characters, you may end up having tricky -things since you need to write them inside *""* which must be escaped: +things since you need to write them inside `""` which must be escaped: NOTIFYCMD "\"c:\\path with space\\notifyme\" \"c:\\path with space\\name\"" -*#* is the comment character. Anything after an unescaped *#* is ignored. +`#` is the comment character. Anything after an unescaped `#` is ignored. Something like this... identity = my#1ups -... will actually turn into "identity = my", since the *#* stops the -parsing. If you really need to have a *#* in your configuration, then +will actually turn into `identity = my`, since the `#` stops the +parsing. If you really need to have a `#` in your configuration, then escape it. identity = my\#1ups Much better. -The *=* character should be used with care too. There should be only one -"simple" *=* character in a line: between the parameter name and its value. -All other *=* characters should be either escaped or within "quotes". +The `=` character should be used with care too. There should be only one +"simple" `=` character in a line: between the parameter name and its value. +All other `=` characters should be either escaped or within "quotes". password = 123=123 - ... is incorrect. You should use: +is incorrect. You should use: password = 123\=123 - ... or : +or: password = "123=123" @@ -95,7 +95,7 @@ You can put a backslash at the end of the line to join it to the next one. This creates one virtual line that is composed of more than one physical line. -Also, if you leave the *""* quote container open before a newline, it will +Also, if you leave the `""` quote container open before a newline, it will keep scanning until it reaches another one. If you see bizarre behavior in your configuration files, check for an unintentional instance of quotes spanning multiple lines. @@ -176,9 +176,9 @@ right one for your hardware. You might need to try other drivers by changing the "driver=" value in ups.conf. Be sure to check the driver's man page to see if it needs any extra -settings in ups.conf to detect your hardware. +settings in `ups.conf` to detect your hardware. -If it says "can't bind /var/state/ups/..." or similar, then your +If it says `can't bind /var/state/ups/...` or similar, then your state path probably isn't writable by the driver. Check the <>. @@ -204,7 +204,7 @@ NOTE: Refer to the NUT user manual <> for information on how to access and secure upsd clients connections. Next, create upsd.users. For now, this can be an empty file. -You can come back and add more to it later when it's time to +You can come back and add more to it later when it's time to configure upsmon or run one of the management tools. Do not make either file world-readable, since they both hold @@ -266,7 +266,7 @@ You should see just one line in response: OL means your system is running on line power. If it says something else (like OB - on battery, or LB - low battery), your driver was probably misconfigured during the <> -step. If you reconfigure the driver, use 'upsdrvctl stop' to stop it, then +step. If you reconfigure the driver, use `upsdrvctl stop` to stop it, then start it again as shown in the <> step. Reference: man page: linkman:upsc[8] @@ -335,7 +335,7 @@ Reference: man page: linkman:upsc[8], Startup scripts ~~~~~~~~~~~~~~~ -NOTE: This step is not need if you installed from packages. +NOTE: This step is not necessary if you installed from packages. Edit your startup scripts, and make sure upsdrvctl and upsd are run every time your system starts. @@ -347,7 +347,7 @@ Configuring automatic shutdowns for low battery events The whole point of UPS software is to bring down the OS cleanly when you run out of battery power. Everything else is roughly eye candy. -To make sure your system shuts down properly, you will need to perform some +To make sure your system shuts down properly, you will need to perform some additional configuration and run upsmon. Here are the basics. [[Shutdown_design]] @@ -384,9 +384,9 @@ The exact behavior depends on the specific device, and is related to: - call their SHUTDOWNCMD - disconnect from upsd -5. The upsmon master system waits up to HOSTSYNC seconds (typically 15) - for the slaves to disconnect from upsd. If any are connected after - this time, upsmon stops waiting and proceeds with the shutdown +5. The upsmon master system waits up to HOSTSYNC seconds (typically 15) + for the slaves to disconnect from upsd. If any are connected after + this time, upsmon stops waiting and proceeds with the shutdown process. 6. The upsmon master: @@ -433,7 +433,7 @@ References: linkman:upsd[8], linkman:upsd.users[5] Reloading the data server ^^^^^^^^^^^^^^^^^^^^^^^^^ -Reload upsd. Depending on your configuration, you may be able to +Reload upsd. Depending on your configuration, you may be able to do this without stopping upsd: /usr/local/ups/sbin/upsd -c reload @@ -441,7 +441,7 @@ do this without stopping upsd: If that doesn't work (check the syslog), just restart it: /usr/local/ups/sbin/upsd -c stop - /usr/local/ups/sbin/upsd + /usr/local/ups/sbin/upsd NOTE: if you want to make reloading work later, see the entry in the link:FAQ.html[FAQ] about starting upsd as a different user. @@ -479,7 +479,7 @@ adding sensitive data in the next step. Create a MONITOR directive for upsmon ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Edit upsmon.conf and create a MONITOR line with the UPS definition +Edit upsmon.conf and create a MONITOR line with the UPS definition (@), username and password from the <> step, and the master or slave setting. @@ -655,7 +655,7 @@ to keep this running either. After stopping driver, server and client you'll have to send the UPS the command to shutdown only if the POWERDOWNFLAG is present. Note -that most likely you'll have to allow for a grace period after sending +that most likely you'll have to allow for a grace period after sending 'upsdrvctl shutdown' since the system will still have to take a snapshot of itself after that. Not all drivers support this, so before going down this road, make sure that the one you're using does. @@ -706,7 +706,7 @@ for individual hosts: A small to medium sized data room usually has one C and a bunch of Bs. This means that there's a system (type C) hooked to the UPS which depends -on it for power. There are also some other systems in there (type B) +on it for power. There are also some other systems in there (type B) which depend on that same UPS for power, but aren't directly connected to it. @@ -715,7 +715,7 @@ of the "single C, many Bs" depending on how it's all wired. Finally, there's a special case. Type A systems are connected to a UPS's serial port, but don't depend on it for power. This usually happens when -a UPS is physically close to a box and can reach the serial port, but +a UPS is physically close to a box and can reach the serial port, but the wiring is such that it doesn't actually feed it. Once you identify a system's type, use this list to decide which of the diff --git a/docs/configure.txt b/docs/configure.txt index 9b12481..aff82c1 100644 --- a/docs/configure.txt +++ b/docs/configure.txt @@ -90,9 +90,9 @@ Verbose output can be enabled using: ASCIIDOC_VERBOSE=-v make This feature requires AsciiDoc 8.6.3 (http://www.methods.co.nz/asciidoc). - --with-lib (default: no) + --with-dev (default: no) -Build and install the upsclient library and header files. +Build and install the upsclient and nutclient library and header files. --with-all (no default) @@ -227,7 +227,7 @@ Sets the base directories for the man pages. The default is --includedir=PATH -Sets the path for include files to be installed when --with-lib is +Sets the path for include files to be installed when `--with-dev` is selected. For example, upsclient.h is installed here. The default is /include. @@ -266,7 +266,7 @@ HTML files will be installed to this path. By default, this is --with-pkgconfig-dir=PATH Where to install pkg-config *.pc files. This option only has an -effect if --with-lib is selected, and causes a pkg-config file to +effect if `--with-dev` is selected, and causes a pkg-config file to be installed in the named location. The default is /pkgconfig. diff --git a/docs/documentation.txt b/docs/documentation.txt index 4483117..ab3bd2c 100644 --- a/docs/documentation.txt +++ b/docs/documentation.txt @@ -46,11 +46,13 @@ Offsite Links ------------- [[general_powerdev_info]] -These are general information about UPS and PDU. +These are general information about UPS, PDU, ATS, PSU and SCD: - link:http://tldp.org/HOWTO/UPS-HOWTO/[UPS HOWTO] (The Linux Documentation Project) - link:http://en.wikipedia.org/wiki/Uninterruptible_power_supply[UPS on Wikipedia] - link:http://en.wikipedia.org/wiki/Power_distribution_unit[PDU on Wikipedia] +- link:https://en.wikipedia.org/wiki/Transfer_switch[Automatic Transfer Switch] +- link:https://en.wikipedia.org/wiki/Power_supply_unit_%28computer%29[Power Supply Units] - link:http://en.wikipedia.org/wiki/Solar_controller[Solar controller on Wikipedia] - link:http://www.pcguide.com/ref/power/ext/ups/over.htm[UPS on The PC Guide] diff --git a/docs/download.txt b/docs/download.txt index 3991b1c..e43ce48 100644 --- a/docs/download.txt +++ b/docs/download.txt @@ -103,11 +103,11 @@ NOTE: The only official releases from this project are source code. NUT is already available in the following systems: - Linux: -link:http://aur.archlinux.org/packages.php?ID=5379[Arch Linux], +link:https://aur.archlinux.org/packages/network-ups-tools[Arch Linux], link:http://packages.debian.org/nut[Debian], link:http://packages.gentoo.org/package/sys-power/nut[Gentoo Linux], Mandriva, -link:https://admin.fedoraproject.org/pkgdb/acls/name/nut[Red Hat / Fedora], +link:https://apps.fedoraproject.org/packages/nut[Red Hat / Fedora], link:http://software.opensuse.org/package/nut[Novell Suse / openSUSE], link:https://forum.openwrt.org/viewtopic.php?id=26269[OpenWrt], link:http://packages.ubuntu.com/nut[Ubuntu], @@ -115,16 +115,16 @@ link:https://github.com/voidlinux/xbps-packages/blob/master/srcpkgs/network-ups- - BSD systems: link:http://www.FreeBSD.org/cgi/ports.cgi?query=^nut-&stype=name[FreeBSD], -link:ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/sysutils/ups-nut/README.html[NetBSD], -link:http://www.openbsd.org/cgi-bin/cvsweb/ports/sysutils/nut/[OpenBSD], -link:http://doc.freenas.org/index.php/UPS[FreeNAS]. +link:http://pkgsrc.se/sysutils/ups-nut[NetBSD], +link:http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/sysutils/nut/[OpenBSD], +link:http://doc.freenas.org/9.3/freenas_services.html#ups[FreeNAS]. - Mac OS X: link:http://pdb.finkproject.org/pdb/package.php/nut[Fink], link:http://trac.macports.org/browser/trunk/dports/sysutils/nut/Portfile[MacPorts] - Windows (complete port, Beta): -link:http://www.networkupstools.org/package/windows/NUT-Installer-2.6.5-3.msi[Windows MSI installer 2.6.5-3] +link:http://www.networkupstools.org/package/windows/NUT-Installer-2.6.5-6.msi[Windows MSI installer 2.6.5-6] Java packages diff --git a/docs/features.txt b/docs/features.txt index 8e25259..eef38b6 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -18,10 +18,12 @@ More and more appliances manufacturers are bundling NUT... Multiple manufacturer and device support ---------------------------------------- -- Monitors many UPS, PDU and SCD models from more than 100 manufacturers with a -unified interface (link:stable-hcl.html[Hardware Compatibility List]). +- Monitors many UPS, PDU, ATS, PSU and SCD models from more than 140 +manufacturers with a unified interface +(link:stable-hcl.html[Hardware Compatibility List]). -- Various communication types are supported with the same common interface: +- Various communication types and many protocols are supported with the same +common interface: * serial, * USB, * network (SNMP, Eaton / MGE XML/HTTP). diff --git a/docs/images/nut_layering.png b/docs/images/nut_layering.png index ff451b4..41f650c 100644 Binary files a/docs/images/nut_layering.png and b/docs/images/nut_layering.png differ diff --git a/docs/man/Makefile.in b/docs/man/Makefile.in index e2fb1a8..71b13d4 100644 --- a/docs/man/Makefile.in +++ b/docs/man/Makefile.in @@ -245,6 +245,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/docs/man/al175.8 b/docs/man/al175.8 index 297d4f7..5c48bf8 100644 --- a/docs/man/al175.8 +++ b/docs/man/al175.8 @@ -2,12 +2,12 @@ .\" Title: al175 .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "AL175" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "AL175" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/apcsmart-old.8 b/docs/man/apcsmart-old.8 index dc8c5d0..d4e2d85 100644 --- a/docs/man/apcsmart-old.8 +++ b/docs/man/apcsmart-old.8 @@ -2,12 +2,12 @@ .\" Title: apcsmart-old .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "APCSMART\-OLD" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "APCSMART\-OLD" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/apcsmart.8 b/docs/man/apcsmart.8 index 7dc6cfd..30d20d5 100644 --- a/docs/man/apcsmart.8 +++ b/docs/man/apcsmart.8 @@ -2,12 +2,12 @@ .\" Title: apcsmart .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "APCSMART" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "APCSMART" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/apcupsd-ups.8 b/docs/man/apcupsd-ups.8 index a6bb2f5..9035797 100644 --- a/docs/man/apcupsd-ups.8 +++ b/docs/man/apcupsd-ups.8 @@ -2,12 +2,12 @@ .\" Title: apcupsd-ups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "APCUPSD\-UPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "APCUPSD\-UPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/asem.8 b/docs/man/asem.8 index 7f1328f..8f594e6 100644 --- a/docs/man/asem.8 +++ b/docs/man/asem.8 @@ -2,12 +2,12 @@ .\" Title: asem .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "ASEM" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "ASEM" "8" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bcmxcp.8 b/docs/man/bcmxcp.8 index 0d6fa26..3088755 100644 --- a/docs/man/bcmxcp.8 +++ b/docs/man/bcmxcp.8 @@ -2,12 +2,12 @@ .\" Title: bcmxcp .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BCMXCP" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BCMXCP" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bcmxcp_usb.8 b/docs/man/bcmxcp_usb.8 index 5e40a3e..77ed3f1 100644 --- a/docs/man/bcmxcp_usb.8 +++ b/docs/man/bcmxcp_usb.8 @@ -2,12 +2,12 @@ .\" Title: bcmxcp_usb .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BCMXCP_USB" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BCMXCP_USB" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/belkin.8 b/docs/man/belkin.8 index 9788c80..07089fa 100644 --- a/docs/man/belkin.8 +++ b/docs/man/belkin.8 @@ -2,12 +2,12 @@ .\" Title: belkin .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BELKIN" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BELKIN" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/belkinunv.8 b/docs/man/belkinunv.8 index 528147a..13d3ba5 100644 --- a/docs/man/belkinunv.8 +++ b/docs/man/belkinunv.8 @@ -2,12 +2,12 @@ .\" Title: belkinunv .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BELKINUNV" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BELKINUNV" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestfcom.8 b/docs/man/bestfcom.8 index bc55212..ec46368 100644 --- a/docs/man/bestfcom.8 +++ b/docs/man/bestfcom.8 @@ -2,12 +2,12 @@ .\" Title: bestfcom .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BESTFCOM" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BESTFCOM" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestfortress.8 b/docs/man/bestfortress.8 index 8edf6d2..130fd8c 100644 --- a/docs/man/bestfortress.8 +++ b/docs/man/bestfortress.8 @@ -2,12 +2,12 @@ .\" Title: bestfortress .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BESTFORTRESS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BESTFORTRESS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestuferrups.8 b/docs/man/bestuferrups.8 index 70338bd..b56a422 100644 --- a/docs/man/bestuferrups.8 +++ b/docs/man/bestuferrups.8 @@ -2,12 +2,12 @@ .\" Title: bestuferrups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BESTUFERRUPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BESTUFERRUPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestups.8 b/docs/man/bestups.8 index f2c5b07..0d6ab8e 100644 --- a/docs/man/bestups.8 +++ b/docs/man/bestups.8 @@ -2,12 +2,12 @@ .\" Title: bestups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BESTUPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BESTUPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/blazer_ser.8 b/docs/man/blazer_ser.8 index 883a139..1939739 100644 --- a/docs/man/blazer_ser.8 +++ b/docs/man/blazer_ser.8 @@ -2,12 +2,12 @@ .\" Title: blazer_ser .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BLAZER_SER" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BLAZER_SER" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/blazer_usb.8 b/docs/man/blazer_usb.8 index 3f6b5b7..726070c 100644 --- a/docs/man/blazer_usb.8 +++ b/docs/man/blazer_usb.8 @@ -2,12 +2,12 @@ .\" Title: blazer_usb .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "BLAZER_USB" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "BLAZER_USB" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/clone.8 b/docs/man/clone.8 index 7f92efb..9636925 100644 --- a/docs/man/clone.8 +++ b/docs/man/clone.8 @@ -2,12 +2,12 @@ .\" Title: clone .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "CLONE" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "CLONE" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/dummy-ups.8 b/docs/man/dummy-ups.8 index eaba7fd..76731e0 100644 --- a/docs/man/dummy-ups.8 +++ b/docs/man/dummy-ups.8 @@ -2,12 +2,12 @@ .\" Title: dummy-ups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "DUMMY\-UPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "DUMMY\-UPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/etapro.8 b/docs/man/etapro.8 index e327592..1a22ae7 100644 --- a/docs/man/etapro.8 +++ b/docs/man/etapro.8 @@ -2,12 +2,12 @@ .\" Title: etapro .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "ETAPRO" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "ETAPRO" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/everups.8 b/docs/man/everups.8 index 784627e..59a9e4c 100644 --- a/docs/man/everups.8 +++ b/docs/man/everups.8 @@ -2,12 +2,12 @@ .\" Title: everups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "EVERUPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "EVERUPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/gamatronic.8 b/docs/man/gamatronic.8 index 12ef3be..2453623 100644 --- a/docs/man/gamatronic.8 +++ b/docs/man/gamatronic.8 @@ -2,12 +2,12 @@ .\" Title: gamatronic .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "GAMATRONIC" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "GAMATRONIC" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/genericups.8 b/docs/man/genericups.8 index a7f883f..591a0b8 100644 --- a/docs/man/genericups.8 +++ b/docs/man/genericups.8 @@ -2,12 +2,12 @@ .\" Title: genericups .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "GENERICUPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "GENERICUPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/hosts.conf.5 b/docs/man/hosts.conf.5 index c2d62fe..45ca6cc 100644 --- a/docs/man/hosts.conf.5 +++ b/docs/man/hosts.conf.5 @@ -2,12 +2,12 @@ .\" Title: hosts.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "HOSTS\&.CONF" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "HOSTS\&.CONF" "5" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/isbmex.8 b/docs/man/isbmex.8 index 06a2041..3496fe2 100644 --- a/docs/man/isbmex.8 +++ b/docs/man/isbmex.8 @@ -2,12 +2,12 @@ .\" Title: isbmex .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "ISBMEX" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "ISBMEX" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/ivtscd.8 b/docs/man/ivtscd.8 index 66d51c7..2854115 100644 --- a/docs/man/ivtscd.8 +++ b/docs/man/ivtscd.8 @@ -2,12 +2,12 @@ .\" Title: ivtscd .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "IVTSCD" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "IVTSCD" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient.3 b/docs/man/libnutclient.3 index fced59c..1fdb60f 100644 --- a/docs/man/libnutclient.3 +++ b/docs/man/libnutclient.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient_commands.3 b/docs/man/libnutclient_commands.3 index 7a30319..649a757 100644 --- a/docs/man/libnutclient_commands.3 +++ b/docs/man/libnutclient_commands.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient_commands .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT_COMMAND" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT_COMMAND" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient_devices.3 b/docs/man/libnutclient_devices.3 index 4c048eb..5874269 100644 --- a/docs/man/libnutclient_devices.3 +++ b/docs/man/libnutclient_devices.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient_devices .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT_DEVICES" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT_DEVICES" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient_general.3 b/docs/man/libnutclient_general.3 index 4b3504e..925a2d6 100644 --- a/docs/man/libnutclient_general.3 +++ b/docs/man/libnutclient_general.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient_general .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT_GENERAL" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT_GENERAL" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient_misc.3 b/docs/man/libnutclient_misc.3 index 0d83919..0092a25 100644 --- a/docs/man/libnutclient_misc.3 +++ b/docs/man/libnutclient_misc.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient_misc .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT_MISC" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT_MISC" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient_tcp.3 b/docs/man/libnutclient_tcp.3 index b91b7b7..6460dda 100644 --- a/docs/man/libnutclient_tcp.3 +++ b/docs/man/libnutclient_tcp.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient_tcp .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT_TCP" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT_TCP" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libnutclient_variables.3 b/docs/man/libnutclient_variables.3 index da3f2ce..6819c91 100644 --- a/docs/man/libnutclient_variables.3 +++ b/docs/man/libnutclient_variables.3 @@ -2,12 +2,12 @@ .\" Title: libnutclient_variables .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBNUTCLIENT_VARIABL" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBNUTCLIENT_VARIABL" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libupsclient-config.1 b/docs/man/libupsclient-config.1 index e2a0dde..5094f7e 100644 --- a/docs/man/libupsclient-config.1 +++ b/docs/man/libupsclient-config.1 @@ -2,12 +2,12 @@ .\" Title: libupsclient-config .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIBUPSCLIENT\-CONFIG" "1" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIBUPSCLIENT\-CONFIG" "1" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/liebert-esp2.8 b/docs/man/liebert-esp2.8 index 24debf7..bd5373f 100644 --- a/docs/man/liebert-esp2.8 +++ b/docs/man/liebert-esp2.8 @@ -2,12 +2,12 @@ .\" Title: liebert-esp2 .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIEBERT\-ESP2" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIEBERT\-ESP2" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/liebert.8 b/docs/man/liebert.8 index 9600054..7fe9f6c 100644 --- a/docs/man/liebert.8 +++ b/docs/man/liebert.8 @@ -2,12 +2,12 @@ .\" Title: liebert .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "LIEBERT" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "LIEBERT" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/macosx-ups.8 b/docs/man/macosx-ups.8 index f3a8327..953fb65 100644 --- a/docs/man/macosx-ups.8 +++ b/docs/man/macosx-ups.8 @@ -2,12 +2,12 @@ .\" Title: macosx-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "MACOSX\-UPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "MACOSX\-UPS" "8" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -39,14 +39,12 @@ This man page only documents the hardware\-specific features of the \fBmacosx\-u If the UPS is visible in the Energy Saver preferences pane of System Preferences, this driver should be able to monitor it\&. .SH "EXTRA ARGUMENTS" .PP -\fBport\fR=\fIregex\fR +\fBport\fR=auto .RS 4 -The +Due to changes in the way that Mac OS X lists power sources, the \fBport\fR -parameter in the configuration file can be a case\-insensitive extended regular expression (see -\fBregex\fR(3) for details) to match against specific UPS and battery names\&. -.sp -The traditional NUT auto\-detection value of "auto" will be changed to "/UPS"\&. To test this driver against the internal battery of a laptop, a value such as "battery" can be used\&. +parameter no longer has any effect\&. The rest of NUT still requres a value here, and our traditional "don\(cqt care" value is +auto\&. .RE .PP \fBmodel\fR=\fIregex\fR diff --git a/docs/man/macosx-ups.txt b/docs/man/macosx-ups.txt index 9202f5b..956abde 100644 --- a/docs/man/macosx-ups.txt +++ b/docs/man/macosx-ups.txt @@ -23,40 +23,16 @@ Preferences, this driver should be able to monitor it. EXTRA ARGUMENTS ---------------- -*port*='regex':: -The *port* parameter in the configuration file can be a case-insensitive -extended regular expression (see *regex*(3) for details) to match against -specific UPS and battery names. -+ -The traditional NUT auto-detection value of "auto" will be changed to "/UPS". -To test this driver against the internal battery of a laptop, a value such as -"battery" can be used. +*port*=auto:: +Due to changes in the way that Mac OS X lists power sources, the *port* +parameter no longer has any effect. The rest of NUT still requres a value here, +and our traditional "don't care" value is `auto`. *model*='regex':: Likewise, if you have more than one UPS, it may be necessary to specify a *model* name to match against. This parameter is also a case-insensitive extended regular expression. -////////////////////////////////////////// -This driver also supports the following optional settings: - -*option1*='num':: -Set the value of ... to 'num'. Contrast with *option2*. - -*option2*='string':: -Some other option. -////////////////////////////////////////// - -////////////////////////////////////////// -Optional: list supported instant commands here: - -INSTANT COMMANDS ----------------- - -*instcmd1*:: -Command 1. -////////////////////////////////////////// - DIAGNOSTICS ----------- diff --git a/docs/man/masterguard.8 b/docs/man/masterguard.8 index f793cff..0947360 100644 --- a/docs/man/masterguard.8 +++ b/docs/man/masterguard.8 @@ -2,12 +2,12 @@ .\" Title: masterguard .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "MASTERGUARD" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "MASTERGUARD" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/metasys.8 b/docs/man/metasys.8 index 321d8c6..0ef74a8 100644 --- a/docs/man/metasys.8 +++ b/docs/man/metasys.8 @@ -2,12 +2,12 @@ .\" Title: metasys .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "METASYS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "METASYS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/mge-shut.8 b/docs/man/mge-shut.8 index fd0fb04..c3faf44 100644 --- a/docs/man/mge-shut.8 +++ b/docs/man/mge-shut.8 @@ -2,12 +2,12 @@ .\" Title: mge-shut .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "MGE\-SHUT" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "MGE\-SHUT" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/mge-utalk.8 b/docs/man/mge-utalk.8 index c8dac81..0c8d5d9 100644 --- a/docs/man/mge-utalk.8 +++ b/docs/man/mge-utalk.8 @@ -2,12 +2,12 @@ .\" Title: mge-utalk .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "MGE\-UTALK" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "MGE\-UTALK" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/microdowell.8 b/docs/man/microdowell.8 index 2252f58..86eb1a8 100644 --- a/docs/man/microdowell.8 +++ b/docs/man/microdowell.8 @@ -2,12 +2,12 @@ .\" Title: microdowell .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "MICRODOWELL" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "MICRODOWELL" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/netxml-ups.8 b/docs/man/netxml-ups.8 index 3784370..3548020 100644 --- a/docs/man/netxml-ups.8 +++ b/docs/man/netxml-ups.8 @@ -2,12 +2,12 @@ .\" Title: netxml-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NETXML\-UPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NETXML\-UPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nut-ipmipsu.8 b/docs/man/nut-ipmipsu.8 index aa2d1a5..c5fb963 100644 --- a/docs/man/nut-ipmipsu.8 +++ b/docs/man/nut-ipmipsu.8 @@ -2,12 +2,12 @@ .\" Title: nut-ipmipsu .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUT\-IPMIPSU" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUT\-IPMIPSU" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nut-recorder.8 b/docs/man/nut-recorder.8 index 54d6f50..1b03f48 100644 --- a/docs/man/nut-recorder.8 +++ b/docs/man/nut-recorder.8 @@ -2,12 +2,12 @@ .\" Title: nut-recorder .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUT\-RECORDER" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUT\-RECORDER" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nut-scanner.8 b/docs/man/nut-scanner.8 index 8cb91fd..a18ba23 100644 --- a/docs/man/nut-scanner.8 +++ b/docs/man/nut-scanner.8 @@ -2,12 +2,12 @@ .\" Title: nut-scanner .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUT\-SCANNER" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUT\-SCANNER" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nut.conf.5 b/docs/man/nut.conf.5 index d291731..f7b7e24 100644 --- a/docs/man/nut.conf.5 +++ b/docs/man/nut.conf.5 @@ -2,12 +2,12 @@ .\" Title: nut.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUT\&.CONF" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUT\&.CONF" "5" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutdrv_atcl_usb.8 b/docs/man/nutdrv_atcl_usb.8 index 7f73147..540c12e 100644 --- a/docs/man/nutdrv_atcl_usb.8 +++ b/docs/man/nutdrv_atcl_usb.8 @@ -2,12 +2,12 @@ .\" Title: nutdrv_atcl_usb .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/09/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTDRV_ATCL_USB" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTDRV_ATCL_USB" "8" "03/09/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -34,7 +34,7 @@ nutdrv_atcl_usb \- Driver for \*(AqATCL FOR UPS\*(Aq equipment This man page only documents the specific features of the nutdrv_atcl_usb driver\&. For information about the core driver, see \fBnutupsdrv\fR(8)\&. .SH "SUPPORTED HARDWARE" .sp -This driver is for UPS hardware which identifies itself as USB idVendor 0001 and idProduct 0000, and iManufacturer ATCL FOR UPS\&. Known manufacturers include Kanji and Plexus\&. The UPS interface seems to be a USB frontend to a traditional contact\-closure interface, which translates into only three states in ups\&.status: \fBOL\fR, \fBOB\fR and \fBOB LB\fR\&. See also \fBgenericups\fR(8)\&. +This driver is for UPS hardware which identifies itself as USB idVendor 0001 and idProduct 0000, and iManufacturer ATCL FOR UPS\&. Known manufacturers include Kanji and Plexus\&. The UPS interface seems to be a generic USB\-to\-serial chip, and for hardware manufactured by Kanji and Plexus, the microcontroller appears to emulate a traditional contact\-closure interface\&. This translates into only three states in ups\&.status: \fBOL\fR, \fBOB\fR and \fBOB LB\fR (similar to \fBgenericups\fR(8)), with no other dynamic status values reported\&. Note that these USB identifiers (including the iManufacturer string) have also been seen on devices that are supported by the fuji subdriver of \fBnutdrv_qx\fR(8)\&. .SH "EXTRA ARGUMENTS" .sp This driver supports the following optional setting: @@ -66,7 +66,7 @@ Charles Lepple \fBgenericups\fR(8) .SS "The Qx driver:" .sp -\fBnutdrv_qx\fR(8) +\fBnutdrv_qx\fR(8) (fuji subdriver) .SS "Internet resources:" .sp The NUT (Network UPS Tools) home page: http://www\&.networkupstools\&.org/ diff --git a/docs/man/nutdrv_atcl_usb.txt b/docs/man/nutdrv_atcl_usb.txt index 18f9257..8443e4a 100644 --- a/docs/man/nutdrv_atcl_usb.txt +++ b/docs/man/nutdrv_atcl_usb.txt @@ -14,9 +14,13 @@ SUPPORTED HARDWARE ------------------ This driver is for UPS hardware which identifies itself as USB idVendor 0001 and idProduct 0000, and iManufacturer +ATCL FOR UPS+. Known manufacturers -include Kanji and Plexus. The UPS interface seems to be a USB frontend to a -traditional contact-closure interface, which translates into only three states -in ups.status: *OL*, *OB* and *OB LB*. See also linkman:genericups[8]. +include Kanji and Plexus. The UPS interface seems to be a generic USB-to-serial +chip, and for hardware manufactured by Kanji and Plexus, the microcontroller +appears to emulate a traditional contact-closure interface. This translates +into only three states in ups.status: *OL*, *OB* and *OB LB* (similar to +linkman:genericups[8]), with no other dynamic status values reported. Note that +these USB identifiers (including the iManufacturer string) have also been seen +on devices that are supported by the `fuji` subdriver of linkman:nutdrv_qx[8]. EXTRA ARGUMENTS --------------- @@ -63,7 +67,7 @@ linkman:genericups[8] The Qx driver: ~~~~~~~~~~~~~~ -linkman:nutdrv_qx[8] +linkman:nutdrv_qx[8] (`fuji` subdriver) Internet resources: ~~~~~~~~~~~~~~~~~~~ diff --git a/docs/man/nutdrv_qx.8 b/docs/man/nutdrv_qx.8 index df98321..59e946f 100644 --- a/docs/man/nutdrv_qx.8 +++ b/docs/man/nutdrv_qx.8 @@ -2,12 +2,12 @@ .\" Title: nutdrv_qx .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/22/2015 +.\" Date: 03/09/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTDRV_QX" "8" "04/22/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTDRV_QX" "8" "03/09/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -558,9 +558,10 @@ Select a serial\-over\-USB subdriver to use\&. You have a choice between \fBfabula\fR, \fBfuji\fR, \fBippon\fR, -\fBkrauler\fR +\fBkrauler\fR, +\fBphoenix\fR and -\fBphoenix\fR\&. When using this option, it is mandatory to also specify the +\fBsgs\fR\&. When using this option, it is mandatory to also specify the \fBvendorid\fR and \fBproductid\fR\&. diff --git a/docs/man/nutdrv_qx.txt b/docs/man/nutdrv_qx.txt index 5d08901..5436131 100644 --- a/docs/man/nutdrv_qx.txt +++ b/docs/man/nutdrv_qx.txt @@ -322,7 +322,7 @@ The argument is a regular expression that must match the bus name where the UPS *subdriver =* 'string':: Select a serial-over-USB subdriver to use. -You have a choice between *cypress*, *fabula*, *fuji*, *ippon*, *krauler* and *phoenix*. +You have a choice between *cypress*, *fabula*, *fuji*, *ippon*, *krauler*, *phoenix* and *sgs*. When using this option, it is mandatory to also specify the *vendorid* and *productid*. *langid_fix =* 'value':: diff --git a/docs/man/nutscan.3 b/docs/man/nutscan.3 index 49211d7..6b93089 100644 --- a/docs/man/nutscan.3 +++ b/docs/man/nutscan.3 @@ -2,12 +2,12 @@ .\" Title: nutscan .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_add_device_to_device.3 b/docs/man/nutscan_add_device_to_device.3 index f98dfac..5f51677 100644 --- a/docs/man/nutscan_add_device_to_device.3 +++ b/docs/man/nutscan_add_device_to_device.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_add_device_to_device .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_ADD_DEVICE_T" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_ADD_DEVICE_T" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_add_option_to_device.3 b/docs/man/nutscan_add_option_to_device.3 index c591587..3db6a23 100644 --- a/docs/man/nutscan_add_option_to_device.3 +++ b/docs/man/nutscan_add_option_to_device.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_add_option_to_device .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_ADD_OPTION_T" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_ADD_OPTION_T" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_cidr_to_ip.3 b/docs/man/nutscan_cidr_to_ip.3 index aedb836..c9f68c5 100644 --- a/docs/man/nutscan_cidr_to_ip.3 +++ b/docs/man/nutscan_cidr_to_ip.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_cidr_to_ip .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_CIDR_TO_IP" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_CIDR_TO_IP" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_display_parsable.3 b/docs/man/nutscan_display_parsable.3 index 0b1ac06..33f7ec9 100644 --- a/docs/man/nutscan_display_parsable.3 +++ b/docs/man/nutscan_display_parsable.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_display_parsable .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_DISPLAY_PARS" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_DISPLAY_PARS" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_display_ups_conf.3 b/docs/man/nutscan_display_ups_conf.3 index 6df43c5..0b1c6d5 100644 --- a/docs/man/nutscan_display_ups_conf.3 +++ b/docs/man/nutscan_display_ups_conf.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_display_ups_conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_DISPLAY_UPS_" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_DISPLAY_UPS_" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_free_device.3 b/docs/man/nutscan_free_device.3 index 962cd4b..af13c90 100644 --- a/docs/man/nutscan_free_device.3 +++ b/docs/man/nutscan_free_device.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_free_device .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_FREE_DEVICE" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_FREE_DEVICE" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_get_serial_ports_list.3 b/docs/man/nutscan_get_serial_ports_list.3 index 567eb8e..12fb92c 100644 --- a/docs/man/nutscan_get_serial_ports_list.3 +++ b/docs/man/nutscan_get_serial_ports_list.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_get_serial_ports_list .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_GET_SERIAL_P" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_GET_SERIAL_P" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_init.3 b/docs/man/nutscan_init.3 index 0691ee5..bad6e1e 100644 --- a/docs/man/nutscan_init.3 +++ b/docs/man/nutscan_init.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_init .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_INIT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_INIT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_new_device.3 b/docs/man/nutscan_new_device.3 index 9bdcab1..1196eff 100644 --- a/docs/man/nutscan_new_device.3 +++ b/docs/man/nutscan_new_device.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_new_device .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_NEW_DEVICE" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_NEW_DEVICE" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_avahi.3 b/docs/man/nutscan_scan_avahi.3 index 921d61f..61ac99f 100644 --- a/docs/man/nutscan_scan_avahi.3 +++ b/docs/man/nutscan_scan_avahi.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_avahi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_AVAHI" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_AVAHI" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_eaton_serial.3 b/docs/man/nutscan_scan_eaton_serial.3 index 13f2bdf..8f5df50 100644 --- a/docs/man/nutscan_scan_eaton_serial.3 +++ b/docs/man/nutscan_scan_eaton_serial.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_eaton_serial .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_EATON_S" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_EATON_S" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_ipmi.3 b/docs/man/nutscan_scan_ipmi.3 index c782ec7..51a9f36 100644 --- a/docs/man/nutscan_scan_ipmi.3 +++ b/docs/man/nutscan_scan_ipmi.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_ipmi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_IPMI" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_IPMI" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_nut.3 b/docs/man/nutscan_scan_nut.3 index d3e34d7..68487e1 100644 --- a/docs/man/nutscan_scan_nut.3 +++ b/docs/man/nutscan_scan_nut.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_nut .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_NUT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_NUT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_snmp.3 b/docs/man/nutscan_scan_snmp.3 index 40cdb3b..6db38fe 100644 --- a/docs/man/nutscan_scan_snmp.3 +++ b/docs/man/nutscan_scan_snmp.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_snmp .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_SNMP" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_SNMP" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_usb.3 b/docs/man/nutscan_scan_usb.3 index fca4e54..d3c8fb9 100644 --- a/docs/man/nutscan_scan_usb.3 +++ b/docs/man/nutscan_scan_usb.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_usb .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_USB" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_USB" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_scan_xml_http.3 b/docs/man/nutscan_scan_xml_http.3 index 64a6797..4a1161a 100644 --- a/docs/man/nutscan_scan_xml_http.3 +++ b/docs/man/nutscan_scan_xml_http.3 @@ -2,12 +2,12 @@ .\" Title: nutscan_scan_xml_http .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTSCAN_SCAN_XML_HTT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTSCAN_SCAN_XML_HTT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutupsdrv.8 b/docs/man/nutupsdrv.8 index 234f103..daa4556 100644 --- a/docs/man/nutupsdrv.8 +++ b/docs/man/nutupsdrv.8 @@ -2,12 +2,12 @@ .\" Title: nutupsdrv .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "NUTUPSDRV" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "NUTUPSDRV" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/oneac.8 b/docs/man/oneac.8 index 4b69624..3187817 100644 --- a/docs/man/oneac.8 +++ b/docs/man/oneac.8 @@ -2,12 +2,12 @@ .\" Title: oneac .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "ONEAC" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "ONEAC" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/optiups.8 b/docs/man/optiups.8 index 6713849..140e059 100644 --- a/docs/man/optiups.8 +++ b/docs/man/optiups.8 @@ -2,12 +2,12 @@ .\" Title: optiups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "OPTIUPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "OPTIUPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/powercom.8 b/docs/man/powercom.8 index 6782a26..a90dfbe 100644 --- a/docs/man/powercom.8 +++ b/docs/man/powercom.8 @@ -2,12 +2,12 @@ .\" Title: powercom .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "POWERCOM" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "POWERCOM" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/powerman-pdu.8 b/docs/man/powerman-pdu.8 index 23549ea..6102f27 100644 --- a/docs/man/powerman-pdu.8 +++ b/docs/man/powerman-pdu.8 @@ -2,12 +2,12 @@ .\" Title: powerman-pdu .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "POWERMAN\-PDU" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "POWERMAN\-PDU" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/powerpanel.8 b/docs/man/powerpanel.8 index 1ca1c84..baa7969 100644 --- a/docs/man/powerpanel.8 +++ b/docs/man/powerpanel.8 @@ -2,12 +2,12 @@ .\" Title: powerpanel .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "POWERPANEL" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "POWERPANEL" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/rhino.8 b/docs/man/rhino.8 index f13dc8f..c1432dc 100644 --- a/docs/man/rhino.8 +++ b/docs/man/rhino.8 @@ -2,12 +2,12 @@ .\" Title: rhino .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "RHINO" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "RHINO" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/richcomm_usb.8 b/docs/man/richcomm_usb.8 index b171425..7d8e45c 100644 --- a/docs/man/richcomm_usb.8 +++ b/docs/man/richcomm_usb.8 @@ -2,12 +2,12 @@ .\" Title: richcomm_usb .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "RICHCOMM_USB" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "RICHCOMM_USB" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/riello_ser.8 b/docs/man/riello_ser.8 index e4f41fe..a8dcedc 100644 --- a/docs/man/riello_ser.8 +++ b/docs/man/riello_ser.8 @@ -2,12 +2,12 @@ .\" Title: riello_ser .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "RIELLO_SER" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "RIELLO_SER" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/riello_usb.8 b/docs/man/riello_usb.8 index b29e0ba..b3c64ed 100644 --- a/docs/man/riello_usb.8 +++ b/docs/man/riello_usb.8 @@ -2,12 +2,12 @@ .\" Title: riello_usb .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "RIELLO_USB" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "RIELLO_USB" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/safenet.8 b/docs/man/safenet.8 index 2cdd042..1ef348b 100644 --- a/docs/man/safenet.8 +++ b/docs/man/safenet.8 @@ -2,12 +2,12 @@ .\" Title: safenet .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "SAFENET" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "SAFENET" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/snmp-ups.8 b/docs/man/snmp-ups.8 index 594e1bf..ceda716 100644 --- a/docs/man/snmp-ups.8 +++ b/docs/man/snmp-ups.8 @@ -2,12 +2,12 @@ .\" Title: snmp-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "SNMP\-UPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "SNMP\-UPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -61,6 +61,11 @@ Socomec Sicon UPS with Netvision Web/SNMP management card/external box Powerware devices with ConnectUPS SNMP cards .RE .PP +\fBpxgx_ups\fR +.RS 4 +Eaton devices with Power Xpert Gateway UPS Card +.RE +.PP \fBaphel_genesisII\fR .RS 4 Eaton Powerware ePDU Monitored @@ -90,6 +95,11 @@ HP/Compaq AF401A management card, perhaps others .RS 4 Cyberpower RMCARD201\&. Should also support RMCARD100 (net version), RMCARD202 and RMCARD301 .RE +.PP +\fBhuawei\fR +.RS 4 +Huawei UPS5000\-E, perhaps others +.RE .SH "EXTRA ARGUMENTS" .sp This driver supports the following optional settings in the \fBups.conf\fR(5): @@ -109,6 +119,16 @@ Set community name (default = public)\&. Note that a RW community name is requir Set SNMP version (default = v1, allowed: v2c, v3) .RE .PP +\fBsnmp_retries\fR=\fIretries\fR +.RS 4 +Specifies the number of Net\-SNMP retries to be used in the requests (default=5) +.RE +.PP +\fBsnmp_timeout\fR=\fItimeout\fR +.RS 4 +Specifies the Net\-SNMP timeout in seconds between retries (default=1) +.RE +.PP \fBpollfreq\fR=\fIvalue\fR .RS 4 Set polling frequency in seconds, to reduce network flow (default=30) diff --git a/docs/man/snmp-ups.txt b/docs/man/snmp-ups.txt index 3ec3a52..bdad553 100644 --- a/docs/man/snmp-ups.txt +++ b/docs/man/snmp-ups.txt @@ -32,6 +32,10 @@ Socomec Sicon UPS with Netvision Web/SNMP management card/external box *pw*:: Powerware devices with ConnectUPS SNMP cards +*pxgx_ups*:: +Eaton devices with Power Xpert Gateway UPS Card + + *aphel_genesisII*:: Eaton Powerware ePDU Monitored @@ -50,6 +54,9 @@ HP/Compaq AF401A management card, perhaps others *cyberpower*:: Cyberpower RMCARD201. Should also support RMCARD100 (net version), RMCARD202 and RMCARD301 +*huawei*:: +Huawei UPS5000-E, perhaps others + EXTRA ARGUMENTS --------------- @@ -70,6 +77,12 @@ Note that a RW community name is required to change UPS settings (as for a power *snmp_version*='version':: Set SNMP version (default = v1, allowed: v2c, v3) +*snmp_retries*='retries':: +Specifies the number of Net-SNMP retries to be used in the requests (default=5) + +*snmp_timeout*='timeout':: +Specifies the Net-SNMP timeout in seconds between retries (default=1) + *pollfreq*='value':: Set polling frequency in seconds, to reduce network flow (default=30) diff --git a/docs/man/solis.8 b/docs/man/solis.8 index 434079e..0893cd1 100644 --- a/docs/man/solis.8 +++ b/docs/man/solis.8 @@ -2,12 +2,12 @@ .\" Title: solis .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "SOLIS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "SOLIS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/tripplite.8 b/docs/man/tripplite.8 index f8fde31..65338cf 100644 --- a/docs/man/tripplite.8 +++ b/docs/man/tripplite.8 @@ -2,12 +2,12 @@ .\" Title: tripplite .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "TRIPPLITE" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "TRIPPLITE" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/tripplite_usb.8 b/docs/man/tripplite_usb.8 index 82e80a5..86714da 100644 --- a/docs/man/tripplite_usb.8 +++ b/docs/man/tripplite_usb.8 @@ -2,12 +2,12 @@ .\" Title: tripplite_usb .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "TRIPPLITE_USB" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "TRIPPLITE_USB" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/tripplitesu.8 b/docs/man/tripplitesu.8 index afb2789..da3f79e 100644 --- a/docs/man/tripplitesu.8 +++ b/docs/man/tripplitesu.8 @@ -2,12 +2,12 @@ .\" Title: tripplitesu .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "TRIPPLITESU" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "TRIPPLITESU" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/ups.conf.5 b/docs/man/ups.conf.5 index 835ae8e..f76c73a 100644 --- a/docs/man/ups.conf.5 +++ b/docs/man/ups.conf.5 @@ -2,12 +2,12 @@ .\" Title: ups.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/22/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPS\&.CONF" "5" "04/22/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPS\&.CONF" "5" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -110,7 +110,19 @@ Optional\&. The status of the UPS will be refreshed after a maximum delay which \fBsynchronous\fR .RS 4 Optional\&. The driver work by default in asynchronous mode (i\&.e -\fBsynchronous=no\fR)\&. This means that all data are pushed by the driver on the communication socket to upsd (Unix socket on Unix, Named pipe on Windows) without waiting for these data to be actually consumed\&. With some HW, such as ePDUs, that can produce a lot of data, asynchronous mode may cause some congestion, resulting in the socket to be full, and the driver to appear as not connected\&. By enabling the +\fBsynchronous=no\fR)\&. This means that all data are pushed by the driver on the communication socket to upsd (Unix socket on Unix, Named pipe on Windows) without waiting for these data to be actually consumed\&. With some HW, such as ePDUs, that can produce a lot of data, asynchronous mode may cause some congestion, resulting in the socket to be full, and the driver to appear as not connected\&. In such case, the driver will provide the following debug message: +.sp +.if n \{\ +.RS 4 +.\} +.nf +write XX bytes to socket Y failed +.fi +.if n \{\ +.RE +.\} +.sp +By enabling the \fIsynchronous\fR flag (value = \fIyes\fR), the driver will wait for data to be consumed by upsd, prior to publishing more\&. This can be enabled either globally or per driver\&. diff --git a/docs/man/ups.conf.txt b/docs/man/ups.conf.txt index dd145bd..235f015 100644 --- a/docs/man/ups.conf.txt +++ b/docs/man/ups.conf.txt @@ -88,10 +88,14 @@ on the communication socket to upsd (Unix socket on Unix, Named pipe on Windows) without waiting for these data to be actually consumed. With some HW, such as ePDUs, that can produce a lot of data, asynchronous mode may cause some congestion, resulting in the socket to -be full, and the driver to appear as not connected. By enabling the -'synchronous' flag (value = 'yes'), the driver will wait for data to be -consumed by upsd, prior to publishing more. This can be enabled either -globally or per driver. +be full, and the driver to appear as not connected. In such case, the +driver will provide the following debug message: ++ + write XX bytes to socket Y failed ++ +By enabling the 'synchronous' flag (value = 'yes'), the driver will wait +for data to be consumed by upsd, prior to publishing more. This can be +enabled either globally or per driver. + The default is 'no' (i.e. asynchronous mode) for backward compatibility of the driver behavior. diff --git a/docs/man/upsc.8 b/docs/man/upsc.8 index 1914da4..49984ab 100644 --- a/docs/man/upsc.8 +++ b/docs/man/upsc.8 @@ -2,12 +2,12 @@ .\" Title: upsc .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSC" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSC" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_add_host_cert.3 b/docs/man/upscli_add_host_cert.3 index aff4f80..127473b 100644 --- a/docs/man/upscli_add_host_cert.3 +++ b/docs/man/upscli_add_host_cert.3 @@ -2,12 +2,12 @@ .\" Title: upscli_add_host_cert .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_ADD_HOST_CERT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_ADD_HOST_CERT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_cleanup.3 b/docs/man/upscli_cleanup.3 index 4ed07ef..22d6626 100644 --- a/docs/man/upscli_cleanup.3 +++ b/docs/man/upscli_cleanup.3 @@ -2,12 +2,12 @@ .\" Title: upscli_cleanup .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_CLEANUP" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_CLEANUP" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_connect.3 b/docs/man/upscli_connect.3 index bf5e5ff..560f7a5 100644 --- a/docs/man/upscli_connect.3 +++ b/docs/man/upscli_connect.3 @@ -2,12 +2,12 @@ .\" Title: upscli_connect .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_CONNECT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_CONNECT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_disconnect.3 b/docs/man/upscli_disconnect.3 index 05dd513..7e28869 100644 --- a/docs/man/upscli_disconnect.3 +++ b/docs/man/upscli_disconnect.3 @@ -2,12 +2,12 @@ .\" Title: upscli_disconnect .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_DISCONNECT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_DISCONNECT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_fd.3 b/docs/man/upscli_fd.3 index 9efb4cf..27844c0 100644 --- a/docs/man/upscli_fd.3 +++ b/docs/man/upscli_fd.3 @@ -2,12 +2,12 @@ .\" Title: upscli_fd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_FD" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_FD" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_get.3 b/docs/man/upscli_get.3 index 590711f..fd8615f 100644 --- a/docs/man/upscli_get.3 +++ b/docs/man/upscli_get.3 @@ -2,12 +2,12 @@ .\" Title: upscli_get .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_GET" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_GET" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_init.3 b/docs/man/upscli_init.3 index 67afe20..9e8712d 100644 --- a/docs/man/upscli_init.3 +++ b/docs/man/upscli_init.3 @@ -2,12 +2,12 @@ .\" Title: upscli_init .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_INIT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_INIT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_list_next.3 b/docs/man/upscli_list_next.3 index 00a231d..af8a324 100644 --- a/docs/man/upscli_list_next.3 +++ b/docs/man/upscli_list_next.3 @@ -2,12 +2,12 @@ .\" Title: upscli_list_next .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_LIST_NEXT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_LIST_NEXT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_list_start.3 b/docs/man/upscli_list_start.3 index e26f750..e9022a1 100644 --- a/docs/man/upscli_list_start.3 +++ b/docs/man/upscli_list_start.3 @@ -2,12 +2,12 @@ .\" Title: upscli_list_start .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_LIST_START" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_LIST_START" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_readline.3 b/docs/man/upscli_readline.3 index 523bbdc..0846adf 100644 --- a/docs/man/upscli_readline.3 +++ b/docs/man/upscli_readline.3 @@ -2,12 +2,12 @@ .\" Title: upscli_readline .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_READLINE" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_READLINE" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_sendline.3 b/docs/man/upscli_sendline.3 index 61bfac1..f9648a2 100644 --- a/docs/man/upscli_sendline.3 +++ b/docs/man/upscli_sendline.3 @@ -2,12 +2,12 @@ .\" Title: upscli_sendline .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_SENDLINE" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_SENDLINE" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_splitaddr.3 b/docs/man/upscli_splitaddr.3 index ec231d7..e04f0de 100644 --- a/docs/man/upscli_splitaddr.3 +++ b/docs/man/upscli_splitaddr.3 @@ -2,12 +2,12 @@ .\" Title: upscli_splitaddr .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_SPLITADDR" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_SPLITADDR" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_splitname.3 b/docs/man/upscli_splitname.3 index bfd993b..f802e98 100644 --- a/docs/man/upscli_splitname.3 +++ b/docs/man/upscli_splitname.3 @@ -2,12 +2,12 @@ .\" Title: upscli_splitname .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_SPLITNAME" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_SPLITNAME" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_ssl.3 b/docs/man/upscli_ssl.3 index a5b5bc1..c185e09 100644 --- a/docs/man/upscli_ssl.3 +++ b/docs/man/upscli_ssl.3 @@ -2,12 +2,12 @@ .\" Title: upscli_ssl .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_SSL" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_SSL" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_strerror.3 b/docs/man/upscli_strerror.3 index af15ed9..8e18095 100644 --- a/docs/man/upscli_strerror.3 +++ b/docs/man/upscli_strerror.3 @@ -2,12 +2,12 @@ .\" Title: upscli_strerror .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_STRERROR" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_STRERROR" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_upserror.3 b/docs/man/upscli_upserror.3 index b2f2d9c..ab54701 100644 --- a/docs/man/upscli_upserror.3 +++ b/docs/man/upscli_upserror.3 @@ -2,12 +2,12 @@ .\" Title: upscli_upserror .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLI_UPSERROR" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLI_UPSERROR" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsclient.3 b/docs/man/upsclient.3 index 8583d22..570b8ce 100644 --- a/docs/man/upsclient.3 +++ b/docs/man/upsclient.3 @@ -2,12 +2,12 @@ .\" Title: upsclient .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCLIENT" "3" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCLIENT" "3" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscmd.8 b/docs/man/upscmd.8 index f86c873..d673c33 100644 --- a/docs/man/upscmd.8 +++ b/docs/man/upscmd.8 @@ -2,12 +2,12 @@ .\" Title: upscmd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCMD" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCMD" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscode2.8 b/docs/man/upscode2.8 index 3163168..cadbfd4 100644 --- a/docs/man/upscode2.8 +++ b/docs/man/upscode2.8 @@ -2,12 +2,12 @@ .\" Title: upscode2 .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSCODE2" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSCODE2" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsd.8 b/docs/man/upsd.8 index 5c81855..1c6281e 100644 --- a/docs/man/upsd.8 +++ b/docs/man/upsd.8 @@ -2,12 +2,12 @@ .\" Title: upsd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSD" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSD" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsd.conf.5 b/docs/man/upsd.conf.5 index 24dc318..a27a048 100644 --- a/docs/man/upsd.conf.5 +++ b/docs/man/upsd.conf.5 @@ -2,12 +2,12 @@ .\" Title: upsd.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSD\&.CONF" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSD\&.CONF" "5" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsd.users.5 b/docs/man/upsd.users.5 index 7367139..9373bb7 100644 --- a/docs/man/upsd.users.5 +++ b/docs/man/upsd.users.5 @@ -2,12 +2,12 @@ .\" Title: upsd.users .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSD\&.USERS" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSD\&.USERS" "5" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsdrvctl.8 b/docs/man/upsdrvctl.8 index ae4e846..1acb6d8 100644 --- a/docs/man/upsdrvctl.8 +++ b/docs/man/upsdrvctl.8 @@ -2,12 +2,12 @@ .\" Title: upsdrvctl .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSDRVCTL" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSDRVCTL" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsimage.cgi.8 b/docs/man/upsimage.cgi.8 index 6464d23..601ebe5 100644 --- a/docs/man/upsimage.cgi.8 +++ b/docs/man/upsimage.cgi.8 @@ -2,12 +2,12 @@ .\" Title: upsimage.cgi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSIMAGE\&.CGI" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSIMAGE\&.CGI" "8" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upslog.8 b/docs/man/upslog.8 index a79cf23..c0ecff4 100644 --- a/docs/man/upslog.8 +++ b/docs/man/upslog.8 @@ -2,12 +2,12 @@ .\" Title: upslog .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSLOG" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSLOG" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsmon.8 b/docs/man/upsmon.8 index 9421226..9f21c21 100644 --- a/docs/man/upsmon.8 +++ b/docs/man/upsmon.8 @@ -2,12 +2,12 @@ .\" Title: upsmon .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSMON" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSMON" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsmon.conf.5 b/docs/man/upsmon.conf.5 index d2e3526..2323abb 100644 --- a/docs/man/upsmon.conf.5 +++ b/docs/man/upsmon.conf.5 @@ -2,12 +2,12 @@ .\" Title: upsmon.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSMON\&.CONF" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSMON\&.CONF" "5" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsrw.8 b/docs/man/upsrw.8 index ed61839..7c9343b 100644 --- a/docs/man/upsrw.8 +++ b/docs/man/upsrw.8 @@ -2,12 +2,12 @@ .\" Title: upsrw .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/09/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSRW" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSRW" "8" "03/09/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -93,6 +93,9 @@ Moreover, if you run this program inside a shell script or similar, you should o .SH "DIAGNOSTICS" .sp \fBupsrw\fR can\(cqt set variables on your UPS unless you provide a valid username and password\&. If you get "access denied" errors, make sure that your \fBupsd.users\fR(5) has an entry for you, and that the username you are using has permissions to SET variables\&. +.SH "VALUE FORMAT" +.sp +When using \fBupsrw\fR to modify a numeric float value, that values must be given using decimal (base 10) english\-based representation, so using a dot, in non\-scientific notation\&. So hexadecimal, exponents, and comma for thousands separator are forbiden\&. For example: "1200\&.20" is valid, while "1,200\&.20" and "1200,20" are invalid\&. .SH "HISTORY" .sp This program used to be called upsct2, which was ambiguous and confusing\&. diff --git a/docs/man/upsrw.txt b/docs/man/upsrw.txt index de09067..0e3bfcf 100644 --- a/docs/man/upsrw.txt +++ b/docs/man/upsrw.txt @@ -84,6 +84,15 @@ username and password. If you get "access denied" errors, make sure that your linkman:upsd.users[5] has an entry for you, and that the username you are using has permissions to SET variables. +VALUE FORMAT +------------ + +When using *upsrw* to modify a numeric float value, that values must be given +using decimal (base 10) english-based representation, so using a dot, in +non-scientific notation. So hexadecimal, exponents, and comma for thousands +separator are forbiden. +For example: "1200.20" is valid, while "1,200.20" and "1200,20" are invalid. + HISTORY ------- diff --git a/docs/man/upssched.8 b/docs/man/upssched.8 index 0c3f838..5bc9c56 100644 --- a/docs/man/upssched.8 +++ b/docs/man/upssched.8 @@ -2,12 +2,12 @@ .\" Title: upssched .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSSCHED" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSSCHED" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upssched.conf.5 b/docs/man/upssched.conf.5 index 8770d33..7f5363b 100644 --- a/docs/man/upssched.conf.5 +++ b/docs/man/upssched.conf.5 @@ -2,12 +2,12 @@ .\" Title: upssched.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSSCHED\&.CONF" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSSCHED\&.CONF" "5" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsset.cgi.8 b/docs/man/upsset.cgi.8 index d74c140..c45c073 100644 --- a/docs/man/upsset.cgi.8 +++ b/docs/man/upsset.cgi.8 @@ -2,12 +2,12 @@ .\" Title: upsset.cgi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSSET\&.CGI" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSSET\&.CGI" "8" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsset.conf.5 b/docs/man/upsset.conf.5 index 4292322..a1abd5f 100644 --- a/docs/man/upsset.conf.5 +++ b/docs/man/upsset.conf.5 @@ -2,12 +2,12 @@ .\" Title: upsset.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSSET\&.CONF" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSSET\&.CONF" "5" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsstats.cgi.8 b/docs/man/upsstats.cgi.8 index 4a2aea9..d627ee8 100644 --- a/docs/man/upsstats.cgi.8 +++ b/docs/man/upsstats.cgi.8 @@ -2,12 +2,12 @@ .\" Title: upsstats.cgi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSSTATS\&.CGI" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSSTATS\&.CGI" "8" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsstats.html.5 b/docs/man/upsstats.html.5 index 0864821..34747ae 100644 --- a/docs/man/upsstats.html.5 +++ b/docs/man/upsstats.html.5 @@ -2,12 +2,12 @@ .\" Title: upsstats.html .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 03/02/2016 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "UPSSTATS\&.HTML" "5" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "UPSSTATS\&.HTML" "5" "03/02/2016" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/usbhid-ups.8 b/docs/man/usbhid-ups.8 index 0972045..e74427a 100644 --- a/docs/man/usbhid-ups.8 +++ b/docs/man/usbhid-ups.8 @@ -2,12 +2,12 @@ .\" Title: usbhid-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "USBHID\-UPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "USBHID\-UPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/victronups.8 b/docs/man/victronups.8 index d400151..5275d9c 100644 --- a/docs/man/victronups.8 +++ b/docs/man/victronups.8 @@ -2,12 +2,12 @@ .\" Title: victronups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 04/17/2015 +.\" Date: 12/29/2015 .\" Manual: NUT Manual -.\" Source: Network UPS Tools 2.7.3 +.\" Source: Network UPS Tools 2.7.3.1 .\" Language: English .\" -.TH "VICTRONUPS" "8" "04/17/2015" "Network UPS Tools 2\&.7\&.3" "NUT Manual" +.TH "VICTRONUPS" "8" "12/29/2015" "Network UPS Tools 2\&.7\&.3\&." "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/net-protocol.txt b/docs/net-protocol.txt index 6357a72..17ecf09 100644 --- a/docs/net-protocol.txt +++ b/docs/net-protocol.txt @@ -132,10 +132,18 @@ Response: - 'RW': this variable may be set to another value with SET - 'ENUM': an enumerated type, which supports a few specific values - 'STRING:n': this is a string of maximum length n -- 'RANGE': this is an integer, comprised in the range (see LIST RANGE) +- 'RANGE': this is an numeric, either integer or float, comprised in the range (see LIST RANGE) +- 'NUMBER': this is a simple numeric value, either integer or float ENUM, STRING and RANGE are usually associated with RW, but not always. -The default , when omitted, is integer. +The default , when omitted, is numeric, so either integer or float. Each +driver is then responsible for handling values as either integer or float. + +Note that float values are expressed using decimal (base 10) english-based +representation, so using a dot, in non-scientific notation. So hexadecimal, +exponents, and comma for thousands separator are forbidden. +For example: "1200.20" is valid, while "1,200.20" and "1200,20" are invalid. + This replaces the old "VARTYPE" command. diff --git a/docs/new-clients.txt b/docs/new-clients.txt index c4b929e..7b41364 100644 --- a/docs/new-clients.txt +++ b/docs/new-clients.txt @@ -23,7 +23,7 @@ to give access to upsd and UPS status information. Both static and shared versions are provided. These library files and associated header files are not installed by -default. You must `./configure --with-lib` to enable building and +default. You must `./configure --with-dev` to enable building and installing these files. The libraries can then be built and installed with `make` and `make install` as usual. This must be done before building other (non-NUT) programs which depend on them. @@ -151,6 +151,6 @@ multiple UPS units). Java ---- -The NUT java support have been externalized. +The NUT Java support has been externalized. It is available at https://github.com/networkupstools/jnut diff --git a/docs/new-drivers.txt b/docs/new-drivers.txt index 9145f49..3949a0b 100644 --- a/docs/new-drivers.txt +++ b/docs/new-drivers.txt @@ -200,7 +200,7 @@ Possible values for status_set: OL - On line (mains is present) OB - On battery (mains is not present) LB - Low battery - HB - High battery + HB - High battery RB - The battery needs to be replaced CHRG - The battery is charging DISCHRG - The battery is discharging (inverter is providing load power) @@ -225,9 +225,13 @@ below). - As an exception, drivers may set "FSD" when an imminent shutdown has been detected. In this case, the "on battery + low battery" condition should not be -met. Otherwise, setting status to "OB LB" should be prefered. +met. Otherwise, setting status to "OB LB" should be preferred. - the OL and OB flags are an indication of the input line status only. + +- the CHRG and DISCHRG flags are under replacement by battery.charger.status. +See the linkdoc:user-manual[NUT command and variable naming scheme,nut-names] +for more information. ================================================================================ UPS alarms diff --git a/docs/nut-names.txt b/docs/nut-names.txt index cb81b7b..d2e46c7 100644 --- a/docs/nut-names.txt +++ b/docs/nut-names.txt @@ -32,7 +32,7 @@ during a transition period. The ups.* data will then be removed. | device.model | Device model | BladeUPS | device.mfr | Device manufacturer | Eaton | device.serial | Device serial number (opaque string) | WS9643050926 -| device.type | Device type (ups, pdu, scd, psu) | ups +| device.type | Device type (ups, pdu, scd, psu, ats) | ups | device.description | Device description (opaque string) | Some ups | device.contact | Device administrator name (opaque string) | John Doe | device.location | Device physical location (opaque string) | 1st floor @@ -129,53 +129,68 @@ input: Incoming line/power information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [options="header"] -|=============================================================================== -| Name | Description | Example value -| input.voltage | Input voltage | 121.5 -| input.voltage.maximum | Maximum incoming voltage seen | 130 -| input.voltage.minimum | Minimum incoming voltage seen | 100 -| input.voltage.nominal | Nominal input voltage | 120 -| input.voltage.extended | Extended input voltage range | no -| input.transfer.delay | Delay before transfer to mains - (seconds) | 60 -| input.transfer.reason | Reason for last transfer - to battery (*** opaque) | T -| input.transfer.low | Low voltage transfer point | 91 -| input.transfer.high | High voltage transfer point | 132 -| input.transfer.low.min | smallest settable low - voltage transfer point | 85 -| input.transfer.low.max | greatest settable low - voltage transfer point | 95 -| input.transfer.high.min | smallest settable high - voltage transfer point | 131 -| input.transfer.high.max | greatest settable high - voltage transfer point | 136 -| input.sensitivity | Input power sensitivity | H (high) -| input.quality | Input power quality (*** - opaque) | FF -| input.current | Input current (A) | 4.25 -| input.current.nominal | Nominal input current (A) | 5.0 -| input.frequency | Input line frequency (Hz) | 60.00 -| input.frequency.nominal | Nominal input line - frequency (Hz) | 60 -| input.frequency.low | Input line frequency low (Hz) | 47 -| input.frequency.high | Input line frequency high (Hz) | 63 -| input.frequency.extended | Extended input frequency range | no -| input.transfer.boost.low | Low voltage boosting - transfer point | 190 -| input.transfer.boost.high | High voltage boosting - transfer point | 210 -| input.transfer.trim.low | Low voltage trimming - transfer point | 230 -| input.transfer.trim.high | High voltage trimming - transfer point | 240 -| input.load | Load on (ePDU) input (percent - of full) | 25 -| input.realpower | Current sum value of all (ePDU) - phases real power (W) | 300 -| input.power | Current sum value of all (ePDU) - phases apparent power (VA) | 500 -|=============================================================================== +|================================================================================= +| Name | Description | Example value +| input.voltage | Input voltage (V) | 121.5 +| input.voltage.maximum | Maximum incoming voltage seen (V) | 130 +| input.voltage.minimum | Minimum incoming voltage seen (V) | 100 +| input.voltage.status | Status relative to the + thresholds | critical-low +| input.voltage.low.warning | Low warning threshold (V) | 205 +| input.voltage.low.critical | Low critical threshold (V) | 200 +| input.voltage.high.warning | High warning threshold (V) | 230 +| input.voltage.high.critical | High critical threshold (V) | 240 +| input.voltage.nominal | Nominal input voltage (V) | 120 +| input.voltage.extended | Extended input voltage range | no +| input.transfer.delay | Delay before transfer to mains + (seconds) | 60 +| input.transfer.reason | Reason for last transfer + to battery (*** opaque) | T +| input.transfer.low | Low voltage transfer point (V) | 91 +| input.transfer.high | High voltage transfer point (V) | 132 +| input.transfer.low.min | smallest settable low + voltage transfer point (V) | 85 +| input.transfer.low.max | greatest settable low + voltage transfer point (V) | 95 +| input.transfer.high.min | smallest settable high + voltage transfer point (V) | 131 +| input.transfer.high.max | greatest settable high + voltage transfer point (V) | 136 +| input.sensitivity | Input power sensitivity | H (high) +| input.quality | Input power quality (*** + opaque) | FF +| input.current | Input current (A) | 4.25 +| input.current.nominal | Nominal input current (A) | 5.0 +| input.current.status | Status relative to the + thresholds | critical-high +| input.current.low.warning | Low warning threshold (A) | 4 +| input.current.low.critical | Low critical threshold (A) | 2 +| input.current.high.warning | High warning threshold (A) | 10 +| input.current.high.critical | High critical threshold (A) | 12 +| input.frequency | Input line frequency (Hz) | 60.00 +| input.frequency.nominal | Nominal input line + frequency (Hz) | 60 +| input.frequency.status | Frequency status | out-of-range +| input.frequency.low | Input line frequency low (Hz) | 47 +| input.frequency.high | Input line frequency high (Hz) | 63 +| input.frequency.extended | Extended input frequency range | no +| input.transfer.boost.low | Low voltage boosting + transfer point (V) | 190 +| input.transfer.boost.high | High voltage boosting + transfer point (V) | 210 +| input.transfer.trim.low | Low voltage trimming + transfer point (V) | 230 +| input.transfer.trim.high | High voltage trimming + transfer point (V) | 240 +| input.load | Load on (ePDU) input (percent + of full) | 25 +| input.realpower | Current sum value of all (ePDU) + phases real power (W) | 300 +| 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 +|================================================================================= output: Outgoing power/inverter information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -258,14 +273,25 @@ Valid with/without context (i.e. per phase or aggregated/averaged) [options="header"] |=============================================================================== | Name | Description +| alarm | Alarms for phases, published in ups.alarm | current | Current (A) | current.maximum | Maximum seen current (A) | current.minimum | Minimum seen current (A) +| current.status | Status relative to the thresholds +| current.low.warning | Low warning threshold (A) +| current.low.critical | Low critical threshold (A) +| current.high.warning | High warning threshold (A) +| current.high.critical | High critical threshold (A) | current.peak | Peak current | voltage | Voltage (V) | voltage.nominal | Nominal voltage (V) | voltage.maximum | Maximum seen voltage (V) | voltage.minimum | Minimum seen voltage (V) +| voltage.status | Status relative to the thresholds +| voltage.low.warning | Low warning threshold (V) +| voltage.low.critical | Low critical threshold (V) +| voltage.high.warning | High warning threshold (V) +| voltage.high.critical | High critical threshold (V) | power | Apparent power (VA) | power.maximum | Maximum seen apparent power (VA) | power.minimum | Minimum seen apparent power (VA) @@ -327,6 +353,8 @@ battery: Any battery details UPS restart after power-off | 20 | battery.charge.warning | Battery level when UPS switches to "Warning" state (percent) | 50 +| battery.charger.status | Status of the battery charger + (see the note below) | charging | battery.voltage | Battery voltage (V) | 24.84 | battery.voltage.nominal | Nominal battery voltage (V) | 024 | battery.voltage.low | Minimum battery voltage, that @@ -362,6 +390,17 @@ battery: Any battery details and load level lower (Watts) | 10 |=============================================================================== +NOTE: +battery.charger.status replaces the historic flags CHRG and DISCHRG that were +exposed through ups.status. battery.charger.status can have one of the +following value: + +- charging: battery is charging, +- discharging: battery is discharging, +- floating: battery has completed its charge cycle, and waiting to go to resting +mode, +- resting: the battery is fully charged, and not charging nor discharging. + ambient: Conditions from external probe equipment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -374,33 +413,56 @@ from '1' to 'n'. For example: 'ambient.1.temperature' for the first external sensor temperature. [options="header"] -|=============================================================================== -| Name | Description | Example value -| ambient.n.temperature | Ambient temperature - (degrees C) | 25.40 -| ambient.n.temperature.alarm | Temperature alarm - (enabled/disabled) | enabled -| ambient.n.temperature.high | Temperature threshold high - (degrees C) | 40 -| ambient.n.temperature.low | Temperature threshold low - (degrees C) | 5 -| ambient.n.temperature.maximum | Maximum temperature seen - (degrees C) | 37.6 -| ambient.n.temperature.minimum | Minimum temperature seen - (degrees C) | 18.1 -| ambient.n.humidity | Ambient relative humidity - (percent) | 038.8 -| ambient.n.humidity.alarm | Relative humidity alarm - (enabled/disabled) | enabled -| ambient.n.humidity.high | Relative humidity - threshold high (percent) | 80 -| ambient.n.humidity.low | Relative humidity - threshold high (percent) | 10 -| ambient.n.humidity.maximum | Maximum relative humidity - seen (percent) | 60 -| ambient.n.humidity.minimum | Minimum relative humidity - seen (percent) | 13 -|=============================================================================== +|================================================================================== +| Name | Description | Example value +| ambient.n.present | Ambient sensor presence | yes +| ambient.n.temperature | Ambient temperature + (degrees C) | 25.40 +| ambient.n.temperature.alarm | Temperature alarm + (enabled/disabled) | enabled +| ambient.n.temperature.status | Ambient temperature status + relative to the thresholds | warning-low +| ambient.n.temperature.high | Temperature threshold high + (degrees C) | 60 +| ambient.n.temperature.high.warning | Temperature threshold high + warning (degrees C) | 40 +| ambient.n.temperature.high.critical | Temperature threshold high + critical (degrees C) | 60 +| ambient.n.temperature.low | Temperature threshold low + (degrees C) | 5 +| ambient.n.temperature.low.warning | Temperature threshold low + warning (degrees C) | 10 +| ambient.n.temperature.low.critical | Temperature threshold low + critical (degrees C) | 5 +| ambient.n.temperature.maximum | Maximum temperature seen + (degrees C) | 37.6 +| ambient.n.temperature.minimum | Minimum temperature seen + (degrees C) | 18.1 +| ambient.n.humidity | Ambient relative humidity + (percent) | 038.8 +| ambient.n.humidity.alarm | Relative humidity alarm + (enabled/disabled) | enabled +| ambient.n.humidity.status | Ambient humidity status + relative to the thresholds | warning-low +| ambient.n.humidity.high | Relative humidity + threshold high (percent) | 80 +| ambient.n.humidity.high.warning | Relative humidity threshold + high warning (percent) | 70 +| ambient.n.humidity.high.critical | Relative humidity threshold + high critical (percent) | 80 +| ambient.n.humidity.low | Relative humidity + threshold low (percent) | 10 +| ambient.n.humidity.low.warning | Relative humidity threshold + low warning (percent) | 20 +| ambient.n.humidity.low.critical | Relative humidity threshold + low critical (percent) | 10 +| ambient.n.humidity.maximum | Maximum relative humidity + seen (percent) | 60 +| ambient.n.humidity.minimum | Minimum relative humidity + seen (percent) | 13 +| ambient.n.contacts.x.status | State of the dry contact + sensor x | open +|================================================================================== outlet: Smart outlet management @@ -408,31 +470,39 @@ outlet: Smart outlet management NOTE: *n* stands for the outlet index. For more information, refer to the NUT outlets management and PDU notes chapter of the user manual. -A special case is "outlet.0" which is equivalent to "outlet", and -represent the whole set of outlets of the device. +A special case is "outlet.0" which is equivalent to "outlet" (without +index), and represent the whole set of outlets of the device. The most +important data is "outlet.count", used to iterate over the whole set of +outlets. [options="header"] |=============================================================================== -| Name | Description | Example value +| Name | Description | Example value +| outlet.count | Total number of outlets | 12 | outlet.n.id | Outlet system identifier - (opaque string) | 1 -| outlet.n.desc | Outlet description - (opaque string) | Main outlet + (opaque string) | 1 +| outlet.n.desc | Outlet name / description + (opaque string) | Main outlet +| outlet.n.groupid | Identifier of the group to + which the outlet belongs to | 1 | outlet.n.switch | Outlet switch control - (on/off) | on + (on/off) | on | outlet.n.status | Outlet switch status - (on/off) | on + (on/off) | on +| outlet.n.alarm | Alarms for outlets and PDU, + published in ups.alarm | outlet 1 low + voltage warning | outlet.n.switchable | Outlet switch ability - (yes/no) | yes + (yes/no) | yes | outlet.n.autoswitch.charge.low | Remaining battery level to power off this outlet - (percent) | 80 + (percent) | 80 | outlet.n.battery.charge.low | Remaining battery level to power off this outlet - (percent) | 80 + (percent) | 80 | outlet.n.delay.shutdown | Interval to wait before shutting down this outlet - (seconds) | 180 + (seconds) | 180 | outlet.n.delay.start | Interval to wait before restarting this outlet (seconds) | 120 @@ -440,20 +510,72 @@ represent the whole set of outlets of the device. will be shutdown (seconds) | 20 | outlet.n.timer.start | Time before the outlet load will be started (seconds) | 30 -| outlet.n.current | Current (A) | 0.19 -| outlet.n.current.maximum | Maximum seen current (A) | 0.56 +| outlet.n.current | Current (A) | 0.19 +| outlet.n.current.maximum | Maximum seen current (A) | 0.56 +| outlet.n.current.status | Current status relative to + the thresholds | good +| outlet.n.current.low.warning | Low warning threshold (A) | 0.10 +| outlet.n.current.low.critical | Low critical threshold (A) | 0.05 +| outlet.n.current.high.warning | High warning threshold (A) | 0.30 +| outlet.n.current.high.critical | High critical threshold (A) | 0.40 | outlet.n.realpower | Current value of real - power (W) | 28 -| outlet.n.voltage | Voltage (V) | 247.0 -| outlet.n.powerfactor | Power Factor - (dimensionless value - between 0 and 1) | 0.85 -| outlet.n.crestfactor | Crest Factor - (dimensionless, equal - to or greater than 1) | 1.41 -| outlet.n.power | Apparent power (VA) | 46 + power (W) | 28 +| outlet.n.voltage | Voltage (V) | 247.0 +| outlet.n.voltage.status | Voltage status relative to + the thresholds | good +| outlet.n.voltage.low.warning | Low warning threshold (V) | 205 +| outlet.n.voltage.low.critical | Low critical threshold (V) | 200 +| outlet.n.voltage.high.warning | High warning threshold (V) | 230 +| outlet.n.voltage.high.critical | High critical threshold (V) | 240 +| outlet.n.powerfactor | Power Factor (dimensionless, + value between 0 and 1) | 0.85 +| outlet.n.crestfactor | Crest Factor (dimensionless, + equal to or greater than 1) | 1.41 +| outlet.n.power | Apparent power (VA) | 46 |=============================================================================== +outlet.group: groups of smart outlets +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This is a refinement of the outlet collection, providing grouped +management for a set of outlets. The same principles and data than the +outlet collection apply to outlet.group, especially for the indexing 'n' +and "outlet.group.count". + +Most of the data published for outlets also apply to outlet.group, +including: id, name (similar as outlet "desc"), status, current and +voltage (including status, alarm and thresholds). + +Some specific data to outlet groups exists: + +[options="header"] +|================================================================================= +| Name | Description | Example value +| outlet.group.n.type | Type of outlet group (OPAQUE) | outlet-section +| outlet.group.n.count | Number of outlets in the group | 12 +|================================================================================= + +Example: + + outlet.group.1.current: 0.00 + outlet.group.1.current.high.critical: 16.00 + outlet.group.1.current.high.warning: 12.80 + outlet.group.1.current.low.warning: 0.00 + outlet.group.1.current.nominal: 16.00 + outlet.group.1.current.status: good + outlet.group.1.id: 1 + outlet.group.1.name: Branch Circuit A + outlet.group.1.status: on + outlet.group.1.voltage: 244.23 + outlet.group.1.voltage.high.critical: 265.00 + outlet.group.1.voltage.high.warning: 255.00 + outlet.group.1.voltage.low.critical: 180.00 + outlet.group.1.voltage.low.warning: 190.00 + outlet.group.1.voltage.status: good + ... + outlet.group.count: 3.00 + + driver: Internal driver information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/nut-qa.txt b/docs/nut-qa.txt index ebf256f..2359509 100644 --- a/docs/nut-qa.txt +++ b/docs/nut-qa.txt @@ -106,6 +106,9 @@ checks that these are well propagated with upsc. - link:https://bugzilla.redhat.com/buglist.cgi?component=nut[Redhat / Fedora Bug tracker] +- link:https://www.openhub.net/p/nut[Black Duck Open Hub] (formerly Ohloh.net) +provides metrics on NUT source code base and activity. + Runtime quality ~~~~~~~~~~~~~~~ diff --git a/docs/nutdrv_qx-subdrivers.txt b/docs/nutdrv_qx-subdrivers.txt index aa7fe50..4a76d64 100644 --- a/docs/nutdrv_qx-subdrivers.txt +++ b/docs/nutdrv_qx-subdrivers.txt @@ -19,7 +19,7 @@ In order to develop a new subdriver for a specific UPS you have to know the idio This kind of devices speaks idioms that can be summed up as follows: -- We send the UPS a query for one or more informations +- We send the UPS a query for one or more information * If the query is supported by the device, we'll get a reply that is mostly of a fixed length, therefore, in most cases, each information starts and ends always at the same indexes @@ -137,8 +137,9 @@ typedef struct item_t { const int to; const char *dfl; unsigned long qxflags; + int (*preprocess_command)(struct item_t *item, char *command, const size_t commandlen); int (*preprocess_answer)(struct item_t *item, const int len); - int (*preprocess)(struct item_t *item, char *value, size_t valuelen); + int (*preprocess)(struct item_t *item, char *value, const size_t valuelen); } item_t; ---- @@ -166,7 +167,7 @@ NOTE: If +QX_FLAG_SETVAR+ is set the value given by the user will be checked aga ---- typedef struct { char value[SMALLBUF]; - int (*preprocess)(char *value, size_t len); + int (*preprocess)(char *value, const size_t len); } info_rw_t; ---- @@ -187,7 +188,7 @@ Command sent to the UPS to get answer/to execute a instant command/to set a vari *+answer+*:: Answer from the UPS, filled at runtime. + -NOTE: If you expect a nonvalid C string (e.g.: inner ++\0++s) or need to perform actions before the answer is used (and treated as a null-terminated string), you should set a +preprocess_answer()+ function. +NOTE: If you expect a non-valid C string (e.g.: inner ++\0++s) or need to perform actions before the answer is used (and treated as a null-terminated string), you should set a +preprocess_answer()+ function. *+answer_len+*:: Expected minimum length of the answer. @@ -245,6 +246,12 @@ If there's a problem with a var in +QX_WALKMODE_INIT+, the driver will automagic ==== -- +*+preprocess_command(item, command, commandlen)+*:: +Last chance to preprocess the command to be sent to the UPS (e.g. to add CRC, ...). +This function is given the currently processed item (+item+), the command to be sent to the UPS (+command+) and its size_t (+commandlen+). +Return +-1+ in case of errors, else +0+. ++command+ must be filled with the actual command to be sent to the UPS. + *+preprocess_answer(item, len)+*:: Function to preprocess the answer we got from the UPS before we do anything else (e.g. for CRC, decoding, ...). This function is given the currently processed item (+item+) with the answer we got from the UPS unmolested and already stored in +item+'s +answer+ and the length of that answer (+len+). @@ -290,7 +297,7 @@ We know that when the UPS is queried for status with +QGS\r+, it replies with so Here's the +item_t+: ---- -{ "output.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 12, 16, "%.1f", 0, NULL, NULL }, +{ "output.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 12, 16, "%.1f", 0, NULL, NULL, NULL }, ---- [horizontal] @@ -333,6 +340,9 @@ Because of that we need to provide a floating point specifier. +qxflags+:: +0+ ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -355,7 +365,7 @@ Also from +QGS\r+, we want to process the 9th status bit +10000000+*`0`*+001+ th Here's the +item_t+: ---- -{ "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 71, 71, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status }, +{ "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 71, 71, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status }, ---- [horizontal] @@ -398,6 +408,9 @@ Since a +preprocess+ function is defined for this item, this could have been +NU +QX_FLAG_QUICK_POLL+ -> this item will be polled every time the driver will check for updates. Since this item is mandatory to run the driver, if a problem arises in +QX_WALKMODE_INIT+ the driver won't skip it an it'll set +datastale+. ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -423,7 +436,7 @@ Here's the +item_t+: ---- { "battery.type", ST_FLAG_RW, voltronic_e_batt_type, "QBT\r", "", 4, '(', "", 1, 2, "%s", - QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_p31b }, + QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_p31b }, ---- [horizontal] @@ -469,6 +482,9 @@ Since a +preprocess+ function is defined for this item, this could have been +NU + +QX_FLAG_ENUM+ -> this r/w variable is of the enumerated type and the enumerated values are listed in the +info_rw+ structure (i.e. +voltronic_e_batt_type+) ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -477,7 +493,7 @@ Since a +preprocess+ function is defined for this item, this could have been +NU + This function will be called *after* the +command+ has been sent to the UPS and we got back the +answer+ and stored the +value+ in order to process it to NUT standards: in this case we will check if the value is in the range and then publish the human readable form of it (i.e. +Li+, +Flooded+ or +AGM+). -We also know that we can change battery type with the +PBTnn\r+ command; we are expecting either +(ACK\r+ if the command succeded or +(NAK\r+ if the command is rejected. +We also know that we can change battery type with the +PBTnn\r+ command; we are expecting either +(ACK\r+ if the command succeeded or +(NAK\r+ if the command is rejected. ---- > [PBTnn\r] nn = 00/01/02 @@ -490,7 +506,7 @@ Here's the +item_t+: ---- { "battery.type", 0, voltronic_e_batt_type, "PBT%02.0f\r", "", 5, '(', "", 1, 4, NULL, - QX_FLAG_SETVAR | QX_FLAG_ENUM, NULL, voltronic_p31b_set }, + QX_FLAG_SETVAR | QX_FLAG_ENUM, NULL, NULL, voltronic_p31b_set }, ---- [horizontal] @@ -534,6 +550,9 @@ Not used for +QX_FLAG_SETVAR+ + +QX_FLAG_ENUM+ -> this r/w variable is of the enumerated type and the enumerated values are listed in the +info_rw+ structure (i.e. +voltronic_e_batt_type+) ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -558,7 +577,7 @@ We know that we have to send to the UPS +Tnn\r+ or +T.n\r+ in order to start a b Here's the +item_t+: ---- -{ "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 4, NULL, QX_FLAG_CMD, NULL, voltronic_process_command }, +{ "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 4, NULL, QX_FLAG_CMD, NULL, NULL, voltronic_process_command }, ---- [horizontal] @@ -598,6 +617,9 @@ Not used for +QX_FLAG_CMD+ +qxflags+:: +QX_FLAG_CMD+ -> this item is an instant command that will be fired when +info_type+ (i.e. +test.battery.start+) is called ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -614,7 +636,7 @@ In order to set the server-side var +ups.delay.start+, that will be then used by ---- { "ups.delay.start", ST_FLAG_RW, voltronic_r_ondelay, NULL, "", 0, 0, "", 0, 0, "180", - QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, voltronic_process_setvar }, + QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, voltronic_process_setvar }, ---- [horizontal] @@ -661,13 +683,16 @@ Not used for +QX_FLAG_ABSENT+ + +QX_FLAG_RANGE+ -> this r/w variable has a settable range and its boundaries are listed in the +info_rw+ structure (i.e. +voltronic_r_ondelay+) ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ +preprocess+:: +voltronic_process_setvar+ + -This function will be called, in setvar, before the driver stores the value in the NUT var: here it's used to truncate the user-provided value to the neareset settable interval. +This function will be called, in setvar, before the driver stores the value in the NUT var: here it's used to truncate the user-provided value to the nearest settable interval. Informations not yet available in NUT @@ -688,7 +713,7 @@ Here's the +item_t+ for input phase angle: ---- { "input_phase_angle", 0, NULL, "QPD\r", "", 9, '(', "", 1, 3, "%03.0f", - QX_FLAG_STATIC | QX_FLAG_NONUT, NULL, voltronic_phase }, + QX_FLAG_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_phase }, ---- [horizontal] @@ -735,6 +760,9 @@ Here instead it's used by the +preprocess+ function. + +QX_FLAG_NONUT+ -> this item doesn't have yet a NUT variable ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -747,7 +775,7 @@ Here's the +item_t+ for output phase angle: ---- { "output_phase_angle", ST_FLAG_RW, voltronic_e_phase, "QPD\r", "", 9, '(', "", 5, 7, "%03.0f", - QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, voltronic_phase }, + QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, NULL, voltronic_phase }, ---- [horizontal] @@ -801,6 +829,9 @@ Here instead it's used by the +preprocess+ function. + +QX_FLAG_NONUT+ -> this item doesn't have yet a NUT variable ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -827,7 +858,7 @@ Here's the +item_t+ ---- { "output_phase_angle", 0, voltronic_e_phase, "PPD%03.0f\r", "", 5, '(', "", 1, 4, NULL, - QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, voltronic_phase_set }, + QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, NULL, voltronic_phase_set }, ---- [horizontal] @@ -877,6 +908,9 @@ Not used for +QX_FLAG_SETVAR+ + +QX_FLAG_NONUT+ -> this item doesn't have yet a NUT variable ++preprocess_command+:: ++NULL+ + +preprocess_answer+:: +NULL+ @@ -892,7 +926,14 @@ Support functions You are already given the following functions: *+int instcmd(const char *cmdname, const char *extradata)+*:: -Execute an instant command. +Execute an instant command. In detail: ++ +-- +- look up the given +cmdname+ in the qx2nut data structure (if not found, try to fallback to commonly known commands); +- if +cmdname+ is found, call its preprocess function, passing to it +extradata+, if any, otherwise its +dfl+ value, if any; +- send the command to the device and check the reply. +-- ++ Return +STAT_INSTCMD_INVALID+ if the command is invalid, +STAT_INSTCMD_FAILED+ if it failed, +STAT_INSTCMD_HANDLED+ on success. *+int setvar(const char *varname, const char *val)+*:: @@ -905,11 +946,11 @@ Find an item of +item_t+ type in +qx2nut+ data structure by its +info_type+, opt - +noflag+: flags that have to be absent in the item, i.e. if at least one of the flags is set in the item it won't be returned. *+int qx_process(item_t *item, const char *command)+*:: -Send +command+ or, if it is +NULL+, send the command stored in the +item+ to the UPS and process the reply. +Send +command+ (a null-terminated byte string) or, if it is +NULL+, send the command stored in the +item+ to the UPS and process the reply, saving it in +item+'s +answer+. Return +-1+ on errors, +0+ on success. *+int ups_infoval_set(item_t *item)+*:: -Process the value we got back from the UPS (set status bits and set the value of other parameters), calling its +preprocess+ function, if any, otherwise executing the standard preprocessing (including trimming if +QX_FLAG_TRIM+ is set). +Process the value we got back from the UPS (set status bits and set the value of other parameters), calling the +item+-specific +preprocess+ function, if any, otherwise executing the standard preprocessing (including trimming if +QX_FLAG_TRIM+ is set). Return +-1+ on failure, +0+ for a status update and +1+ in all other cases. *+int qx_status(void)+*:: diff --git a/docs/packager-guide.txt b/docs/packager-guide.txt index 2d40b83..e20a0dd 100644 --- a/docs/packager-guide.txt +++ b/docs/packager-guide.txt @@ -30,7 +30,7 @@ software integration into an OS, and allows users to have an easy software installation and support out of the box. NOTE: making NUT packaging more uniform should help its documentation, -support and maintenance accross the supported OSes. +support and maintenance across the supported OSes. ------------------------------------------------------------------------ *sandbox* @@ -41,7 +41,7 @@ Facts about NUT packaging ========================= NUT has so much evolved those two last years (with USB and SNMP -support, the premices of libraries, ...) that the simple +support, the premises of libraries, ...) that the simple "1, 2 or 3 package(s)" approach is no more suitable. This fact has reached a high level since NUT 1.4. Actually, diff --git a/docs/scheduling.txt b/docs/scheduling.txt index 922bea3..c186228 100644 --- a/docs/scheduling.txt +++ b/docs/scheduling.txt @@ -107,7 +107,7 @@ in your upsmon.conf, if you also enable the 'EXEC' in your 'NOTIFYFLAGS'. In this case, we want upsmon to call upssched as the notifier, since it will be doing all the work for us. So, in the upsmon.conf: - NOTIFYCMD /usr/local/ups/bin/upssched + NOTIFYCMD /usr/local/ups/sbin/upssched Then we want upsmon to actually _use_ it for the notify events, so again in the upsmon.conf we set the flags: diff --git a/docs/snmp-subdrivers.txt b/docs/snmp-subdrivers.txt index d717b96..3a2b3ff 100644 --- a/docs/snmp-subdrivers.txt +++ b/docs/snmp-subdrivers.txt @@ -126,7 +126,7 @@ mode 1: get SNMP data from a real agent This method requires to have a network access to the device, in order to automatically retrieve the needed information. -You have to specify the following paramaters: +You have to specify the following parameters: - *-H* host address: is the SNMP host IP address or name - *-c* community: is the SNMP v1 community name (default: public)" @@ -218,6 +218,7 @@ subdrivers are written.: - netvision-mib.c/h - powerware-mib.c/h - raritan-pdu-mib.c +- huawei-mib.c/h To help you, above each entry in -mib.c, there is a comment that displays the textual OID name. For example, the following entry: diff --git a/docs/user-manual.txt b/docs/user-manual.txt index d25083d..3e85d56 100644 --- a/docs/user-manual.txt +++ b/docs/user-manual.txt @@ -111,10 +111,14 @@ This section document the various acronyms used throughout the present documentation. [template="glossary",id="terms"] +ATS:: + Automatic Transfer Switch. NUT:: Network UPS Tools. PDU:: Power Distribution Unit. +PSU:: + Power Supply Units. SCD:: Solar Controller Device. UPS:: diff --git a/drivers/Makefile.am b/drivers/Makefile.am index bf36319..2a66e91 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -129,6 +129,7 @@ rhino_SOURCES = rhino.c rhino_LDADD = $(LDADD) -lm safenet_SOURCES = safenet.c solis_SOURCES = solis.c +solis_LDADD = $(LDADD) -lm tripplite_SOURCES = tripplite.c tripplite_LDADD = $(LDADD) -lm tripplitesu_SOURCES = tripplitesu.c @@ -199,8 +200,8 @@ mge_shut_LDADD = $(LDADD) # SNMP snmp_ups_SOURCES = snmp-ups.c apc-mib.c baytech-mib.c compaq-mib.c eaton-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 + bestpower-mib.c cyberpower-mib.c delta_ups-mib.c xppc-mib.c huawei-mib.c \ + eaton-ats-mib.c apc-ats-mib.c snmp_ups_LDADD = $(LDADD_DRIVERS) $(LIBNETSNMP_LIBS) # NEON XML/HTTP @@ -264,7 +265,7 @@ dist_noinst_HEADERS = apc-mib.h apc-hid.h baytech-mib.h bcmxcp.h \ delta_ups-mib.h nutdrv_qx.h nutdrv_qx_bestups.h nutdrv_qx_blazer-common.h nutdrv_qx_mecer.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 + xppc-mib.h huawei-mib.h eaton-ats-mib.h apc-ats-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/Makefile.in b/drivers/Makefile.in index 6824bc3..1803bb2 100644 --- a/drivers/Makefile.in +++ b/drivers/Makefile.in @@ -426,13 +426,14 @@ am_snmp_ups_OBJECTS = snmp-ups.$(OBJEXT) apc-mib.$(OBJEXT) \ ietf-mib.$(OBJEXT) mge-mib.$(OBJEXT) netvision-mib.$(OBJEXT) \ powerware-mib.$(OBJEXT) raritan-pdu-mib.$(OBJEXT) \ bestpower-mib.$(OBJEXT) cyberpower-mib.$(OBJEXT) \ - delta_ups-mib.$(OBJEXT) xppc-mib.$(OBJEXT) + delta_ups-mib.$(OBJEXT) xppc-mib.$(OBJEXT) \ + huawei-mib.$(OBJEXT) eaton-ats-mib.$(OBJEXT) \ + apc-ats-mib.$(OBJEXT) snmp_ups_OBJECTS = $(am_snmp_ups_OBJECTS) snmp_ups_DEPENDENCIES = $(LDADD_DRIVERS) $(am__DEPENDENCIES_1) am_solis_OBJECTS = solis.$(OBJEXT) solis_OBJECTS = $(am_solis_OBJECTS) -solis_LDADD = $(LDADD) -solis_DEPENDENCIES = $(am__DEPENDENCIES_2) +solis_DEPENDENCIES = $(am__DEPENDENCIES_3) am_tripplite_OBJECTS = tripplite.$(OBJEXT) tripplite_OBJECTS = $(am_tripplite_OBJECTS) tripplite_DEPENDENCIES = $(am__DEPENDENCIES_3) @@ -622,6 +623,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ @@ -833,6 +835,7 @@ rhino_SOURCES = rhino.c rhino_LDADD = $(LDADD) -lm safenet_SOURCES = safenet.c solis_SOURCES = solis.c +solis_LDADD = $(LDADD) -lm tripplite_SOURCES = tripplite.c tripplite_LDADD = $(LDADD) -lm tripplitesu_SOURCES = tripplitesu.c @@ -895,8 +898,8 @@ mge_shut_LDADD = $(LDADD) # SNMP snmp_ups_SOURCES = snmp-ups.c apc-mib.c baytech-mib.c compaq-mib.c eaton-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 + bestpower-mib.c cyberpower-mib.c delta_ups-mib.c xppc-mib.c huawei-mib.c \ + eaton-ats-mib.c apc-ats-mib.c snmp_ups_LDADD = $(LDADD_DRIVERS) $(LIBNETSNMP_LIBS) @@ -950,7 +953,7 @@ dist_noinst_HEADERS = apc-mib.h apc-hid.h baytech-mib.h bcmxcp.h \ delta_ups-mib.h nutdrv_qx.h nutdrv_qx_bestups.h nutdrv_qx_blazer-common.h nutdrv_qx_mecer.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 + xppc-mib.h huawei-mib.h eaton-ats-mib.h apc-ats-mib.h # Define a dummy library so that Automake builds rules for the @@ -1330,6 +1333,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/al175.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apc-ats-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apc-hid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apc-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apcsmart-old.Po@am__quote@ @@ -1360,6 +1364,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delta_ups-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dstate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dummy_ups-dummy-ups.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaton-ats-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eaton-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/etapro.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/everups.Po@am__quote@ @@ -1367,6 +1372,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gamatronic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genericups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hidparser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huawei-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idowell-hid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isbmex.Po@am__quote@ diff --git a/drivers/apc-ats-mib.c b/drivers/apc-ats-mib.c new file mode 100755 index 0000000..d642a3f --- /dev/null +++ b/drivers/apc-ats-mib.c @@ -0,0 +1,447 @@ +/* apcats-mib.c - subdriver to monitor apcats SNMP devices with NUT + * + * Copyright (C) + * 2011 - 2012 Arnaud Quette + * 2016 Arnaud Quette + * + * Note: this subdriver was initially generated as a "stub" by the + * gen-snmp-subdriver script. It must be customized! + * + * 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 "apc-ats-mib.h" + +#define APC_ATS_MIB_VERSION "0.2" + +#define APC_ATS_SYSOID ".1.3.6.1.4.1.318.1.3.11" + +static info_lkp_t ats_sensitivity_info[] = { + { 1, "high" }, + { 2, "low" }, + { 0, NULL } +}; + +static info_lkp_t ats_output_status_info[] = { + { 1, "OFF" }, /* fail */ + { 2, "OL" }, /* ok */ + { 0, NULL } +}; + +static info_lkp_t ats_outletgroups_name_info[] = { + { 1, "total" }, + { 2, "bank1" }, + { 3, "bank2" }, + { 0, NULL } +}; + +static info_lkp_t ats_outletgroups_status_info[] = { + { 1, "OL" }, /* normal */ + { 2, "" }, /* lowload */ + { 3, "" }, /* nearoverload */ + { 4, "OVER" }, /* overload */ + { 0, NULL } +}; + +/* APC ATS Snmp2NUT lookup table */ +static snmp_info_t apc_ats_mib[] = { + + /* Device collection */ + { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "ats", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + /* ats2IdentManufacturer.0 = STRING: EATON */ + { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "APC", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + /* atsIdentModelNumber.0 = STRING: "AP7724" */ + { "device.model", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.1.5.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* FIXME: RFC for device.firmware! */ + /* atsIdentHardwareRev.0 = STRING: "R01" */ + { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* FIXME: RFC for device.firmware.aux! */ + /* atsIdentFirmwareRev.0 = STRING: "3.0.5" */ + { "ups.firmware.aux", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.1.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsIdentFirmwareDate.0 = STRING: "09/13/11" */ + /*{ "unmapped.atsIdentFirmwareDate", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.1.3.0", NULL, SU_FLAG_OK, NULL, NULL },*/ + /* atsIdentSerialNumber.0 = STRING: "5A1516T15268" */ + { "device.serial", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.1.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* FIXME: RFC for device.mfr.date! */ + /* atsIdentDateOfManufacture.0 = STRING: "04/18/2015" */ + { "ups.mfr.date", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.1.4.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigProductName.0 = STRING: "m-ups-04" */ + { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.4.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* Input collection */ + /* atsIdentNominalLineVoltage.0 = INTEGER: 230 */ + { "input.voltage.nominal", 0, 1, ".1.3.6.1.4.1.318.1.1.8.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsIdentNominalLineFrequency.0 = INTEGER: 50 */ + { "input.frequency.nominal", 0, 1, ".1.3.6.1.4.1.318.1.1.8.1.8.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusSelectedSource.0 = INTEGER: sourceB(2) */ + { "input.source", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigPreferredSource.0 = INTEGER: sourceB(2) */ + { "input.source.preferred", ST_FLAG_RW, 1, ".1.3.6.1.4.1.318.1.1.8.4.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputVoltage.1.1.1 = INTEGER: 216 */ + { "input.1.voltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.3.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputVoltage.2.1.1 = INTEGER: 215 */ + { "input.2.voltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.3.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputFrequency.1 = INTEGER: 50 */ + { "input.1.frequency", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.4.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputFrequency.2 = INTEGER: 50 */ + { "input.2.frequency", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.4.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigVoltageSensitivity.0 = INTEGER: high(1) */ + { "input.sensitivity", ST_FLAG_RW, 1, ".1.3.6.1.4.1.318.1.1.8.4.4.0", NULL, SU_FLAG_OK, &ats_sensitivity_info[0], NULL }, + /* FIXME: RFC for input.count! */ + /* atsNumInputs.0 = INTEGER: 2 */ + { "input.count", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* Output collection */ + /* atsOutputFrequency.1 = INTEGER: 50 */ + { "output.frequency", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.2.1.4.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankOutputVoltage.1 = INTEGER: 215 */ + { "output.voltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.6.1", NULL, SU_FLAG_OK, NULL, NULL }, + + /* UPS collection */ + /* FIXME: RFC for device.status! */ + /* atsStatusVoltageOutStatus.0 = INTEGER: ok(2) */ + { "ups.status", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.15.0", NULL, SU_FLAG_OK, &ats_output_status_info[0], NULL }, + + /* Outlet groups collection */ + /* Note: prefer the OutputBank data to the ConfigBank ones */ + /* atsConfigBankTableSize.0 = INTEGER: 3 */ + /*{ "outlet.group.count", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.13.0", NULL, SU_FLAG_OK, NULL, NULL },*/ + /* atsOutputBankTableSize.0 = INTEGER: 3 */ + { "outlet.group.count", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.4.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankTableIndex.%i = INTEGER: %i */ + /*{ "outlet.group.%i.id", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.4.14.1.1.%i", NULL, SU_FLAG_OK, NULL, NULL },*/ + /* atsOutputBankTableIndex.%i = INTEGER: %i */ + { "outlet.group.%i.id", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.1.%i", NULL, SU_FLAG_OK | SU_OUTLET_GROUP, NULL, NULL }, + /* atsConfigBank.%i = INTEGER: total(1) */ + /*{ "outlet.group.%i.name", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.2.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP, &ats_group_name_info[0], NULL },*/ + /* atsOutputBank.1 = INTEGER: total(1) */ + { "outlet.group.%i.name", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.3.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP, &ats_outletgroups_name_info[0], NULL }, + /* atsOutputBankCurrent.%i = Gauge32: 88 */ + { "outlet.group.%i.current", 0, 0.1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.4.%i", NULL, SU_OUTLET_GROUP, NULL, NULL }, + /* atsOutputBankState.%i = INTEGER: normal(1) */ + { "outlet.group.%i.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.5.%i", NULL, SU_OUTLET_GROUP, &ats_outletgroups_status_info[0], NULL }, + /* atsOutputBankOutputVoltage.%i = INTEGER: 215 */ + { "outlet.group.%i.voltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.6.%i", NULL, SU_OUTLET_GROUP, NULL, NULL }, + /* atsOutputBankPower.1 = INTEGER: 1883 */ + { "outlet.group.%i.realpower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.15.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + + +#if 0 /* FIXME: Remaining data to be processed */ + /* atsIdentDeviceRating.0 = INTEGER: 32 */ + { "unmapped.atsIdentDeviceRating", 0, 1, ".1.3.6.1.4.1.318.1.1.8.1.9.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationNumInputs.0 = INTEGER: 2 */ + { "unmapped.atsCalibrationNumInputs", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationNumInputPhases.0 = INTEGER: 1 */ + { "unmapped.atsCalibrationNumInputPhases", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationInputTableIndex.1.1.1 = INTEGER: 1 */ + { "unmapped.atsCalibrationInputTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.3.1.1.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationInputTableIndex.2.1.1 = INTEGER: 2 */ + { "unmapped.atsCalibrationInputTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.3.1.1.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationInputPhaseTableIndex.1.1.1 = INTEGER: 1 */ + { "unmapped.atsCalibrationInputPhaseTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.3.1.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationInputPhaseTableIndex.2.1.1 = INTEGER: 1 */ + { "unmapped.atsCalibrationInputPhaseTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.3.1.2.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsLineVoltageCalibrationFactor.1.1.1 = INTEGER: 487 */ + { "unmapped.atsLineVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.3.1.3.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsLineVoltageCalibrationFactor.2.1.1 = INTEGER: 488 */ + { "unmapped.atsLineVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.1.3.1.3.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltages.0 = INTEGER: 5 */ + { "unmapped.atsCalibrationPowerSupplyVoltages", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltageTableIndex.1 = INTEGER: 1 */ + { "unmapped.atsCalibrationPowerSupplyVoltageTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltageTableIndex.2 = INTEGER: 2 */ + { "unmapped.atsCalibrationPowerSupplyVoltageTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.1.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltageTableIndex.3 = INTEGER: 3 */ + { "unmapped.atsCalibrationPowerSupplyVoltageTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.1.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltageTableIndex.4 = INTEGER: 4 */ + { "unmapped.atsCalibrationPowerSupplyVoltageTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.1.4", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltageTableIndex.5 = INTEGER: 5 */ + { "unmapped.atsCalibrationPowerSupplyVoltageTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.1.5", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltage.1 = INTEGER: powerSupply24V(1) */ + { "unmapped.atsCalibrationPowerSupplyVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.2.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltage.2 = INTEGER: powerSupply12V(2) */ + { "unmapped.atsCalibrationPowerSupplyVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.2.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltage.3 = INTEGER: powerSupply(3) */ + { "unmapped.atsCalibrationPowerSupplyVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.2.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltage.4 = INTEGER: powerSupply24VSourceB(4) */ + { "unmapped.atsCalibrationPowerSupplyVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.2.4", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationPowerSupplyVoltage.5 = INTEGER: powerSupplyMinus12V(5) */ + { "unmapped.atsCalibrationPowerSupplyVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.2.5", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsPowerSupplyVoltageCalibrationFactor.1 = INTEGER: 521 */ + { "unmapped.atsPowerSupplyVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsPowerSupplyVoltageCalibrationFactor.2 = INTEGER: 1076 */ + { "unmapped.atsPowerSupplyVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.3.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsPowerSupplyVoltageCalibrationFactor.3 = INTEGER: 2560 */ + { "unmapped.atsPowerSupplyVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.3.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsPowerSupplyVoltageCalibrationFactor.4 = INTEGER: 521 */ + { "unmapped.atsPowerSupplyVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.3.4", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsPowerSupplyVoltageCalibrationFactor.5 = INTEGER: 975 */ + { "unmapped.atsPowerSupplyVoltageCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.2.2.1.3.5", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationNumOutputs.0 = INTEGER: 1 */ + { "unmapped.atsCalibrationNumOutputs", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.3.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationNumOutputPhases.0 = INTEGER: 1 */ + { "unmapped.atsCalibrationNumOutputPhases", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.3.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationOutputTableIndex.1.phase1.1 = INTEGER: 1 */ + { "unmapped.atsCalibrationOutputTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.3.3.1.1.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsCalibrationOutputPhasesTableIndex.1.phase1.1 = INTEGER: phase1(1) */ + { "unmapped.atsCalibrationOutputPhasesTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.3.3.1.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputCurrentCalibrationFactor.1.phase1.1 = INTEGER: 487 */ + { "unmapped.atsOutputCurrentCalibrationFactor", 0, 1, ".1.3.6.1.4.1.318.1.1.8.2.3.3.1.3.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsControlResetATS.0 = INTEGER: none(1) */ + { "unmapped.atsControlResetATS", 0, 1, ".1.3.6.1.4.1.318.1.1.8.3.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsControlClearAllAlarms.0 = INTEGER: -1 */ + { "unmapped.atsControlClearAllAlarms", 0, 1, ".1.3.6.1.4.1.318.1.1.8.3.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsConfigFrontPanelLockout.0 = INTEGER: enableFrontPanel(2) */ + { "unmapped.atsConfigFrontPanelLockout", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsConfigTransferVoltageRange.0 = INTEGER: medium(2) */ + { "unmapped.atsConfigTransferVoltageRange", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.5.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigCurrentLimit.0 = INTEGER: 32 */ + { "unmapped.atsConfigCurrentLimit", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigResetValues.0 = INTEGER: -1 */ + { "unmapped.atsConfigResetValues", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigLineVRMS.0 = INTEGER: 230 */ + { "unmapped.atsConfigLineVRMS", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.8.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigLineVRMSNarrowLimit.0 = INTEGER: 16 */ + { "unmapped.atsConfigLineVRMSNarrowLimit", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.9.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigLineVRMSMediumLimit.0 = INTEGER: 23 */ + { "unmapped.atsConfigLineVRMSMediumLimit", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.10.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigLineVRMSWideLimit.0 = INTEGER: 30 */ + { "unmapped.atsConfigLineVRMSWideLimit", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.11.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigFrequencyDeviation.0 = INTEGER: two(2) */ + { "unmapped.atsConfigFrequencyDeviation", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.12.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* Outlet groups collection */ + /* atsConfigBankLowLoadThreshold.1 = INTEGER: 0 */ + { "unmapped.atsConfigBankLowLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankLowLoadThreshold.2 = INTEGER: 0 */ + { "unmapped.atsConfigBankLowLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.3.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankLowLoadThreshold.3 = INTEGER: 0 */ + { "unmapped.atsConfigBankLowLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.3.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankNearOverLoadThreshold.1 = INTEGER: 28 */ + { "unmapped.atsConfigBankNearOverLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.4.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankNearOverLoadThreshold.2 = INTEGER: 12 */ + { "unmapped.atsConfigBankNearOverLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.4.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankNearOverLoadThreshold.3 = INTEGER: 12 */ + { "unmapped.atsConfigBankNearOverLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.4.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankOverLoadThreshold.1 = INTEGER: 32 */ + { "unmapped.atsConfigBankOverLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.5.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankOverLoadThreshold.2 = INTEGER: 16 */ + { "unmapped.atsConfigBankOverLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.5.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigBankOverLoadThreshold.3 = INTEGER: 16 */ + { "unmapped.atsConfigBankOverLoadThreshold", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.14.1.5.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsConfigPhaseTableSize.0 = INTEGER: 0 */ + { "unmapped.atsConfigPhaseTableSize", 0, 1, ".1.3.6.1.4.1.318.1.1.8.4.15.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusCommStatus.0 = INTEGER: atsCommEstablished(2) */ + { "unmapped.atsStatusCommStatus", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsStatusRedundancyState.0 = INTEGER: atsFullyRedundant(2) */ + { "unmapped.atsStatusRedundancyState", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusOverCurrentState.0 = INTEGER: atsCurrentOK(2) */ + { "unmapped.atsStatusOverCurrentState", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.4.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatus5VPowerSupply.0 = INTEGER: atsPowerSupplyOK(2) */ + { "unmapped.atsStatus5VPowerSupply", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.5.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatus24VPowerSupply.0 = INTEGER: atsPowerSupplyOK(2) */ + { "unmapped.atsStatus24VPowerSupply", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatus24VSourceBPowerSupply.0 = INTEGER: atsPowerSupplyOK(2) */ + { "unmapped.atsStatus24VSourceBPowerSupply", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusPlus12VPowerSupply.0 = INTEGER: atsPowerSupplyOK(2) */ + { "unmapped.atsStatusPlus12VPowerSupply", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.8.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusMinus12VPowerSupply.0 = INTEGER: atsPowerSupplyOK(2) */ + { "unmapped.atsStatusMinus12VPowerSupply", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.9.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusSwitchStatus.0 = INTEGER: ok(2) */ + { "unmapped.atsStatusSwitchStatus", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.10.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusFrontPanel.0 = INTEGER: unlocked(2) */ + { "unmapped.atsStatusFrontPanel", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.11.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusSourceAStatus.0 = INTEGER: ok(2) */ + { "unmapped.atsStatusSourceAStatus", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.12.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusSourceBStatus.0 = INTEGER: ok(2) */ + { "unmapped.atsStatusSourceBStatus", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.13.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusPhaseSyncStatus.0 = INTEGER: inSync(1) */ + { "unmapped.atsStatusPhaseSyncStatus", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.14.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsStatusHardwareStatus.0 = INTEGER: ok(2) */ + { "unmapped.atsStatusHardwareStatus", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.1.16.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsStatusResetMaxMinValues.0 = INTEGER: -1 */ + { "unmapped.atsStatusResetMaxMinValues", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.2.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsInputTableIndex.1 = INTEGER: 1 */ + { "unmapped.atsInputTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputTableIndex.2 = INTEGER: 2 */ + { "unmapped.atsInputTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.1.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsNumInputPhases.1 = INTEGER: 1 */ + { "unmapped.atsNumInputPhases", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.2.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsNumInputPhases.2 = INTEGER: 1 */ + { "unmapped.atsNumInputPhases", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.2.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputVoltageOrientation.1 = INTEGER: singlePhase(2) */ + { "unmapped.atsInputVoltageOrientation", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputVoltageOrientation.2 = INTEGER: singlePhase(2) */ + { "unmapped.atsInputVoltageOrientation", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.3.2", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsInputType.1 = INTEGER: main(2) */ + { "unmapped.atsInputType", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.5.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputType.2 = INTEGER: main(2) */ + { "unmapped.atsInputType", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.5.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputName.1 = STRING: "Source A" */ + { "unmapped.atsInputName", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.6.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputName.2 = STRING: "Source B" */ + { "unmapped.atsInputName", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.318.1.1.8.5.3.2.1.6.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputPhaseTableIndex.1.1.1 = INTEGER: 1 */ + { "unmapped.atsInputPhaseTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.1.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputPhaseTableIndex.2.1.1 = INTEGER: 2 */ + { "unmapped.atsInputPhaseTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.1.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputPhaseIndex.1.1.1 = INTEGER: 1 */ + { "unmapped.atsInputPhaseIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputPhaseIndex.2.1.1 = INTEGER: 1 */ + { "unmapped.atsInputPhaseIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.2.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsInputMaxVoltage.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMaxVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.4.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMaxVoltage.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMaxVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.4.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMinVoltage.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMinVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.5.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMinVoltage.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMinVoltage", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.5.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputCurrent.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.6.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputCurrent.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.6.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMaxCurrent.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMaxCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.7.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMaxCurrent.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMaxCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.7.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMinCurrent.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMinCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.8.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMinCurrent.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMinCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.8.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputPower.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.9.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputPower.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.9.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMaxPower.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMaxPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.10.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMaxPower.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMaxPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.10.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMinPower.1.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMinPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.11.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsInputMinPower.2.1.1 = INTEGER: -1 */ + { "unmapped.atsInputMinPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.3.3.1.11.2.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsNumOutputs.0 = INTEGER: 1 */ + { "unmapped.atsNumOutputs", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputTableIndex.1 = INTEGER: 1 */ + { "unmapped.atsOutputTableIndex", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsNumOutputPhases.1 = INTEGER: 1 */ + { "unmapped.atsNumOutputPhases", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.2.1.2.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputVoltageOrientation.1 = INTEGER: singlePhase(2) */ + { "unmapped.atsOutputVoltageOrientation", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.2.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsOutputPhase.1 = INTEGER: phase1(1) */ + { "unmapped.atsOutputPhase", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.2.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputPhase.2 = INTEGER: phase1(1) */ + { "unmapped.atsOutputPhase", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.2.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputPhase.3 = INTEGER: phase1(1) */ + { "unmapped.atsOutputPhase", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.2.3", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsOutputBankMaxCurrent.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.7.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxCurrent.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.7.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxCurrent.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.7.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinCurrent.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.8.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinCurrent.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.8.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinCurrent.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinCurrent", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.8.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankLoad.1 = INTEGER: 1883 */ + { "unmapped.atsOutputBankLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.9.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankLoad.2 = INTEGER: 984 */ + { "unmapped.atsOutputBankLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.9.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankLoad.3 = INTEGER: 898 */ + { "unmapped.atsOutputBankLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.9.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxLoad.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.10.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxLoad.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.10.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxLoad.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.10.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinLoad.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.11.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinLoad.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.11.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinLoad.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.11.3", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsOutputBankPercentLoad.1 = INTEGER: 25 */ + { "unmapped.atsOutputBankPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.12.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankPercentLoad.2 = INTEGER: 13 */ + { "unmapped.atsOutputBankPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.12.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankPercentLoad.3 = INTEGER: 12 */ + { "unmapped.atsOutputBankPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.12.3", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsOutputBankMaxPercentLoad.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.13.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPercentLoad.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.13.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPercentLoad.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.13.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPercentLoad.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.14.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPercentLoad.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.14.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPercentLoad.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPercentLoad", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.14.3", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsOutputBankMaxPower.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.16.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPower.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.16.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPower.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.16.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPower.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.17.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPower.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.17.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPower.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.17.3", NULL, SU_FLAG_OK, NULL, NULL }, + + /* atsOutputBankPercentPower.1 = INTEGER: 25 */ + { "unmapped.atsOutputBankPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.18.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankPercentPower.2 = INTEGER: 13 */ + { "unmapped.atsOutputBankPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.18.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankPercentPower.3 = INTEGER: 12 */ + { "unmapped.atsOutputBankPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.18.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPercentPower.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.19.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPercentPower.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.19.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMaxPercentPower.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMaxPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.19.3", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPercentPower.1 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.20.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPercentPower.2 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.20.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* atsOutputBankMinPercentPower.3 = INTEGER: -1 */ + { "unmapped.atsOutputBankMinPercentPower", 0, 1, ".1.3.6.1.4.1.318.1.1.8.5.4.5.1.20.3", NULL, SU_FLAG_OK, NULL, NULL }, +#endif /* 0 */ + + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL } +}; + +mib2nut_info_t apc_ats = { "apc_ats", APC_ATS_MIB_VERSION, NULL, NULL, apc_ats_mib, APC_ATS_SYSOID }; diff --git a/drivers/apc-ats-mib.h b/drivers/apc-ats-mib.h new file mode 100755 index 0000000..7a44a04 --- /dev/null +++ b/drivers/apc-ats-mib.h @@ -0,0 +1,29 @@ +/* apcats-mib.h - subdriver to monitor apcats SNMP devices with NUT + * + * Copyright (C) + * 2011 - 2012 Arnaud Quette + * + * 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 APCATS_MIB_H +#define APCATS_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t apc_ats; + +#endif /* APCATS_MIB_H */ diff --git a/drivers/apc-hid.c b/drivers/apc-hid.c index 34601d5..9bbeee1 100644 --- a/drivers/apc-hid.c +++ b/drivers/apc-hid.c @@ -31,7 +31,7 @@ #include "apc-hid.h" #include "usb-common.h" -#define APC_HID_VERSION "APC HID 0.95" +#define APC_HID_VERSION "APC HID 0.96" /* APC */ #define APC_VENDORID 0x051d @@ -62,6 +62,11 @@ static void *general_apc_check(USBDevice_t *device) { int i = 0; + if (!device->Product) { + upslogx(LOG_WARNING, "device->Product is NULL so it is not possible to determine whether to activate max_report_size workaround"); + return NULL; + } + /* Some models of Back-UPS overflow on some ReportID. * This results in some data not being exposed and IO errors on * WIN32, causing endless reconnection or driver's failure */ diff --git a/drivers/apc-mib.c b/drivers/apc-mib.c index b52ad1f..59eab70 100644 --- a/drivers/apc-mib.c +++ b/drivers/apc-mib.c @@ -63,7 +63,7 @@ static info_lkp_t apcc_batt_info[] = { { 1, "" }, /* unknown */ { 2, "" }, /* batteryNormal */ { 3, "LB" }, /* batteryLow */ - { 0, "NULL" } + { 0, NULL } } ; #define APCC_OID_POWER_STATUS ".1.3.6.1.4.1.318.1.1.1.4.1.1.0" @@ -81,7 +81,7 @@ static info_lkp_t apcc_pwr_info[] = { { 10, "BYPASS" }, /* hardwareFailureBypass */ { 11, "OFF" }, /* sleepingUntilPowerReturn */ { 12, "OL TRIM" }, /* onSmartTrim */ - { 0, "NULL" } + { 0, NULL } } ; #define APCC_OID_CAL_RESULTS ".1.3.6.1.4.1.318.1.1.1.7.2.6.0" @@ -89,14 +89,14 @@ static info_lkp_t apcc_cal_info[] = { { 1, "" }, /* Calibration Successful */ { 2, "" }, /* Calibration not done, battery capacity below 100% */ { 3, "CAL" }, /* Calibration in progress */ - { 0, "NULL" } + { 0, NULL } }; #define APCC_OID_NEEDREPLBATT ".1.3.6.1.4.1.318.1.1.1.2.2.4.0" static info_lkp_t apcc_battrepl_info[] = { { 1, "" }, /* No battery needs replacing */ { 2, "RB" }, /* Batteries need to be replaced */ - { 0, "NULL" } + { 0, NULL } }; #define APCC_OID_TESTDIAGRESULTS ".1.3.6.1.4.1.318.1.1.1.7.2.3.0" @@ -105,7 +105,7 @@ static info_lkp_t apcc_testdiag_results[] = { { 2, "Failed" }, { 3, "InvalidTest" }, { 4, "TestInProgress"}, - { 0, "NULL" } + { 0, NULL } }; #define APCC_OID_SENSITIVITY ".1.3.6.1.4.1.318.1.1.1.5.2.7.0" @@ -114,7 +114,7 @@ static info_lkp_t apcc_sensitivity_modes[] = { { 2, "low" }, { 3, "medium" }, { 4, "high" }, - { 0, "NULL" } + { 0, NULL } }; #define APCC_OID_TRANSFERREASON "1.3.6.1.4.1.318.1.1.1.3.2.5.0" diff --git a/drivers/baytech-mib.c b/drivers/baytech-mib.c index d17c0a5..ec0b8c3 100644 --- a/drivers/baytech-mib.c +++ b/drivers/baytech-mib.c @@ -23,7 +23,7 @@ #include "baytech-mib.h" -#define BAYTECH_MIB_VERSION "4031" +#define BAYTECH_MIB_VERSION "4032" /* Baytech MIB */ #define BAYTECH_OID_MIB ".1.3.6.1.4.1.4779" @@ -48,6 +48,8 @@ static snmp_info_t baytech_mib[] = { 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.2.1.2.2.1.6.2", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, /* UPS page */ { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "Baytech", @@ -62,8 +64,6 @@ static snmp_info_t baytech_mib[] = { 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.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.2.2.1.6.2", - "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, { "ups.temperature", 0, 0.1, ".1.3.6.1.4.1.4779.1.3.5.5.1.10.2.1", NULL, 0, NULL, NULL }, /* Outlet page */ @@ -88,4 +88,4 @@ static snmp_info_t baytech_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } }; -mib2nut_info_t baytech = { "baytech", BAYTECH_MIB_VERSION, "", BAYTECH_OID_MODEL_NAME, baytech_mib }; +mib2nut_info_t baytech = { "baytech", BAYTECH_MIB_VERSION, NULL, BAYTECH_OID_MODEL_NAME, baytech_mib }; diff --git a/drivers/bcmxcp.c b/drivers/bcmxcp.c index 98553c1..6fb2f86 100644 --- a/drivers/bcmxcp.c +++ b/drivers/bcmxcp.c @@ -117,7 +117,7 @@ TODO List: #include "bcmxcp.h" #define DRIVER_NAME "BCMXCP UPS driver" -#define DRIVER_VERSION "0.30" +#define DRIVER_VERSION "0.31" #define MAX_NUT_NAME_LENGTH 128 #define NUT_OUTLET_POSITION 7 @@ -1413,7 +1413,7 @@ void upsdrv_initinfo(void) if (strstr(pTmp, power_rating) == NULL) { snprintfcat(pTmp, len+10, " %s", power_rating); } - dstate_setinfo("ups.model", "%s", rtrim(pTmp, ' ')); + dstate_setinfo("ups.model", "%s", str_rtrim(pTmp, ' ')); free(pTmp); /* Get meter map info from ups, and init our map */ diff --git a/drivers/bcmxcp.h b/drivers/bcmxcp.h index 90c690c..058b34f 100644 --- a/drivers/bcmxcp.h +++ b/drivers/bcmxcp.h @@ -16,6 +16,7 @@ #define PW_COMMAND_START_BYTE (unsigned char)0xAB #define PW_LAST_SEQ (unsigned char)0x80 /* bit flag to indicate final sequence */ #define PW_SEQ_MASK (unsigned char)0x7F /* bit mask to extract just the sequence # */ +#define PW_HEADER_LENGTH 4 /* Size of response header */ #define PW_ANSWER_MAX_SIZE 256 diff --git a/drivers/bcmxcp_usb.c b/drivers/bcmxcp_usb.c index 2788029..cf5f171 100644 --- a/drivers/bcmxcp_usb.c +++ b/drivers/bcmxcp_usb.c @@ -128,18 +128,21 @@ void send_write_command(unsigned char *command, int command_length) } } +#define PW_HEADER_SIZE (PW_HEADER_LENGTH + 1) +#define PW_CMD_BUFSIZE 256 /* get the answer of a command from the ups. And check that the answer is for this command */ int get_answer(unsigned char *data, unsigned char command) { - unsigned char buf[1024], *my_buf = buf; - int length, end_length, res, endblock, bytes_read, ellapsed_time; + unsigned char buf[PW_CMD_BUFSIZE], *my_buf = buf; + int length, end_length, res, endblock, bytes_read, ellapsed_time, need_data; + int tail; unsigned char block_number, sequence, seq_num; struct timeval start_time, now; if (upsdev == NULL) return -1; - length = 1; /* non zero to enter the read loop */ + need_data = PW_HEADER_SIZE; /* 4 - cmd response header length, 1 for csum */ end_length = 0; /* total length of sequence(s), not counting header(s) */ endblock = 0; /* signal the last sequence in the block */ bytes_read = 0; /* total length of data read, including XCP header */ @@ -151,14 +154,14 @@ int get_answer(unsigned char *data, unsigned char command) /* Store current time */ gettimeofday(&start_time, NULL); + memset(&buf, 0x0, PW_CMD_BUFSIZE); while ( (!endblock) && ((XCP_USB_TIMEOUT - ellapsed_time) > 0) ) { /* Get (more) data if needed */ - if ((length - (bytes_read - 5)) > 0) { - res = usb_interrupt_read(upsdev, 0x81, - (char *)&buf[bytes_read], - (PW_ANSWER_MAX_SIZE - bytes_read), + if (need_data > 0) { + res = usb_interrupt_read(upsdev, 0x81, (char *) buf + bytes_read, + 128, (XCP_USB_TIMEOUT - ellapsed_time)); /* Update time */ @@ -181,54 +184,41 @@ int get_answer(unsigned char *data, unsigned char command) /* FIXME: */ continue; } - - /* Else, we got some input bytes */ + /* Else, we got some input bytes */ bytes_read += res; + need_data -= res; upsdebug_hex(1, "get_answer", buf, bytes_read); } + if (need_data > 0) /* We need more data */ + continue; + /* Now validate XCP frame */ /* Check header */ - if ( my_buf[0] != 0xAB ) { - upsdebugx(2, "get_answer: wrong header"); - return -1; + if ( my_buf[0] != PW_COMMAND_START_BYTE ) { + upsdebugx(2, "get_answer: wrong header 0xab vs %02x", my_buf[0]); + /* Sometime we read something wrong. bad cables? bad ports? */ + my_buf = memchr(my_buf, PW_COMMAND_START_BYTE, bytes_read); + if (!my_buf) + return -1; } - /* These validations seem not needed! */ /* Read block number byte */ block_number = my_buf[1]; upsdebugx(1, "get_answer: block_number = %x", block_number); -#if 0 - if (command <= 0x43) { - if ((command - 0x30) != block_number){ - nutusb_comm_fail("Receive error (Request command): BLOCK: %x (instead of %x), COMMAND: %x!\n", - block_number, (command - 0x30), command); - return -1; - } - } - - if (command >= 0x89) { - if ((command == 0xA0) && (block_number != 0x01)){ - nutusb_comm_fail("Receive error (Request command): BLOCK: %x (instead of 0x01), COMMAND: %x!\n", block_number, command); - return -1; - } - else if ((command != 0xA0) && (block_number != 0x09)){ - nutusb_comm_fail("Receive error (Request command): BLOCK: %x (instead of 0x09), COMMAND: %x!\n", block_number, command); - return -1; - } - } -#endif /* if 0 */ /* Check data length byte (remove the header length) */ length = my_buf[2]; upsdebugx(3, "get_answer: data length = %d", length); - if ((bytes_read - 5) < length) { - upsdebugx(2, "get_answer: need to read %d more data", length - (bytes_read - 5)); + if (bytes_read - (length + PW_HEADER_SIZE) < 0) { + if (need_data < 0) --need_data; /* count zerro byte too */ + need_data += length + 1; /* packet lenght + checksum */ + upsdebugx(2, "get_answer: need to read %d more data", need_data); continue; } /* Check if Length conforms to XCP (121 for normal, 140 for Test mode) */ /* Use the more generous length for testing */ - if (length > 140 ) { + if (length > 140) { upsdebugx(2, "get_answer: bad length"); return -1; } @@ -260,13 +250,19 @@ int get_answer(unsigned char *data, unsigned char command) } else { seq_num++; + upsdebugx(2, "get_answer: next sequence is %d", seq_num); } /* copy the current valid XCP frame back */ - memcpy(data+end_length, my_buf+4, length); + memcpy(data+end_length, my_buf + 4, length); /* increment pointers to process the next sequence */ end_length += length; - my_buf += length + 5; + tail = bytes_read - (length + PW_HEADER_SIZE); + if (tail > 0) + my_buf = memmove(&buf[0], my_buf + length + PW_HEADER_SIZE, tail); + else if (tail == 0) + my_buf = &buf[0]; + bytes_read = tail; } upsdebug_hex (5, "get_answer", data, end_length); @@ -431,6 +427,10 @@ usb_dev_handle *nutusb_open(const char *port) if (usb_clear_halt(dev_h, 0x81) < 0) { upsdebugx(1, "Can't reset POWERWARE USB endpoint: %s", usb_strerror()); + if (dev_claimed) + usb_release_interface(dev_h, 0); + usb_reset(dev_h); + sleep(5); /* Wait reconnect */ errout = 1; } else diff --git a/drivers/bestpower-mib.c b/drivers/bestpower-mib.c index 29c1926..ea87186 100644 --- a/drivers/bestpower-mib.c +++ b/drivers/bestpower-mib.c @@ -36,7 +36,7 @@ static info_lkp_t bestpower_power_status[] = { { 1, "OL" }, { 2, "OB" }, - { 0, "NULL" } + { 0, NULL } } ; /* Snmp2NUT lookup table for Best Power MIB */ @@ -80,5 +80,5 @@ static snmp_info_t bestpower_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } } ; -mib2nut_info_t bestpower = { "bestpower", BESTPOWER_MIB_VERSION, "", +mib2nut_info_t bestpower = { "bestpower", BESTPOWER_MIB_VERSION, NULL, BESTPOWER_OID_MODEL_NAME, bestpower_mib }; diff --git a/drivers/blazer.c b/drivers/blazer.c index cbcfadc..da72928 100644 --- a/drivers/blazer.c +++ b/drivers/blazer.c @@ -381,7 +381,7 @@ static int blazer_vendor(const char *cmd) snprintf(val, sizeof(val), "%.*s", information[i].len, &buf[index]); - dstate_setinfo(information[i].var, "%s", rtrim(val, ' ')); + dstate_setinfo(information[i].var, "%s", str_rtrim(val, ' ')); } return 0; diff --git a/drivers/blazer_ser.c b/drivers/blazer_ser.c index 7fa7280..629bec2 100644 --- a/drivers/blazer_ser.c +++ b/drivers/blazer_ser.c @@ -26,7 +26,7 @@ #include "blazer.h" #define DRIVER_NAME "Megatec/Q1 protocol serial driver" -#define DRIVER_VERSION "1.56" +#define DRIVER_VERSION "1.57" /* driver description structure */ upsdrv_info_t upsdrv_info = { diff --git a/drivers/blazer_usb.c b/drivers/blazer_usb.c index 14d2af9..0e1a74d 100644 --- a/drivers/blazer_usb.c +++ b/drivers/blazer_usb.c @@ -28,7 +28,7 @@ #include "blazer.h" #define DRIVER_NAME "Megatec/Q1 protocol USB driver" -#define DRIVER_VERSION "0.11" +#define DRIVER_VERSION "0.12" /* driver description structure */ upsdrv_info_t upsdrv_info = { diff --git a/drivers/compaq-mib.c b/drivers/compaq-mib.c index a4eacc0..cd7e11e 100644 --- a/drivers/compaq-mib.c +++ b/drivers/compaq-mib.c @@ -86,14 +86,14 @@ /* Not used, as no longer supported by MIB ver. 1.76 (Github issue 118) static info_lkp_t cpqpower_alarm_ob[] = { { 1, "OB" }, - { 0, "NULL" } + { 0, NULL } }; */ /* Not used, as no longer supported by MIB ver. 1.76 (Github issue 118) static info_lkp_t cpqpower_alarm_lb[] = { { 1, "LB" }, - { 0, "NULL" } + { 0, NULL } }; */ @@ -109,7 +109,7 @@ static info_lkp_t cpqpower_pwr_info[] = { { 8, "OL" /* parallelCapacity */ }, { 9, "OL" /* parallelRedundant */ }, { 10, "OL" /* HighEfficiencyMode */ }, - { 0, "NULL" } + { 0, NULL } } ; static info_lkp_t cpqpower_mode_info[] = { @@ -123,7 +123,7 @@ static info_lkp_t cpqpower_mode_info[] = { { 8, "parallel capacity" }, { 9, "parallel redundancy" }, {10, "high efficiency" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t cpqpower_battery_abm_status[] = { @@ -132,7 +132,7 @@ static info_lkp_t cpqpower_battery_abm_status[] = { /* { 3, "Floating" }, */ /* { 4, "Resting" }, */ /* { 5, "Unknown" }, */ - { 0, "NULL" } + { 0, NULL } } ; /* Defines for CPQPOWER_OID_UPS_TEST_RES */ @@ -144,7 +144,7 @@ static info_lkp_t cpqpower_test_res_info[] = { { 5, "Not supported" }, { 6, "Inhibited" }, { 7, "Scheduled" }, - { 0, "NULL" } + { 0, NULL } } ; #define CPQPOWER_START_TEST 1 @@ -328,5 +328,5 @@ static snmp_info_t cpqpower_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } }; -mib2nut_info_t compaq = { "cpqpower", CPQPOWER_MIB_VERSION, "", CPQPOWER_OID_MFR_NAME, cpqpower_mib, CPQPOWER_SYSOID }; +mib2nut_info_t compaq = { "cpqpower", CPQPOWER_MIB_VERSION, NULL, CPQPOWER_OID_MFR_NAME, cpqpower_mib, CPQPOWER_SYSOID }; diff --git a/drivers/cyberpower-mib.c b/drivers/cyberpower-mib.c index e2d81cd..93b7bc4 100644 --- a/drivers/cyberpower-mib.c +++ b/drivers/cyberpower-mib.c @@ -37,7 +37,7 @@ static info_lkp_t cyberpower_power_status[] = { { 7, "OL" }, { 1, "NULL" }, { 6, "NULL" }, - { 0, "NULL" } + { 0, NULL } } ; /* Snmp2NUT lookup table for CyberPower MIB */ @@ -77,5 +77,5 @@ static snmp_info_t cyberpower_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } } ; -mib2nut_info_t cyberpower = { "cyberpower", CYBERPOWER_MIB_VERSION, "", +mib2nut_info_t cyberpower = { "cyberpower", CYBERPOWER_MIB_VERSION, NULL, CYBERPOWER_OID_MODEL_NAME, cyberpower_mib, CYBERPOWER_SYSOID }; diff --git a/drivers/delta_ups-mib.c b/drivers/delta_ups-mib.c index 7b10858..e3ba55e 100644 --- a/drivers/delta_ups-mib.c +++ b/drivers/delta_ups-mib.c @@ -34,7 +34,7 @@ * static info_lkp_t onbatt_info[] = { * { 1, "OB" }, * { 2, "OL" }, - * { 0, "NULL" } + * { 0, NULL } * }; */ @@ -44,7 +44,7 @@ static info_lkp_t delta_ups_upstype_info[] = { { 3, "line-interactive" }, { 4, "3phase" }, { 5, "splite-phase" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t delta_ups_pwr_info[] = { @@ -56,7 +56,7 @@ static info_lkp_t delta_ups_pwr_info[] = { { 5, "BYPASS" }, /* manualBypass */ /*{ 6, "NULL" },*/ /* other */ { 7, "OFF" }, /* none */ - { 0, "NULL" } + { 0, NULL } } ; /* DELTA_UPS Snmp2NUT lookup table */ @@ -84,7 +84,7 @@ static snmp_info_t delta_ups_mib[] = { * static info_lkp_t onbatt_info[] = { * { 1, "OB" }, * { 2, "OL" }, - * { 0, "NULL" } + * { 0, NULL } * }; */ diff --git a/drivers/dstate.c b/drivers/dstate.c index 20d239a..6adb1f2 100644 --- a/drivers/dstate.c +++ b/drivers/dstate.c @@ -35,7 +35,7 @@ static int sockfd = -1, stale = 1, alarm_active = 0, ignorelb = 0; static char *sockfn = NULL; - static char status_buf[ST_MAX_VALUE_LEN], alarm_buf[ST_MAX_VALUE_LEN]; + static char status_buf[ST_MAX_VALUE_LEN], alarm_buf[LARGEBUF]; static st_tree_t *dtree_root = NULL; static conn_t *connhead = NULL; static cmdlist_t *cmdhead = NULL; @@ -185,7 +185,7 @@ static void send_to_all(const char *fmt, ...) ret = write(conn->fd, buf, strlen(buf)); if (ret != (int)strlen(buf)) { - upsdebugx(2, "write %d bytes to socket %d failed", (int)strlen(buf), conn->fd); + upsdebugx(1, "write %d bytes to socket %d failed", (int)strlen(buf), conn->fd); sock_disconnect(conn); } } @@ -211,7 +211,7 @@ static int send_to_one(conn_t *conn, const char *fmt, ...) ret = write(conn->fd, buf, strlen(buf)); if (ret != (int)strlen(buf)) { - upsdebugx(2, "write %d bytes to socket %d failed", (int)strlen(buf), conn->fd); + upsdebugx(1, "write %d bytes to socket %d failed", (int)strlen(buf), conn->fd); sock_disconnect(conn); return 0; /* failed */ } diff --git a/drivers/dummy-ups.c b/drivers/dummy-ups.c index 7dbb991..6518ef3 100644 --- a/drivers/dummy-ups.c +++ b/drivers/dummy-ups.c @@ -1,7 +1,7 @@ /* dummy-ups.c - NUT simulation and device repeater driver Copyright (C) - 2005 - 2010 Arnaud Quette + 2005 - 2015 Arnaud Quette 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 @@ -40,7 +40,7 @@ #include "dummy-ups.h" #define DRIVER_NAME "Device simulation and repeater driver" -#define DRIVER_VERSION "0.13" +#define DRIVER_VERSION "0.14" /* driver description structure */ upsdrv_info_t upsdrv_info = @@ -309,6 +309,12 @@ static int setvar(const char *varname, const char *val) if (item->info_flags & ST_FLAG_STRING) dstate_setaux(item->info_type, item->info_len); } + else + { + upsdebugx(2, "setvar: unknown variable (%s), using default flags", varname); + dstate_setflags(varname, ST_FLAG_STRING | ST_FLAG_RW); + dstate_setaux(varname, 32); + } } return STAT_SET_HANDLED; } diff --git a/drivers/dummy-ups.h b/drivers/dummy-ups.h index 49294ca..978f5d3 100644 --- a/drivers/dummy-ups.h +++ b/drivers/dummy-ups.h @@ -186,7 +186,7 @@ battery.packs.bad { "ambient.humidity.high", ST_FLAG_RW, 1, NULL, DU_FLAG_NONE, NULL }, { "ambient.humidity.low", ST_FLAG_RW, 1, NULL, DU_FLAG_NONE, NULL }, /* -FIXME: how to manage these? +FIXME: how to manage these? (i.e. index ) outlet.n.id outlet.n.desc outlet.n.switch @@ -195,6 +195,7 @@ outlet.n.switchable outlet.n.autoswitch.charge.low outlet.n.delay.shutdown outlet.n.delay.start +... driver.name driver.version diff --git a/drivers/eaton-ats-mib.c b/drivers/eaton-ats-mib.c new file mode 100644 index 0000000..572b782 --- /dev/null +++ b/drivers/eaton-ats-mib.c @@ -0,0 +1,245 @@ +/* eaton_ats-mib.c - subdriver to monitor eaton_ats SNMP devices with NUT + * + * Copyright (C) + * 2011 - 2012 Arnaud Quette + * 2016 Arnaud Quette + * + * Note: this subdriver was initially generated as a "stub" by the + * gen-snmp-subdriver script. It must be customized! + * + * 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-ats-mib.h" + +#define EATON_ATS_MIB_VERSION "0.11" + +#define EATON_ATS_SYSOID ".1.3.6.1.4.1.534.10" +#define EATON_ATS_MODEL ".1.3.6.1.4.1.534.10.2.1.2.0" + +static info_lkp_t ats_source_info[] = { + { 1, "init" }, + { 2, "diagnosis" }, + { 3, "off" }, + { 4, "1" }, + { 5, "2" }, + { 6, "safe" }, + { 7, "fault" }, + { 0, NULL } +}; + +static info_lkp_t ats_sensitivity_info[] = { + { 1, "normal" }, + { 2, "high" }, + { 3, "low" }, + { 0, NULL } +}; + +static info_lkp_t ats_input_frequency_status_info[] = { + { 1, "good" }, /* No threshold triggered */ + { 2, "out-of-range" }, /* Frequency out of range triggered */ + { 0, NULL } +}; + +static info_lkp_t ats_input_voltage_status_info[] = { + { 1, "good" }, /* No threshold triggered */ + { 2, "derated-range" }, /* Voltage derated */ + { 3, "out-of-range" }, /* Voltage out of range triggered */ + { 4, "unknown" }, /* "missing" */ + { 0, NULL } +}; + +static info_lkp_t ats_test_result_info[] = { + { 1, "done and passed" }, + { 2, "done and warning" }, + { 3, "done and error" }, + { 4, "aborted" }, + { 5, "in progress" }, + { 6, "no test initiated" }, + { 0, NULL } +}; + +static info_lkp_t ats_output_status_info[] = { + { 1, "OFF" }, /* Output not powered */ + { 2, "OL" }, /* Output powered */ + { 0, NULL } +}; + +/* EATON_ATS Snmp2NUT lookup table */ +static snmp_info_t eaton_ats_mib[] = { + + /* Device collection */ + { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "ats", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + /* ats2IdentManufacturer.0 = STRING: EATON */ + { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.1.0", "Eaton", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* ats2IdentModel.0 = STRING: Eaton ATS */ + { "device.model", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.2.0", "ATS", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* FIXME: RFC for device.firmware! */ + /* ats2IdentFWVersion.0 = STRING: 00.00.0009 */ + { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.3.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* FIXME: RFC for device.firmware.aux! */ + /* ats2IdentRelease.0 = STRING: JF */ + { "ups.firmware.aux", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.4.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* ats2IdentSerialNumber.0 = STRING: GA04F23009 */ + { "device.serial", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.5.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* ats2IdentPartNumber.0 = STRING: EATS16N */ + { "device.part", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.6.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* ats2IdentAgentVersion.0 = STRING: 301F23C28 */ + /* { "unmapped.ats2IdentAgentVersion", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.1.7.0", NULL, SU_FLAG_OK, NULL, NULL }, */ + /* ats2InputDephasing.0 = INTEGER: 2 degrees */ + /* { "unmapped.ats2InputDephasing", 0, 1, ".1.3.6.1.4.1.534.10.2.2.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, */ + + /* Input collection */ + /* ats2InputIndex.source1 = INTEGER: source1(1) */ + { "input.1.id", 0, 1, ".1.3.6.1.4.1.534.10.2.2.2.1.1.1", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* ats2InputIndex.source2 = INTEGER: source2(2) */ + { "input.2.id", 0, 1, ".1.3.6.1.4.1.534.10.2.2.2.1.1.2", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* ats2InputVoltage.source1 = INTEGER: 2292 0.1 V */ + { "input.1.voltage", 0, 0.1, ".1.3.6.1.4.1.534.10.2.2.2.1.2.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputVoltage.source2 = INTEGER: 2432 0.1 V */ + { "input.2.voltage", 0, 0.1, ".1.3.6.1.4.1.534.10.2.2.2.1.2.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusVoltage.source1 = INTEGER: normalRange(1) */ + { "input.1.voltage.status", ST_FLAG_STRING, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.5.1", NULL, SU_FLAG_OK, ats_input_voltage_status_info, NULL }, + /* ats2InputStatusVoltage.source2 = INTEGER: normalRange(1) */ + { "input.2.voltage.status", ST_FLAG_STRING, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.5.2", NULL, SU_FLAG_OK, ats_input_voltage_status_info, NULL }, + /* ats2InputFrequency.source1 = INTEGER: 500 0.1 Hz */ + { "input.1.frequency", 0, 0.1, ".1.3.6.1.4.1.534.10.2.2.2.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputFrequency.source2 = INTEGER: 500 0.1 Hz */ + { "input.2.frequency", 0, 0.1, ".1.3.6.1.4.1.534.10.2.2.2.1.3.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusFrequency.source1 = INTEGER: good(1) */ + { "input.1.frequency.status", ST_FLAG_STRING, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.2.1", NULL, SU_FLAG_OK, ats_input_frequency_status_info, NULL }, + /* ats2InputStatusFrequency.source2 = INTEGER: good(1) */ + { "input.2.frequency.status", ST_FLAG_STRING, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.2.2", NULL, SU_FLAG_OK, ats_input_frequency_status_info, NULL }, + /* ats2ConfigSensitivity.0 = INTEGER: normal(1) */ + { "input.sensitivity", ST_FLAG_RW, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.4.6.0", NULL, SU_FLAG_OK, &ats_sensitivity_info[0], NULL }, + /* ats2OperationMode.0 = INTEGER: source1(4) */ + { "input.source", ST_FLAG_STRING, 1, ".1.3.6.1.4.1.534.10.2.2.4.0", NULL, SU_FLAG_OK, ats_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 }, + + /* Output collection */ + /* ats2OutputVoltage.0 = INTEGER: 2304 0.1 V */ + { "output.voltage", 0, 0.1, ".1.3.6.1.4.1.534.10.2.2.3.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigOutputVoltage.0 = INTEGER: 230 1 V */ + { "output.voltage.nominal", ST_FLAG_RW, 1, ".1.3.6.1.4.1.534.10.2.4.4.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2OutputCurrent.0 = INTEGER: 5 0.1 A */ + { "output.current", 0, 0.1, ".1.3.6.1.4.1.534.10.2.2.3.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* UPS collection */ + /* FIXME: RFC for device.test.result! */ + /* ats2ConfigTransferTest.0 = INTEGER: noTestInitiated(6) */ + { "ups.test.result", 0, 1, ".1.3.6.1.4.1.534.10.2.4.8.0", NULL, SU_FLAG_OK, ats_test_result_info, NULL }, + /* FIXME: RFC for device.status! */ + /* ats2StatusOutput.0 = INTEGER: outputPowered(2) */ + { "ups.status", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.2.0", NULL, SU_FLAG_OK, ats_output_status_info, NULL }, + + /* Ambient collection */ + /* ats2EnvRemoteTemp.0 = INTEGER: 0 degrees Centigrade */ + { "ambient.temperature", 0, 1, ".1.3.6.1.4.1.534.10.2.5.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2EnvRemoteTempLowerLimit.0 = INTEGER: 5 degrees Centigrade */ + { "ambient.temperature.low", ST_FLAG_RW, 1, ".1.3.6.1.4.1.534.10.2.5.5.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2EnvRemoteTempUpperLimit.0 = INTEGER: 40 degrees Centigrade */ + { "ambient.temperature.high", ST_FLAG_RW, 1, ".1.3.6.1.4.1.534.10.2.5.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2EnvRemoteHumidity.0 = INTEGER: 0 percent */ + { "ambient.humidity", 0, 1, ".1.3.6.1.4.1.534.10.2.5.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2EnvRemoteHumidityLowerLimit.0 = INTEGER: 5 percent */ + { "ambient.humidity.low", ST_FLAG_RW, 1, ".1.3.6.1.4.1.534.10.2.5.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2EnvRemoteHumidityUpperLimit.0 = INTEGER: 90 percent */ + { "ambient.humidity.high", ST_FLAG_RW, 1, ".1.3.6.1.4.1.534.10.2.5.8.0", NULL, SU_FLAG_OK, NULL, NULL }, + +#if 0 /* FIXME: Remaining data to be processed */ + /* ats2InputStatusDephasing.0 = INTEGER: normal(1) */ + { "unmapped.ats2InputStatusDephasing", 0, 1, ".1.3.6.1.4.1.534.10.2.3.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusIndex.source1 = INTEGER: source1(1) */ + { "unmapped.ats2InputStatusIndex", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusIndex.source2 = INTEGER: source2(2) */ + { "unmapped.ats2InputStatusIndex", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.1.2", NULL, SU_FLAG_OK, NULL, NULL }, + + /* ats2InputStatusGood.source1 = INTEGER: voltageAndFreqNormalRange(2) */ + { "unmapped.ats2InputStatusGood", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusGood.source2 = INTEGER: voltageAndFreqNormalRange(2) */ + { "unmapped.ats2InputStatusGood", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.3.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusInternalFailure.source1 = INTEGER: good(1) */ + { "unmapped.ats2InputStatusInternalFailure", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.4.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusInternalFailure.source2 = INTEGER: good(1) */ + { "unmapped.ats2InputStatusInternalFailure", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.4.2", NULL, SU_FLAG_OK, NULL, NULL }, + + /* ats2InputStatusUsed.source1 = INTEGER: poweringLoad(2) */ + { "unmapped.ats2InputStatusUsed", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.6.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2InputStatusUsed.source2 = INTEGER: notPoweringLoad(1) */ + { "unmapped.ats2InputStatusUsed", 0, 1, ".1.3.6.1.4.1.534.10.2.3.2.1.6.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2StatusInternalFailure.0 = INTEGER: good(1) */ + { "unmapped.ats2StatusInternalFailure", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* ats2StatusOverload.0 = INTEGER: noOverload(1) */ + { "unmapped.ats2StatusOverload", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2StatusOverTemperature.0 = INTEGER: noOverTemperature(1) */ + { "unmapped.ats2StatusOverTemperature", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.4.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2StatusShortCircuit.0 = INTEGER: noShortCircuit(1) */ + { "unmapped.ats2StatusShortCircuit", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.5.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2StatusCommunicationLost.0 = INTEGER: good(1) */ + { "unmapped.ats2StatusCommunicationLost", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.6.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2StatusConfigurationFailure.0 = INTEGER: good(1) */ + { "unmapped.ats2StatusConfigurationFailure", 0, 1, ".1.3.6.1.4.1.534.10.2.3.3.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigTimeRTC.0 = Wrong Type (should be Counter32): Gauge32: 19191036 */ + { "unmapped.ats2ConfigTimeRTC", 0, 1, ".1.3.6.1.4.1.534.10.2.4.1.1.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigTimeTextDate.0 = STRING: 08/11/1970 */ + { "unmapped.ats2ConfigTimeTextDate", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.4.1.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigTimeTextTime.0 = STRING: 02/50/36 */ + { "unmapped.ats2ConfigTimeTextTime", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.4.1.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigInputVoltageRating.0 = INTEGER: 1 1 V */ + { "unmapped.ats2ConfigInputVoltageRating", 0, 1, ".1.3.6.1.4.1.534.10.2.4.2.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigInputFrequencyRating.0 = INTEGER: 50 Hz */ + { "unmapped.ats2ConfigInputFrequencyRating", 0, 1, ".1.3.6.1.4.1.534.10.2.4.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* ats2ConfigTransferMode.0 = INTEGER: standard(1) */ + { "unmapped.ats2ConfigTransferMode", 0, 1, ".1.3.6.1.4.1.534.10.2.4.7.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* ats2ConfigBrownoutLow.0 = INTEGER: 202 1 V */ + { "unmapped.ats2ConfigBrownoutLow", 0, 1, ".1.3.6.1.4.1.534.10.2.4.9.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigBrownoutLowDerated.0 = INTEGER: 189 1 V */ + { "unmapped.ats2ConfigBrownoutLowDerated", 0, 1, ".1.3.6.1.4.1.534.10.2.4.10.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigBrownoutHigh.0 = INTEGER: 258 1 V */ + { "unmapped.ats2ConfigBrownoutHigh", 0, 1, ".1.3.6.1.4.1.534.10.2.4.11.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ConfigHysteresisVoltage.0 = INTEGER: 5 1 V */ + { "unmapped.ats2ConfigHysteresisVoltage", 0, 1, ".1.3.6.1.4.1.534.10.2.4.12.0", NULL, SU_FLAG_OK, NULL, NULL }, + + /* Ambient collection */ + /* ats2EnvNumContacts.0 = INTEGER: 2 */ + { "unmapped.ats2EnvNumContacts", 0, 1, ".1.3.6.1.4.1.534.10.2.5.3.0", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactIndex.1 = INTEGER: 1 */ + { "unmapped.ats2ContactIndex", 0, 1, ".1.3.6.1.4.1.534.10.2.5.4.1.1.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactIndex.2 = INTEGER: 2 */ + { "unmapped.ats2ContactIndex", 0, 1, ".1.3.6.1.4.1.534.10.2.5.4.1.1.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactType.1 = INTEGER: notUsed(4) */ + { "unmapped.ats2ContactType", 0, 1, ".1.3.6.1.4.1.534.10.2.5.4.1.2.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactType.2 = INTEGER: notUsed(4) */ + { "unmapped.ats2ContactType", 0, 1, ".1.3.6.1.4.1.534.10.2.5.4.1.2.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactState.1 = INTEGER: open(1) */ + { "unmapped.ats2ContactState", 0, 1, ".1.3.6.1.4.1.534.10.2.5.4.1.3.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactState.2 = INTEGER: open(1) */ + { "unmapped.ats2ContactState", 0, 1, ".1.3.6.1.4.1.534.10.2.5.4.1.3.2", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactDescr.1 = STRING: Input #1 */ + { "unmapped.ats2ContactDescr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.5.4.1.4.1", NULL, SU_FLAG_OK, NULL, NULL }, + /* ats2ContactDescr.2 = STRING: Input #2 */ + { "unmapped.ats2ContactDescr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.10.2.5.4.1.4.2", NULL, SU_FLAG_OK, NULL, NULL }, +#endif /* if 0 */ + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL } +}; + +mib2nut_info_t eaton_ats = { "eaton_ats", EATON_ATS_MIB_VERSION, NULL, EATON_ATS_MODEL, eaton_ats_mib, ".1.3.6.1.4.1.705.1" }; +/* FIXME: Eaton ATS need to be fixed for the sysOID (currently .1.3.6.1.4.1.705.1!) */ +/* mib2nut_info_t eaton_ats = { "eaton_ats", EATON_ATS_MIB_VERSION, NULL, EATON_ATS_MODEL, eaton_ats_mib, EATON_ATS_SYSOID }; */ diff --git a/drivers/eaton-ats-mib.h b/drivers/eaton-ats-mib.h new file mode 100644 index 0000000..8b04f4e --- /dev/null +++ b/drivers/eaton-ats-mib.h @@ -0,0 +1,30 @@ +/* eaton_ats-mib.h - subdriver to monitor eaton_ats SNMP devices with NUT + * + * Copyright (C) + * 2011 - 2012 Arnaud Quette + * 2016 Arnaud Quette + * + * 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_ATS_MIB_H +#define EATON_ATS_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t eaton_ats; + +#endif /* EATON_ATS_MIB_H */ diff --git a/drivers/eaton-mib.c b/drivers/eaton-mib.c index 77d9e00..6eccc51 100644 --- a/drivers/eaton-mib.c +++ b/drivers/eaton-mib.c @@ -30,7 +30,7 @@ #include "eaton-mib.h" -#define EATON_APHEL_MIB_VERSION "0.46" +#define EATON_APHEL_MIB_VERSION "0.47" /* APHEL-GENESIS-II-MIB (monitored ePDU) * ************************************* @@ -56,6 +56,8 @@ static snmp_info_t eaton_aphel_genesisII_mib[] = { "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", @@ -68,8 +70,6 @@ static snmp_info_t eaton_aphel_genesisII_mib[] = { 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 }, - { "ups.macaddr", ST_FLAG_STRING, SU_INFOSIZE, APHEL1_OID_UNIT_MACADDR, "unknown", - 0, NULL, NULL }, /* Outlet page */ /* we can't use template since there is no counterpart to outlet.count */ @@ -132,7 +132,7 @@ static info_lkp_t outlet_status_info[] = { /* Snmp2NUT lookup table for Eaton Revelation MIB */ static snmp_info_t eaton_aphel_revelation_mib[] = { - /* Device page */ + /* 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, @@ -141,8 +141,10 @@ static snmp_info_t eaton_aphel_revelation_mib[] = { 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 }, - /* UPS page */ + /* 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, @@ -155,11 +157,9 @@ static snmp_info_t eaton_aphel_revelation_mib[] = { 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.macaddr", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_UNIT_MACADDR, "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, { "ups.temperature", 0, 1, AR_OID_UNIT_CPUTEMPERATURE, NULL, 0, NULL, NULL }, - /* Outlet page */ + /* 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 }, @@ -190,7 +190,7 @@ static snmp_info_t eaton_aphel_revelation_mib[] = { * ambient.%i.humidity => .1.3.6.1.4.1.534.6.6.6.2.4.1.3.%i */ - /* Ambient page */ + /* 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 }, @@ -217,7 +217,7 @@ static snmp_info_t eaton_aphel_revelation_mib[] = { /* Eaton PDU-MIB - Marlin MIB * ************************** */ -#define EATON_MARLIN_MIB_VERSION "0.10" +#define EATON_MARLIN_MIB_VERSION "0.37" #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" @@ -229,6 +229,14 @@ static info_lkp_t marlin_outlet_status_info[] = { { 0, NULL } }; +static info_lkp_t marlin_outletgroups_status_info[] = { + { 0, "off" }, + { 1, "on" }, + { 2, "rebooting" }, /* transitional status */ + { 3, "mixed" }, /* transitional status, not sure what it means! */ + { 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 outlet_switchability_info[] = { @@ -237,10 +245,91 @@ static info_lkp_t outlet_switchability_info[] = { { 0, NULL } }; +static info_lkp_t marlin_ambient_presence_info[] = { + { -1, "unknown" }, + { 0, "no" }, /* disconnected */ + { 1, "yes" }, /* connected */ + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_status_info[] = { + { 0, "good" }, /* No threshold triggered */ + { 1, "warning-low" }, /* Warning low threshold triggered */ + { 2, "critical-low" }, /* Critical low threshold triggered */ + { 3, "warning-high" }, /* Warning high threshold triggered */ + { 4, "critical-high" }, /* Critical high threshold triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_frequency_status_info[] = { + { 0, "good" }, /* No threshold triggered */ + { 1, "out-of-range" }, /* Frequency out of range triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_ambient_drycontacts_info[] = { + { -1, "unknown" }, + { 0, "open" }, + { 1, "closed" }, + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_voltage_alarms_info[] = { + { 0, "" }, /* No threshold triggered */ + { 1, "low voltage warning!" }, /* Warning low threshold triggered */ + { 2, "low voltage critical!" }, /* Critical low threshold triggered */ + { 3, "high voltage warning!" }, /* Warning high threshold triggered */ + { 4, "high voltage critical!" }, /* Critical high threshold triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_current_alarms_info[] = { + { 0, "" }, /* No threshold triggered */ + { 1, "low current warning!" }, /* Warning low threshold triggered */ + { 2, "low current critical!" }, /* Critical low threshold triggered */ + { 3, "high current warning!" }, /* Warning high threshold triggered */ + { 4, "high current critical!" }, /* Critical high threshold triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_frequency_alarm_info[] = { + { 0, "" }, /* No threshold triggered */ + { 1, "frequency out of range!" }, /* Frequency out of range triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_temperature_alarms_info[] = { + { 0, "" }, /* No threshold triggered */ + { 1, "low temperature warning!" }, /* Warning low threshold triggered */ + { 2, "low temperature critical!" }, /* Critical low threshold triggered */ + { 3, "high temperature warning!" }, /* Warning high threshold triggered */ + { 4, "high temperature critical!" }, /* Critical high threshold triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_threshold_humidity_alarms_info[] = { + { 0, "" }, /* No threshold triggered */ + { 1, "low humidity warning!" }, /* Warning low threshold triggered */ + { 2, "low humidity critical!" }, /* Critical low threshold triggered */ + { 3, "high humidity warning!" }, /* Warning high threshold triggered */ + { 4, "high humidity critical!" }, /* Critical high threshold triggered */ + { 0, NULL } +}; + +static info_lkp_t marlin_outlet_group_type_info[] = { + { 0, "unknown" }, + { 1, "breaker1pole" }, + { 2, "breaker2pole" }, + { 3, "breaker3pole" }, + { 4, "outlet-section" }, + { 5, "user-defined" }, + { 0, NULL } +}; + /* Snmp2NUT lookup table for Eaton Marlin MIB */ static snmp_info_t eaton_marlin_mib[] = { - /* Device page */ + /* Device collection */ { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, { "device.model", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0", @@ -249,11 +338,12 @@ static snmp_info_t eaton_marlin_mib[] = { "", 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 }, - /* FIXME: need RFC validation on this variable - * { "device.part", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.3.0", - "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, */ + { "device.part", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.3.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.2.2.1.6.2", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - /* UPS page */ + /* UPS collection */ { "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, "1.3.6.1.4.1.534.6.6.7.1.2.1.2.0", @@ -268,12 +358,7 @@ static snmp_info_t eaton_marlin_mib[] = { "", 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 }, - /* TODO: - * The below possibly requires (?) the use of - * int snprint_hexstring(char *buf, size_t buf_len, const u_char *, size_t); - * { "ups.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.2.2.1.6.2", - "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, - * + date reformating callback + /* 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 * { "ups.date", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.8.0", @@ -282,12 +367,12 @@ static snmp_info_t eaton_marlin_mib[] = { "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, */ - /* Input page */ + /* Input collection */ /* Historically, some of these data were previously published as * outlet.{realpower,...} * However, it's more suitable and logic to have these on input.{...} */ - { "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_OK, NULL, NULL }, + { "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 }, /* 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 @@ -295,6 +380,8 @@ static snmp_info_t eaton_marlin_mib[] = { /* Frequency is measured globally */ { "input.frequency", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.3.1.1.3.0.1", NULL, 0, NULL, NULL }, + { "input.frequency.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.1.1.4.0.1", NULL, SU_FLAG_OK, &marlin_threshold_frequency_status_info[0], NULL }, + { "ups.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.1.1.4.0.1", NULL, SU_FLAG_OK, &marlin_threshold_frequency_alarm_info[0], NULL }, /* inputCurrentPercentLoad (measured globally) * Current percent load, based on the rated current capacity */ @@ -305,23 +392,75 @@ static snmp_info_t eaton_marlin_mib[] = { { "input.L3.load", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.3.1.11.0.1.3", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, /* FIXME: - * - Voltage is only mesured per phase, as mV! + * - Voltage is only measured per phase, as mV! * so input.voltage == input.L1.voltage for both single and 3phase * - As per NUT namespace (http://www.networkupstools.org/docs/developer-guide.chunked/apas01.html#_valid_contexts) * Voltage has to be expressed either phase-phase or phase-neutral * This is depending on OID inputVoltageMeasType - * INTEGER {singlePhase (1),phase1toN (2),phase2toN (3),phase3toN (4),phase1to2 (5),phase2to3 (6),phase3to1 (7)*/ + * INTEGER {singlePhase (1),phase1toN (2),phase2toN (3),phase3toN (4),phase1to2 (5),phase2to3 (6),phase3to1 (7) + * => RFC input.Lx.voltage.context */ { "input.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.3.0.1.1", NULL, 0, NULL, NULL }, + { "input.voltage.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "ups.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_voltage_alarms_info[0], NULL }, + { "input.voltage.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.5.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.voltage.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.6.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.voltage.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.7.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.8.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, { "input.L1.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.3.0.1.1", NULL, 0, NULL, NULL }, + { "input.L1.voltage.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "L1.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_voltage_alarms_info[0], NULL }, + { "input.L1.voltage.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.5.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L1.voltage.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.6.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L1.voltage.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.7.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L1.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.8.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, { "input.L2.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.3.0.1.2", NULL, 0, NULL, NULL }, + { "input.L2.voltage.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.2", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "L2.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.2", NULL, SU_FLAG_OK, &marlin_threshold_voltage_alarms_info[0], NULL }, + { "input.L2.voltage.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.5.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L2.voltage.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.6.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L2.voltage.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.7.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L2.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.8.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, { "input.L3.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.3.0.1.3", NULL, 0, NULL, NULL }, - + { "input.L3.voltage.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.3", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "L3.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.2.1.4.0.1.3", NULL, SU_FLAG_OK, &marlin_threshold_voltage_alarms_info[0], NULL }, + { "input.L3.voltage.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.5.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L3.voltage.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.6.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L3.voltage.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.7.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L3.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.8.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, /* FIXME: * - input.current is mapped on input.L1.current for both single and 3phase !!! */ { "input.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.4.0.1.1", NULL, 0, NULL, NULL }, + { "input.current.nominal", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.3.0.1.1", NULL, 0, NULL, NULL }, + { "input.current.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "ups.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_current_alarms_info[0], NULL }, + { "input.current.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.6.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.current.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.7.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.current.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.8.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.current.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.9.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, { "input.L1.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.4.0.1.1", NULL, 0, NULL, NULL }, + { "input.L1.current.nominal", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.3.0.1.1", NULL, 0, NULL, NULL }, + { "input.L1.current.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "L1.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.1", NULL, SU_FLAG_OK, &marlin_threshold_current_alarms_info[0], NULL }, + { "input.L1.current.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.6.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L1.current.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.7.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L1.current.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.8.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L1.current.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.9.0.1.1", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, { "input.L2.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.4.0.1.2", NULL, 0, NULL, NULL }, + { "input.L2.current.nominal", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.3.0.1.2", NULL, 0, NULL, NULL }, + { "input.L2.current.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.2", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "L2.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.2", NULL, SU_FLAG_OK, &marlin_threshold_current_alarms_info[0], NULL }, + { "input.L2.current.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.6.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L2.current.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.7.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L2.current.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.8.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L2.current.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.9.0.1.2", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, { "input.L3.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.4.0.1.3", NULL, 0, NULL, NULL }, + { "input.L3.current.nominal", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.3.0.1.3", NULL, 0, NULL, NULL }, + { "input.L3.current.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.3", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "L3.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.3.3.1.5.0.1.3", NULL, SU_FLAG_OK, &marlin_threshold_current_alarms_info[0], NULL }, + { "input.L3.current.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.6.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L3.current.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.7.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L3.current.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.8.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, + { "input.L3.current.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.3.1.9.0.1.3", NULL, SU_FLAG_NEGINVALID, NULL, NULL }, /* Sum of all phases realpower, valid for Shark 1ph/3ph only */ { "input.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.5.1.4.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_UNIQUE | SU_FLAG_OK, NULL, NULL }, /* Fallback 1: Sum of all phases realpower, valid for Marlin 3ph only */ @@ -331,25 +470,43 @@ static snmp_info_t eaton_marlin_mib[] = { { "input.L1.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.4.0.1.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, { "input.L2.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.4.0.1.2", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, { "input.L3.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.4.0.1.3", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, - /* Sum of all phases apparent power, valid for 3phase only */ + /* Sum of all phases apparent power, valid for Shark 1ph/3ph only */ + { "input.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.5.1.3.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_UNIQUE | SU_FLAG_OK, NULL, NULL }, + /* Fallback 1: Sum of all phases realpower, valid for Marlin 3ph only */ { "input.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.4", NULL, SU_FLAG_NEGINVALID | SU_FLAG_UNIQUE | SU_FLAG_OK, NULL, NULL }, - /* Sum of the phase apparent power, valid for 1phase only (fallback for also publishing) */ - { "input.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + /* Fallback 2: Sum of the phase realpower, valid for Marlin 1ph only */ + { "input.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.2", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, { "input.L1.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, { "input.L2.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.2", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, { "input.L3.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.3", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, - /* Ambient page */ - /* We use critical levels, for both temperature and humidity, - * since warning levels are also available! */ + /* Ambient collection */ + { "ambient.present", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.1.1.3.0.1", NULL, SU_FLAG_OK, &marlin_ambient_presence_info[0], NULL }, + { "ambient.temperature.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.1.1.5.0.1", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "ups.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.1.1.5.0.1", NULL, SU_FLAG_OK, &marlin_threshold_temperature_alarms_info[0], NULL }, { "ambient.temperature", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.4.0.1", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.temperature.low", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, - { "ambient.temperature.high", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + /* Low and high threshold use the respective critical levels */ + { "ambient.temperature.low", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.low.critical", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.low.warning", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.6.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.high", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.high.warning", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.8.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.high.critical", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.2.1.5.0.1", NULL, SU_FLAG_OK, &marlin_threshold_status_info[0], NULL }, + { "ups.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.2.1.5.0.1", NULL, SU_FLAG_OK, &marlin_threshold_humidity_alarms_info[0], NULL }, { "ambient.humidity", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.4.0.1", NULL, SU_FLAG_OK, NULL, NULL }, - { "ambient.humidity.low", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, - { "ambient.humidity.high", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + /* Low and high threshold use the respective critical levels */ + { "ambient.humidity.low", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.low.warning", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.6.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.low.critical", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.high", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.high.warning", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.8.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.high.critical", ST_FLAG_RW, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + /* Dry contacts on TH module */ + { "ambient.contacts.1.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.3.1.4.0.1", NULL, SU_FLAG_OK, &marlin_ambient_drycontacts_info[0], NULL }, + { "ambient.contacts.2.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.7.3.1.4.0.2", NULL, SU_FLAG_OK, &marlin_ambient_drycontacts_info[0], NULL }, - /* Outlet page */ + /* Outlet collection */ { "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, { "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "All outlets", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, @@ -370,18 +527,87 @@ static snmp_info_t eaton_marlin_mib[] = { NULL, SU_FLAG_OK | SU_OUTLET, &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! */ { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET, 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.0.%i.1", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET, NULL, NULL }, + { "outlet.%i.groupid", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.2.1.3.0.%i.2", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET, NULL, NULL }, + { "outlet.%i.groupid", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.2.1.3.0.%i.3", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET, NULL, NULL }, + { "outlet.%i.groupid", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.2.1.3.0.%i.4", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET, NULL, NULL }, + { "outlet.%i.groupid", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.2.1.3.0.%i.5", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET, NULL, NULL }, + { "outlet.%i.groupid", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.2.1.3.0.%i.6", NULL, SU_FLAG_STATIC | SU_FLAG_UNIQUE | SU_OUTLET, NULL, NULL }, { "outlet.%i.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.4.1.3.0.%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.current.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.4.1.4.0.%i", NULL, SU_OUTLET, &marlin_threshold_status_info[0], NULL }, + { "outlet.%i.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.4.1.4.0.%i", NULL, SU_OUTLET, &marlin_threshold_current_alarms_info[0], NULL }, + { "outlet.%i.current.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.4.1.5.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, + { "outlet.%i.current.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.4.1.6.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, + { "outlet.%i.current.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.4.1.7.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, + { "outlet.%i.current.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.4.1.8.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, { "outlet.%i.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.6.5.1.3.0.%i", NULL, SU_OUTLET, NULL, NULL }, { "outlet.%i.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.2.0.%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.voltage.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.3.1.3.0.%i", NULL, SU_OUTLET, &marlin_threshold_status_info[0], NULL }, + { "outlet.%i.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.3.1.3.0.%i", NULL, SU_OUTLET, &marlin_threshold_voltage_alarms_info[0], NULL }, + { "outlet.%i.voltage.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.4.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, + { "outlet.%i.voltage.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.5.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, + { "outlet.%i.voltage.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.6.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, + { "outlet.%i.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.7.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET, NULL, NULL }, { "outlet.%i.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.6.5.1.2.0.%i", NULL, SU_OUTLET, 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.0.%i", "no", SU_FLAG_STATIC | SU_FLAG_OK, &outlet_switchability_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.0.%i", "no", SU_FLAG_STATIC | SU_OUTLET | SU_FLAG_OK, &outlet_switchability_info[0], NULL }, /* TODO: handle statistics * outletWh.0.1 * outletWhTimer.0.1 */ + /* Outlet groups collection */ + { "outlet.group.count", 0, 1, ".1.3.6.1.4.1.534.6.6.7.1.2.1.21.0", "0", SU_FLAG_STATIC, 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) */ + /* groupID.0.1 = OctetString: A */ + { "outlet.group.%i.id", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.1.1.2.0.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP, NULL, NULL }, + /* groupName.0.1 = OctetString: Factory Group 1 */ + /* FIXME: SU_FLAG_SEMI_STATIC or SU_FLAG_SETTING => refreshed from time to time or upon call to setvar */ + { "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.0.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP, 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.0.%i", NULL, SU_FLAG_STATIC | SU_OUTLET_GROUP, &marlin_outlet_group_type_info[0], NULL }, + /* 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.0.%i", + NULL, SU_FLAG_OK | SU_OUTLET_GROUP, &marlin_outletgroups_status_info[0], NULL }, + /* groupChildCount.0.1 = Integer: 12 */ + { "outlet.group.%i.count", 0, 1, ".1.3.6.1.4.1.534.6.6.7.5.1.1.6.0.%i", NULL, SU_OUTLET_GROUP, NULL, NULL }, + /* groupVoltage.0.1 = Integer: 243080 */ + { "outlet.group.%i.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.3.1.3.0.%i", NULL, SU_OUTLET_GROUP, NULL, NULL }, + /* groupVoltageThStatus.0.1 = Integer: good (0) */ + { "outlet.group.%i.voltage.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.3.1.4.0.%i", NULL, SU_OUTLET_GROUP, &marlin_threshold_status_info[0], NULL }, + { "outlet.group.%i.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.3.1.4.0.%i", NULL, SU_OUTLET_GROUP, &marlin_threshold_voltage_alarms_info[0], NULL }, + { "outlet.group.%i.voltage.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.3.1.5.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + { "outlet.group.%i.voltage.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.3.1.6.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + { "outlet.group.%i.voltage.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.3.1.7.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + { "outlet.group.%i.voltage.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.3.1.8.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrent.0.1 = Integer: 0 */ + { "outlet.group.%i.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.4.1.3.0.%i", NULL, SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrentCapacity.0.1 = Integer: 16000 */ + { "outlet.group.%i.current.nominal", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.4.1.2.0.%i", NULL, SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrentThStatus.0.1 = Integer: good (0) */ + { "outlet.group.%i.current.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.4.1.4.0.%i", NULL, SU_OUTLET_GROUP, &marlin_threshold_status_info[0], NULL }, + { "outlet.group.%i.alarm", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.5.4.1.4.0.%i", NULL, SU_OUTLET_GROUP, &marlin_threshold_current_alarms_info[0], NULL }, + /* groupCurrentPercentLoad.0.1 = Integer: 0 */ + { "outlet.group.%i.load", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.5.4.1.10.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrentThLowerWarning.0.1 = Integer: 0 */ + { "outlet.group.%i.current.low.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.4.1.5.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrentThLowerCritical.0.1 = Integer: -1 */ + { "outlet.group.%i.current.low.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.4.1.6.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrentThUpperWarning.0.1 = Integer: 12800 */ + { "outlet.group.%i.current.high.warning", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.4.1.7.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupCurrentThUpperCritical.0.1 = Integer: 16000 */ + { "outlet.group.%i.current.high.critical", ST_FLAG_RW, 0.001, ".1.3.6.1.4.1.534.6.6.7.5.4.1.8.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupWatts.0.1 = Integer: 2670 */ + { "outlet.group.%i.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.5.5.1.3.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + /* groupVA.0.1 = Integer: 3132 */ + { "outlet.group.%i.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.5.5.1.2.0.%i", NULL, SU_FLAG_NEGINVALID | SU_OUTLET_GROUP, NULL, NULL }, + + /* instant commands. */ /* Notes: * - load.cycle might be replaced by / mapped on shutdown.reboot @@ -399,6 +625,16 @@ static snmp_info_t eaton_marlin_mib[] = { { "outlet.%i.load.on", 0, 0, ".1.3.6.1.4.1.534.6.6.7.6.6.1.4.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, { "outlet.%i.load.cycle", 0, 0, ".1.3.6.1.4.1.534.6.6.7.6.6.1.5.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + /* TODO: handle delays + * 0-n :Time in seconds until the group command is issued + * -1:Cancel a pending group-level Off/On/Reboot command */ + /* groupControlOffCmd.0.1 = Integer: -1 */ + { "outlet.group.%i.load.off", 0, 0, ".1.3.6.1.4.1.534.6.6.7.5.6.1.3.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET_GROUP, NULL, NULL }, + /* groupControl0nCmd.0.1 = Integer: -1 */ + { "outlet.group.%i.load.on", 0, 0, ".1.3.6.1.4.1.534.6.6.7.5.6.1.4.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET_GROUP, NULL, NULL }, + /* groupControlRebootCmd.0.1 = Integer: -1 */ + { "outlet.group.%i.load.cycle", 0, 0, ".1.3.6.1.4.1.534.6.6.7.5.6.1.5.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET_GROUP, NULL, NULL }, + /* end of structure. */ { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } }; @@ -416,7 +652,7 @@ static snmp_info_t eaton_marlin_mib[] = { /* Pulizzi Switched ePDU */ -#define EATON_PULIZZI_SW_MIB_VERSION "0.1" +#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" @@ -448,6 +684,8 @@ static snmp_info_t eaton_pulizzi_switched_mib[] = { "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", @@ -459,8 +697,6 @@ static snmp_info_t eaton_pulizzi_switched_mib[] = { "", 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 }, - { "ups.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.2.6.0", - "unknown", 0, NULL, NULL }, /* Outlet page */ /* Note: outlet.count is deduced, with guestimate_outlet_count() */ @@ -484,9 +720,9 @@ static snmp_info_t eaton_pulizzi_switched_mib[] = { /* 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, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.1.%i.5.0", NULL, SU_OUTLET, NULL, NULL }, + { "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, SU_INFOSIZE, ".1.3.6.1.4.1.20677.2.6.1.%i.4.0", NULL, SU_OUTLET, NULL, NULL }, + { "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) */ @@ -505,10 +741,10 @@ static snmp_info_t eaton_pulizzi_switched_mib[] = { }; -mib2nut_info_t aphel_genesisII = { "aphel_genesisII", EATON_APHEL_MIB_VERSION, "", APHEL1_OID_MODEL_NAME, eaton_aphel_genesisII_mib, APHEL1_SYSOID }; -mib2nut_info_t aphel_revelation = { "aphel_revelation", EATON_APHEL_MIB_VERSION, "", APHEL2_OID_MODEL_NAME, eaton_aphel_revelation_mib, APHEL2_SYSOID }; -mib2nut_info_t eaton_marlin = { "eaton_epdu", EATON_MARLIN_MIB_VERSION, "", EATON_MARLIN_OID_MODEL_NAME, eaton_marlin_mib, EATON_MARLIN_SYSOID }; +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, "", PULIZZI1_OID_MODEL_NAME, eaton_pulizzi_monitored_mib, PULIZZI1_OID_MIB };*/ -mib2nut_info_t pulizzi_switched1 = { "pulizzi_switched1", EATON_PULIZZI_SW_MIB_VERSION, "", EATON_PULIZZI_SWITCHED1_SYSOID, eaton_pulizzi_switched_mib, EATON_PULIZZI_SWITCHED1_SYSOID }; -mib2nut_info_t pulizzi_switched2 = { "pulizzi_switched2", EATON_PULIZZI_SW_MIB_VERSION, "", EATON_PULIZZI_SWITCHED1_SYSOID, eaton_pulizzi_switched_mib, EATON_PULIZZI_SWITCHED2_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/hidparser.c b/drivers/hidparser.c index 1fb4a5e..41cae5c 100644 --- a/drivers/hidparser.c +++ b/drivers/hidparser.c @@ -27,11 +27,8 @@ #include "config.h" #include "hidparser.h" -#include "nut_stdint.h" /* for int8_t, int16_t, int32_t */ - -/* to be implemented for DEBUG purpose */ -/* previously: #define ERROR(x) if(x) __asm { int 3 }; */ -#define ERROR(x) +#include "nut_stdint.h" /* for int8_t, int16_t, int32_t */ +#include "common.h" /* for fatalx() */ static const uint8_t ItemSize[4] = { 0, 1, 2, 4 }; @@ -175,7 +172,7 @@ static int HIDParse(HIDParser_t *pParser, HIDData_t *pData) memcpy(&pParser->Value, &pParser->ReportDesc[pParser->Pos], ItemSize[pParser->Item & SIZE_MASK]); #endif /* Pos on next item */ - pParser->Pos += ItemSize[pParser->Item & SIZE_MASK]; + pParser->Pos += ItemSize[pParser->Item & SIZE_MASK]; } switch (pParser->Item & ITEM_MASK) @@ -249,7 +246,7 @@ static int HIDParse(HIDParser_t *pParser, HIDData_t *pData) if(pParser->Count == 0) { pParser->Count = pParser->ReportCount; } - + /* Get UPage/Usage from UsageTab and store them in pParser->Data.Path */ pParser->Data.Path.Node[pParser->Data.Path.Size] = pParser->UsageTab[0]; pParser->Data.Path.Size++; @@ -341,10 +338,14 @@ static int HIDParse(HIDParser_t *pParser, HIDData_t *pData) } } /* while ((Found < 0) && (pParser->Pos < pParser->ReportDescSize)) */ - ERROR(pParser->Data.Path.Size >= PATH_SIZE); - ERROR(pParser->ReportDescSize >= REPORT_DSC_SIZE); - ERROR(pParser->UsageSize >= USAGE_TAB_SIZE); - ERROR(pParser->Data.ReportID >= MAX_REPORT); + if(pParser->Data.Path.Size >= PATH_SIZE) + upslogx(LOG_ERR, "%s: HID path too long", __func__); + if(pParser->ReportDescSize >= REPORT_DSC_SIZE) + upslogx(LOG_ERR, "%s: Report descriptor too big", __func__); + if(pParser->UsageSize >= USAGE_TAB_SIZE) + upslogx(LOG_ERR, "%s: HID Usage too high", __func__); + if(pParser->Data.ReportID >= MAX_REPORT) + upslogx(LOG_ERR, "%s: Too many HID reports", __func__); return Found; } @@ -594,6 +595,11 @@ HIDDesc_t *Parse_ReportDesc(const unsigned char *ReportDesc, const int n) } } + /* Sanity check: are there remaining HID objects that can't + * be processed? */ + if ((pDesc->nitems == MAX_REPORT) && (parser->Pos < parser->ReportDescSize)) + upslogx(LOG_ERR, "ERROR in %s: Too many HID objects", __func__); + free(parser); if (pDesc->nitems == 0) { diff --git a/drivers/hidtypes.h b/drivers/hidtypes.h index f7e2581..ad8d03c 100644 --- a/drivers/hidtypes.h +++ b/drivers/hidtypes.h @@ -5,6 +5,7 @@ * * Copyright (C) * 1998-2003 MGE UPS SYSTEMS, Luc Descotils + * 2015 Eaton, Arnaud Quette (Update MAX_REPORT) * * 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 @@ -38,11 +39,11 @@ extern "C" { /* * Constants * -------------------------------------------------------------------------- */ -#define PATH_SIZE 10 /* Deep max for Path */ -#define USAGE_TAB_SIZE 50 /* Size of usage stack */ -#define MAX_REPORT 300 /* Including FEATURE, INPUT and OUTPUT */ -#define REPORT_DSC_SIZE 6144 /* Size max of Report Descriptor */ -#define MAX_REPORT_TS 3 /* Max time validity of a report */ +#define PATH_SIZE 10 /* Deep max for Path */ +#define USAGE_TAB_SIZE 50 /* Size of usage stack */ +#define MAX_REPORT 500 /* Including FEATURE, INPUT and OUTPUT */ +#define REPORT_DSC_SIZE 6144 /* Size max of Report Descriptor */ +#define MAX_REPORT_TS 3 /* Max time validity of a report */ /* * Items diff --git a/drivers/huawei-mib.c b/drivers/huawei-mib.c new file mode 100644 index 0000000..1d029b3 --- /dev/null +++ b/drivers/huawei-mib.c @@ -0,0 +1,234 @@ +/* huawei-mib.c - subdriver to monitor Huawei SNMP devices with NUT + * + * Copyright (C) + * 2011 - 2012 Arnaud Quette + * 2015 Stuart Henderson + * + * 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 "huawei-mib.h" + +#define HUAWEI_MIB_VERSION "0.1" + +#define HUAWEI_SYSOID ".1.3.6.1.4.1.8072.3.2.10" +#define HUAWEI_UPSMIB ".1.3.6.1.4.1.2011" + +/* To create a value lookup structure (as needed on the 2nd line of the example + * below), use the following kind of declaration, outside of the present snmp_info_t[]: + * static info_lkp_t onbatt_info[] = { + * { 1, "OB" }, + * { 2, "OL" }, + * { 0, NULL } + * }; + */ + +static info_lkp_t supplymethod_info[] = { + { 1, "" }, /* no supply */ + { 2, "OL BYPASS" }, + { 3, "OL" }, + { 4, "OB" }, + { 5, "" }, /* combined */ + { 6, "OL ECO" }, + { 7, "OB ECO" }, + { 0, NULL } +}; + +static info_lkp_t battstate_info[] = { + { 1, "" }, /* not connected */ + { 2, "" }, /* not charging or discharging */ + { 3, "" }, /* hibernation */ + { 4, "" }, /* float */ + { 5, "CHRG" }, /* equalized charging */ + { 6, "DISCHRG" }, + { 0, NULL } +}; + +static info_lkp_t phase_info[] = { + { 1, "1" }, + { 2, "3" }, + { 0, NULL } +}; + +static info_lkp_t voltrating_info[] = { + { 1, "200" }, + { 2, "208" }, + { 3, "220" }, + { 4, "380" }, + { 5, "400" }, + { 6, "415" }, + { 7, "480" }, + { 8, "600" }, + { 9, "690" }, + { 0, NULL } +}; + +static info_lkp_t freqrating_info[] = { + { 1, "50" }, + { 2, "60" }, + { 0, NULL } +}; + +static info_lkp_t pwrrating_info[] = { + { 1, "80000" }, + { 2, "100000" }, + { 3, "120000" }, + { 4, "160000" }, + { 5, "200000" }, + { 6, "30000" }, + { 7, "40000" }, + { 8, "60000" }, + { 9, "2400000" }, + { 10, "2500000" }, + { 11, "2800000" }, + { 12, "3000000" }, + { 0, NULL } +}; + +static info_lkp_t ietf_test_result_info[] = { + { 1, "done and passed" }, + { 2, "done and warning" }, + { 3, "done and error" }, + { 4, "aborted" }, + { 5, "in progress" }, + { 6, "no test initiated" }, + { 0, NULL } +}; + + +/* HUAWEI Snmp2NUT lookup table */ +static snmp_info_t huawei_mib[] = { + + /* Data format: + * { info_type, info_flags, info_len, OID, dfl, flags, oid2info, setvar }, + * + * info_type: NUT INFO_ or CMD_ element name + * info_flags: flags to set in addinfo + * info_len: length of strings if STR + * cmd value if CMD, multiplier otherwise + * OID: SNMP OID or NULL + * dfl: default value + * flags: snmp-ups internal flags (FIXME: ...) + * oid2info: lookup table between OID and NUT values + * setvar: variable to set for SU_FLAG_SETINT + * + * Example: + * { "input.voltage", 0, 0.1, ".1.3.6.1.4.1.705.1.6.2.1.2.1", "", SU_INPUT_1, NULL }, + * { "ups.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.705.1.7.3.0", "", SU_FLAG_OK | SU_STATUS_BATT, onbatt_info }, + * + * To create a value lookup structure (as needed on the 2nd line), use the + * following kind of declaration, outside of the present snmp_info_t[]: + * static info_lkp_t onbatt_info[] = { + * { 1, "OB" }, + * { 2, "OL" }, + * { 0, NULL } + * }; + */ + + /* UPS page */ + + { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "Huawei", SU_FLAG_ABSENT | SU_FLAG_OK, NULL }, + { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.2.100.1.2.1", "Generic SNMP UPS", SU_FLAG_STATIC | SU_FLAG_OK, NULL }, + { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.1.1.2.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL }, + + { "ups.time", 0, 1, ".1.3.6.1.4.1.2011.6.174.1.11.1.0", NULL, SU_FLAG_OK, NULL }, /* seconds since epoch */ + + { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.2.100.1.3.1", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL }, + { "ups.serial", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.2.100.1.5.1", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL }, + + { "ups.status", 0, 1, ".1.3.6.1.4.1.2011.6.174.1.2.101.1.1.1", NULL, SU_FLAG_OK, supplymethod_info }, + { "ups.status", 0, 1, ".1.3.6.1.4.1.2011.6.174.1.2.101.1.3.1", NULL, SU_STATUS_BATT | SU_FLAG_OK, battstate_info }, + + { "ups.test.result", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.33.1.7.3.0", "", 0, ietf_test_result_info }, + + + /* Input page */ + + /* hwUpsCtrlInputStandard listed in MIB but not present on tested UPS5000-E */ + { "input.phases", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.102.100.1.8", "3", SU_FLAG_ABSENT | SU_FLAG_OK, phase_info }, + + { "input.L1-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.1.1", NULL, SU_FLAG_OK, NULL }, + { "input.L2-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.2.1", NULL, SU_FLAG_OK, NULL }, + { "input.L3-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.3.1", NULL, SU_FLAG_OK, NULL }, + + { "input.frequency", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.4.1", NULL, SU_FLAG_OK, NULL }, + + { "input.L1.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.5.1", NULL, SU_FLAG_OK, NULL }, + { "input.L2.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.6.1", NULL, SU_FLAG_OK, NULL }, + { "input.L3.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.7.1", NULL, SU_FLAG_OK, NULL }, + + { "input.L1.powerfactor", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.8.1", NULL, SU_FLAG_OK, NULL }, + { "input.L2.powerfactor", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.9.1", NULL, SU_FLAG_OK, NULL }, + { "input.L3.powerfactor", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.3.100.1.10.1", NULL, SU_FLAG_OK, NULL }, + + { "input.bypass.L1-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.5.100.1.1.1", NULL, SU_FLAG_OK, NULL }, + { "input.bypass.L2-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.5.100.1.2.1", NULL, SU_FLAG_OK, NULL }, + { "input.bypass.L3-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.5.100.1.3.1", NULL, SU_FLAG_OK, NULL }, + + { "input.bypass.frequency", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.5.100.1.4.1", NULL, SU_FLAG_OK, NULL }, + + + /* Output page */ + + /* hwUpsCtrlOutputStandard listed in MIB but not present on tested UPS5000-E */ + { "output.phases", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.102.100.1.9", "3", SU_FLAG_ABSENT | SU_FLAG_OK, phase_info }, + + { "output.L1-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.1.1", NULL, SU_FLAG_OK, NULL }, + { "output.L2-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.2.1", NULL, SU_FLAG_OK, NULL }, + { "output.L3-N.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.3.1", NULL, SU_FLAG_OK, NULL }, + + { "output.L1.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.4.1", NULL, SU_FLAG_OK, NULL }, + { "output.L2.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.5.1", NULL, SU_FLAG_OK, NULL }, + { "output.L3.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.6.1", NULL, SU_FLAG_OK, NULL }, + + { "output.frequency", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.7.1", NULL, SU_FLAG_OK, NULL }, + + { "output.L1.realpower", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.8.1", NULL, SU_FLAG_OK, NULL }, + { "output.L1.realpower", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.9.1", NULL, SU_FLAG_OK, NULL }, + { "output.L1.realpower", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.10.1", NULL, SU_FLAG_OK, NULL }, + + { "output.L1.power", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.11.1", NULL, SU_FLAG_OK, NULL }, + { "output.L2.power", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.12.1", NULL, SU_FLAG_OK, NULL }, + { "output.L3.power", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.13.1", NULL, SU_FLAG_OK, NULL }, + + { "output.L1.power.percent", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.14.1", NULL, SU_FLAG_OK, NULL }, + { "output.L2.power.percent", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.15.1", NULL, SU_FLAG_OK, NULL }, + { "output.L3.power.percent", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.16.1", NULL, SU_FLAG_OK, NULL }, + + { "output.voltage.nominal", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.17.1", NULL, SU_FLAG_STATIC | SU_FLAG_OK, voltrating_info }, + { "output.frequency.nominal", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.18.1", NULL, SU_FLAG_STATIC | SU_FLAG_OK, freqrating_info }, + { "output.power.nominal", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.2011.6.174.1.2.100.1.6.1", NULL, SU_FLAG_STATIC | SU_FLAG_OK, pwrrating_info }, + + { "output.L1.powerfactor", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.19.1", NULL, SU_FLAG_OK, NULL }, + { "output.L2.powerfactor", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.20.1", NULL, SU_FLAG_OK, NULL }, + { "output.L2.powerfactor", 0, 0.01, ".1.3.6.1.4.1.2011.6.174.1.4.100.1.21.1", NULL, SU_FLAG_OK, NULL }, + + + /* Battery page */ + + { "battery.voltage", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.6.100.1.1.1", NULL, SU_FLAG_OK, NULL }, + { "battery.current", 0, 0.1, ".1.3.6.1.4.1.2011.6.174.1.6.100.1.2.1", NULL, SU_FLAG_OK, NULL }, + { "battery.charge", 0, 1, ".1.3.6.1.4.1.2011.6.174.1.6.100.1.3.1", NULL, SU_FLAG_OK, NULL }, + { "battery.runtime", 0, 1, ".1.3.6.1.4.1.2011.6.174.1.6.100.1.4.1", NULL, SU_FLAG_OK, NULL }, + + + /* { "unmapped.hwUpsBattTest", 0, 1, ".1.3.6.1.4.1.2011.6.174.1.103.101.1.6.1", NULL, SU_FLAG_OK, NULL }, */ + + + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL } +}; + +mib2nut_info_t huawei = { "huawei", HUAWEI_MIB_VERSION, NULL, NULL, huawei_mib, HUAWEI_SYSOID }; diff --git a/drivers/huawei-mib.h b/drivers/huawei-mib.h new file mode 100644 index 0000000..326a71e --- /dev/null +++ b/drivers/huawei-mib.h @@ -0,0 +1,9 @@ +#ifndef HUAWEI_MIB_H +#define HUAWEI_MIB_H + +#include "main.h" +#include "snmp-ups.h" + +extern mib2nut_info_t huawei; + +#endif /* HUAWEI_MIB_H */ diff --git a/drivers/ietf-mib.c b/drivers/ietf-mib.c index f5d1f62..5ccb00d 100644 --- a/drivers/ietf-mib.c +++ b/drivers/ietf-mib.c @@ -26,11 +26,12 @@ #include "ietf-mib.h" -#define IETF_MIB_VERSION "1.4" +#define IETF_MIB_VERSION "1.5" /* SNMP OIDs set */ #define IETF_OID_UPS_MIB "1.3.6.1.2.1.33.1." #define IETF_SYSOID ".1.3.6.1.2.1.33" +#define TRIPPLITE_SYSOID ".1.3.6.1.4.1.850.1" /* #define DEBUG */ @@ -39,7 +40,7 @@ static info_lkp_t ietf_battery_info[] = { { 2, "" /* batteryNormal */}, { 3, "LB" /* batteryLow */ }, { 4, "LB" /* batteryDepleted */ }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_power_source_info[] = { @@ -50,12 +51,12 @@ static info_lkp_t ietf_power_source_info[] = { { 5, "OB" /* battery */ }, { 6, "OL BOOST" /* booster */ }, { 7, "OL TRIM" /* reducer */ }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_overload_info[] = { { 1, "OVER" }, /* output overload */ - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_test_active_info[] = { @@ -64,7 +65,7 @@ static info_lkp_t ietf_test_active_info[] = { { 3, "TEST" }, /* upsTestGeneralSystemsTest */ { 4, "TEST" }, /* upsTestQuickBatteryTest */ { 5, "CAL" }, /* upsTestDeepBatteryCalibration */ - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_test_result_info[] = { @@ -74,28 +75,28 @@ static info_lkp_t ietf_test_result_info[] = { { 4, "aborted" }, { 5, "in progress" }, { 6, "no test initiated" }, - { 0, "NULL" } + { 0, NULL } }; #ifdef DEBUG static info_lkp_t ietf_shutdown_type_info[] = { { 1, "output" }, { 2, "system" }, - { 0, "NULL" } + { 0, NULL } }; #endif static info_lkp_t ietf_yes_no_info[] = { { 1, "yes" }, { 2, "no" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_beeper_status_info[] = { { 1, "disabled" }, { 2, "enabled" }, { 3, "muted" }, - { 0, "NULL" } + { 0, NULL } }; /* Snmp2NUT lookup table info_type, info_flags, info_len, OID, dfl, flags, oid2info, setvar */ @@ -275,3 +276,4 @@ static snmp_info_t ietf_mib[] = { }; mib2nut_info_t ietf = { "ietf", IETF_MIB_VERSION, IETF_OID_UPS_MIB "4.1.0", IETF_OID_UPS_MIB "1.1.0", ietf_mib, IETF_SYSOID }; +mib2nut_info_t tripplite_ietf = { "ietf", IETF_MIB_VERSION, NULL, NULL, ietf_mib, TRIPPLITE_SYSOID }; diff --git a/drivers/ietf-mib.h b/drivers/ietf-mib.h index d1c32ac..b9ddedc 100644 --- a/drivers/ietf-mib.h +++ b/drivers/ietf-mib.h @@ -5,5 +5,6 @@ #include "snmp-ups.h" extern mib2nut_info_t ietf; +extern mib2nut_info_t tripplite_ietf; #endif /* IETF_MIB_H */ diff --git a/drivers/libhid.c b/drivers/libhid.c index 25d4d00..75d2db6 100644 --- a/drivers/libhid.c +++ b/drivers/libhid.c @@ -287,6 +287,8 @@ void HIDDumpTree(hid_dev_handle_t udev, usage_tables_t *utab) return; } + upsdebugx(1, "%i HID objects found", pDesc->nitems); + for (i = 0; i < pDesc->nitems; i++) { double value; @@ -407,7 +409,7 @@ char *HIDGetIndexString(hid_dev_handle_t udev, const int Index, char *buf, size_ if (comm_driver->get_string(udev, Index, buf, buflen) < 1) buf[0] = '\0'; - return rtrim(buf, '\n'); + return str_rtrim(buf, '\n'); } /* Return pointer to indexed string from HID path (empty if not found) @@ -429,7 +431,7 @@ char *HIDGetItemString(hid_dev_handle_t udev, const char *hidpath, char *buf, si */ int HIDSetDataValue(hid_dev_handle_t udev, HIDData_t *hiddata, double Value) { - int i, r; + int r; long hValue; if (hiddata == NULL) { @@ -456,9 +458,7 @@ int HIDSetDataValue(hid_dev_handle_t udev, HIDData_t *hiddata, double Value) } /* flush the report buffer (data may have changed) */ - for (i=0; i<256; i++) { - reportbuf->ts[i] = 0; - } + memset(reportbuf->ts, 0, sizeof(reportbuf->ts)); upsdebugx(4, "Set report succeeded"); return 1; diff --git a/drivers/libshut.c b/drivers/libshut.c index 1e2cd8d..ac132e2 100644 --- a/drivers/libshut.c +++ b/drivers/libshut.c @@ -41,7 +41,7 @@ #include "common.h" /* for xmalloc, upsdebugx prototypes */ #define SHUT_DRIVER_NAME "SHUT communication driver" -#define SHUT_DRIVER_VERSION "0.84" +#define SHUT_DRIVER_VERSION "0.85" /* communication driver description structure */ upsdrv_info_t comm_upsdrv_info = { @@ -300,6 +300,10 @@ int libshut_open(int *upsfd, SHUTDevice_t *curDevice, char *device_path, /* report descriptor */ unsigned char rdbuf[MAX_REPORT_SIZE]; int rdlen; + /* All devices use HID descriptor at index 0. However, some newer + * Eaton units have a light HID descriptor at index 0, and the full + * version is at index 1 (in which case, bcdDevice == 0x0202) */ + int hid_desc_index = 0; upsdebugx(2, "libshut_open: using port %s", device_path); @@ -361,6 +365,7 @@ int libshut_open(int *upsfd, SHUTDevice_t *curDevice, char *device_path, curDevice->VendorID = dev_descriptor->idVendor; curDevice->ProductID = dev_descriptor->idProduct; curDevice->Bus = strdup("serial"); + curDevice->bcdDevice = dev_descriptor->bcdDevice; curDevice->Vendor = strdup("Eaton"); if (dev_descriptor->iManufacturer) { ret = shut_get_string_simple(*upsfd, dev_descriptor->iManufacturer, @@ -400,11 +405,17 @@ int libshut_open(int *upsfd, SHUTDevice_t *curDevice, char *device_path, upsdebugx(2, "- Product: %s", curDevice->Product); upsdebugx(2, "- Serial Number: %s", curDevice->Serial); upsdebugx(2, "- Bus: %s", curDevice->Bus); + upsdebugx(2, "- Device release number: %04x", curDevice->bcdDevice); upsdebugx(2, "Device matches"); + if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) { + upsdebugx(1, "Eaton device v2.02. Using full report descriptor"); + hid_desc_index = 1; + } + /* Get HID descriptor */ desc = (struct my_hid_descriptor *)buf; - res = shut_get_descriptor(*upsfd, USB_DT_HID, 0, buf, 0x9); + res = shut_get_descriptor(*upsfd, USB_DT_HID, hid_desc_index, buf, 0x9); /* res = shut_control_msg(devp, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR, (USB_DT_HID << 8) + 0, 0, buf, 0x9, SHUT_TIMEOUT); */ @@ -437,7 +448,7 @@ int libshut_open(int *upsfd, SHUTDevice_t *curDevice, char *device_path, } /* Get REPORT descriptor */ - res = shut_get_descriptor(*upsfd, USB_DT_REPORT, 0, rdbuf, rdlen); + res = shut_get_descriptor(*upsfd, USB_DT_REPORT, hid_desc_index, rdbuf, rdlen); /* res = shut_control_msg(devp, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR, (USB_DT_REPORT << 8) + 0, 0, ReportDesc, desc->wDescriptorLength, SHUT_TIMEOUT); */ diff --git a/drivers/libshut.h b/drivers/libshut.h index 48f48bb..077eeda 100644 --- a/drivers/libshut.h +++ b/drivers/libshut.h @@ -42,12 +42,13 @@ extern upsdrv_info_t comm_upsdrv_info; * corresponding string did not exist or could not be retrieved. */ typedef struct SHUTDevice_s { - uint16_t VendorID; /*!< Device's Vendor ID */ - uint16_t ProductID; /*!< Device's Product ID */ - char* Vendor; /*!< Device's Vendor Name */ - char* Product; /*!< Device's Product Name */ - char* Serial; /* Product serial number */ - char* Bus; /* Bus name, e.g. "003" */ + uint16_t VendorID; /*!< Device's Vendor ID */ + uint16_t ProductID; /*!< Device's Product ID */ + char* Vendor; /*!< Device's Vendor Name */ + char* Product; /*!< Device's Product Name */ + char* Serial; /*!< Product serial number */ + char* Bus; /*!< Bus name, e.g. "003" */ + uint16_t bcdDevice; /*!< Device release number */ } SHUTDevice_t; /*! diff --git a/drivers/libusb.c b/drivers/libusb.c index 8625ed6..1d4688c 100644 --- a/drivers/libusb.c +++ b/drivers/libusb.c @@ -34,7 +34,7 @@ #include "libusb.h" #define USB_DRIVER_NAME "USB communication driver" -#define USB_DRIVER_VERSION "0.32" +#define USB_DRIVER_VERSION "0.33" /* driver description structure */ upsdrv_info_t comm_upsdrv_info = { @@ -154,6 +154,10 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice unsigned char *p; char string[256]; int i; + /* All devices use HID descriptor at index 0. However, some newer + * Eaton units have a light HID descriptor at index 0, and the full + * version is at index 1 (in which case, bcdDevice == 0x0202) */ + int hid_desc_index = 0; /* report descriptor */ unsigned char rdbuf[MAX_REPORT_SIZE]; @@ -199,6 +203,7 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice curDevice->VendorID = dev->descriptor.idVendor; curDevice->ProductID = dev->descriptor.idProduct; curDevice->Bus = strdup(bus->dirname); + curDevice->bcdDevice = dev->descriptor.bcdDevice; if (dev->descriptor.iManufacturer) { ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer, @@ -230,6 +235,11 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice upsdebugx(2, "- Product: %s", curDevice->Product ? curDevice->Product : "unknown"); upsdebugx(2, "- Serial Number: %s", curDevice->Serial ? curDevice->Serial : "unknown"); upsdebugx(2, "- Bus: %s", curDevice->Bus ? curDevice->Bus : "unknown"); + upsdebugx(2, "- Device release number: %04x", curDevice->bcdDevice); + + if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) { + hid_desc_index = 1; + } upsdebugx(2, "Trying to match device"); for (m = matcher; m; m=m->next) { @@ -293,9 +303,9 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice /* Get HID descriptor */ /* FIRST METHOD: ask for HID descriptor directly. */ - /* res = usb_get_descriptor(udev, USB_DT_HID, 0, buf, 0x9); */ + /* res = usb_get_descriptor(udev, USB_DT_HID, hid_desc_index, buf, 0x9); */ res = usb_control_msg(udev, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR, - (USB_DT_HID << 8) + 0, 0, buf, 0x9, USB_TIMEOUT); + (USB_DT_HID << 8) + hid_desc_index, 0, buf, 0x9, USB_TIMEOUT); if (res < 0) { upsdebugx(2, "Unable to get HID descriptor (%s)", usb_strerror()); @@ -311,6 +321,7 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice if (rdlen1 < -1) { upsdebugx(2, "Warning: HID descriptor, method 1 failed"); } + upsdebugx(3, "HID descriptor length (method 1) %d", rdlen1); /* SECOND METHOD: find HID descriptor among "extra" bytes of interface descriptor, i.e., bytes tucked onto the end of @@ -336,12 +347,19 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice if (rdlen2 < -1) { upsdebugx(2, "Warning: HID descriptor, method 2 failed"); } + upsdebugx(3, "HID descriptor length (method 2) %d", rdlen2); /* when available, always choose the second value, as it seems to be more reliable (it is the one reported e.g. by lsusb). Note: if the need arises, can change this to use the maximum of the two values instead. */ - rdlen = rdlen2 >= 0 ? rdlen2 : rdlen1; + if ((curDevice->VendorID == 0x463) && (curDevice->bcdDevice == 0x0202)) { + upsdebugx(1, "Eaton device v2.02. Using full report descriptor"); + rdlen = rdlen1; + } + else { + rdlen = rdlen2 >= 0 ? rdlen2 : rdlen1; + } if (rdlen < 0) { upsdebugx(2, "Unable to retrieve any HID descriptor"); @@ -358,9 +376,9 @@ static int libusb_open(usb_dev_handle **udevp, USBDevice_t *curDevice, USBDevice goto next_device; } - /* res = usb_get_descriptor(udev, USB_DT_REPORT, 0, bigbuf, rdlen); */ + /* res = usb_get_descriptor(udev, USB_DT_REPORT, hid_desc_index, bigbuf, rdlen); */ res = usb_control_msg(udev, USB_ENDPOINT_IN+1, USB_REQ_GET_DESCRIPTOR, - (USB_DT_REPORT << 8) + 0, 0, rdbuf, rdlen, USB_TIMEOUT); + (USB_DT_REPORT << 8) + hid_desc_index, 0, rdbuf, rdlen, USB_TIMEOUT); if (res < 0) { diff --git a/drivers/macosx-ups.c b/drivers/macosx-ups.c index 11ed475..4873855 100644 --- a/drivers/macosx-ups.c +++ b/drivers/macosx-ups.c @@ -1,6 +1,6 @@ /* Bridge driver to read Mac OS X UPS status (as displayed in Energy Saver control panel) * - * Copyright (C) 2011-2012 Charles Lepple + * Copyright (C) 2011-2012, 2015 Charles Lepple * * 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 @@ -27,7 +27,7 @@ #include "IOKit/ps/IOPSKeys.h" #define DRIVER_NAME "Mac OS X UPS meta-driver" -#define DRIVER_VERSION "1.0" +#define DRIVER_VERSION "1.2" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -42,39 +42,63 @@ upsdrv_info_t upsdrv_info = { #define CFRelease(ref) do { upsdebugx(3, "%s:%d: CFRelease(%p)", __FILE__, __LINE__, ref); CFRelease(ref); } while(0) #endif -static CFStringRef g_power_key = NULL; +static CFStringRef g_power_source_name = NULL; static double max_capacity_value = 100.0; /*! Copy the current power dictionary. * * Caller must release power dictionary when finished with it. */ -static CFDictionaryRef copy_power_dictionary(CFTypeRef power_key) +static CFDictionaryRef copy_power_dictionary(CFStringRef power_source_name) { - CFTypeRef power_blob; - CFDictionaryRef power_dictionary; + CFTypeRef power_sources_info, power_source; + CFArrayRef sources_list; + CFDictionaryRef this_power_dictionary, power_dictionary = NULL; + CFStringRef this_power_source_name; + CFIndex num_keys, index; - power_blob = IOPSCopyPowerSourcesInfo(); + power_sources_info = IOPSCopyPowerSourcesInfo(); - assert(power_blob); - upsdebugx(6, "%s: Got power_blob:", __func__); - if(nut_debug_level >= 6) CFShow(power_blob); + assert(power_sources_info); + upsdebugx(6, "%s: Got power_sources_info:", __func__); + if(nut_debug_level >= 6) CFShow(power_sources_info); - upsdebugx(5, "power_key = "); - if(nut_debug_level >= 5) CFShow(power_key); - upsdebugx(6, "end power_key"); + upsdebugx(5, "power_source_name = "); + if(nut_debug_level >= 5) CFShow(power_source_name); + upsdebugx(6, "end power_source_name"); - power_dictionary = IOPSGetPowerSourceDescription(power_blob, power_key); + sources_list = IOPSCopyPowerSourcesList(power_sources_info); - upsdebugx(5, "Asserting 'power_dictionary': %p", power_dictionary); - assert(power_dictionary); - upsdebugx(5, "CFShowing 'power_dictionary'"); - if(nut_debug_level >= 5) CFShow(power_dictionary); + num_keys = CFArrayGetCount(sources_list); + for(index=0; index < num_keys; index++) { + upsdebugx(6, "%s: Getting power source %ld/%ld...", __func__, index+1, num_keys); + power_source = CFArrayGetValueAtIndex(sources_list, index); + assert(power_source); - CFRetain(power_dictionary); + upsdebugx(6, "%s: power source %ld = ", __func__, index+1); + if(nut_debug_level >= 6) CFShow(power_source); - /* Get a new power_blob next time: */ - CFRelease(power_blob); + this_power_dictionary = IOPSGetPowerSourceDescription(power_sources_info, power_source); + assert(this_power_dictionary); + + this_power_source_name = CFDictionaryGetValue(this_power_dictionary, CFSTR(kIOPSNameKey)); + assert(this_power_source_name); + + if(!CFStringCompare(this_power_source_name, power_source_name, 0)) { + power_dictionary = this_power_dictionary; + CFRetain(power_dictionary); + break; + } + } + + if(power_dictionary) { + upsdebugx(5, "CFShowing 'power_dictionary'"); + if(nut_debug_level >= 5) CFShow(power_dictionary); + } + + /* Get a new power_sources_info next time: */ + CFRelease(power_sources_info); + CFRelease(sources_list); return power_dictionary; } @@ -92,7 +116,7 @@ void upsdrv_initinfo(void) dstate_setinfo("device.mfr", "(unknown)"); - power_dictionary = copy_power_dictionary(g_power_key); + power_dictionary = copy_power_dictionary(g_power_source_name); device_type_cfstr = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSTypeKey)); if(device_type_cfstr && !CFStringCompare(device_type_cfstr, CFSTR(kIOPSInternalBatteryType), 0)) { @@ -144,8 +168,11 @@ void upsdrv_updateinfo(void) upsdebugx(1, "upsdrv_updateinfo()"); - power_dictionary = copy_power_dictionary( g_power_key ); - assert(power_dictionary); /* TODO: call dstate_datastale()? */ + power_dictionary = copy_power_dictionary( g_power_source_name ); + if(!power_dictionary) { + dstate_datastale(); + return; + } status_init(); @@ -314,9 +341,9 @@ void upsdrv_initups(void) CFDictionaryRef power_dictionary; CFTypeRef power_blob; CFStringRef potential_key, potential_model; - char *device_name = device_path, *model_name; /* regex(3) */ - char potential_device_name[80], potential_model_name[80]; - regex_t name_regex, model_regex; + char *model_name; /* regex(3) */ + char potential_model_name[256]; + regex_t model_regex; int ret; upsdebugx(3, "upsdrv_initups(): Power Sources blob:"); @@ -329,6 +356,8 @@ void upsdrv_initups(void) if(nut_debug_level >= 3) CFShow(power_blob); +/* The CFDictionary through 10.9 has changed to a CFArray, so this part is no longer applicable: */ +#if 0 if(!strcmp(device_name, "auto")) { device_name = "/UPS"; } @@ -342,6 +371,7 @@ void upsdrv_initups(void) "Failed to compile regex from 'port' parameter: '%s'.", device_name); } +#endif if((model_name = getval("model"))) { upsdebugx(2, "Matching power supply model names against regex '%s'", model_name); @@ -363,61 +393,55 @@ void upsdrv_initups(void) if(num_keys < 1) { /* bail */ - fatalx(EXIT_FAILURE, "Couldn't find any UPS or battery"); + fatalx(EXIT_FAILURE, "Couldn't find any UPS or battery. Is your UPS shown in the 'Energy Saver' control panel?"); } for(index=0; index < num_keys; index++) { + upsdebugx(2, "Retrieving power source #%ld", index+1); potential_key = CFArrayGetValueAtIndex(power_source_key_list, index); - CFStringGetCString(potential_key, potential_device_name, - sizeof(potential_device_name), kCFStringEncodingUTF8); - upsdebugx(1, " Power supply: %s", potential_device_name); + upsdebugx(3, "Power source key/index:"); + if(nut_debug_level >= 3) CFShow(potential_key); - ret = regexec(&name_regex, potential_device_name, 0,0,0); - - power_dictionary = copy_power_dictionary(potential_key); + power_dictionary = IOPSGetPowerSourceDescription(power_blob, potential_key); + assert(power_dictionary); + CFRetain(power_dictionary); upsdebugx(2, "Getting 'Name' key (UPS model)"); potential_model = CFDictionaryGetValue(power_dictionary, CFSTR(kIOPSNameKey)); - CFStringGetCString(potential_model, potential_model_name, sizeof(potential_model_name), kCFStringEncodingUTF8); - upsdebugx(1, " model name: %s", potential_model_name); + CFRetain(potential_model); + if(CFStringGetCString(potential_model, potential_model_name, sizeof(potential_model_name), kCFStringEncodingUTF8)) { + upsdebugx(1, " model name: %s", potential_model_name); + } else { + upsdebugx(1, " (failed to retrieve 'Name')"); + } CFRelease(power_dictionary); - /* Does key match? Check model: */ - if (!ret) { - if(model_name) { - ret = regexec(&model_regex, potential_model_name, 0,0,0); - if(!ret) { - upsdebugx(2, "Matched model name"); - break; - } - } else { - upsdebugx(2, "Matched key name"); + if(model_name) { + ret = regexec(&model_regex, potential_model_name, 0,0,0); + if(!ret) { + upsdebugx(2, "Matched model name"); break; } } + CFRelease(potential_model); } - regfree(&name_regex); if(model_name) { regfree(&model_regex); } if(ret) { - fatalx(EXIT_FAILURE, "Couldn't find UPS or battery matching both 'port' (%s) and 'model' (%s)", - device_name, model_name); + if(model_name) { + fatalx(EXIT_FAILURE, "Couldn't find UPS or battery matching 'model' (%s)", + model_name); + } else { + fatalx(EXIT_FAILURE, "Couldn't find an UPS or battery."); + } } - g_power_key = potential_key; - CFRetain(g_power_key); - upsdebugx(2, "g_power_key = "); - if(nut_debug_level >= 2) CFShow(g_power_key); - upsdebugx(2, "end g_power_key."); - - power_dictionary = copy_power_dictionary(g_power_key); - assert(power_dictionary); - if(nut_debug_level >= 3) CFShow(power_dictionary); + g_power_source_name = potential_model; /* the upsh handlers can't be done here, as they get initialized * shortly after upsdrv_initups returns to main. @@ -426,14 +450,12 @@ void upsdrv_initups(void) /* don't try to detect the UPS here */ /* do stuff */ - - CFRelease(power_dictionary); } void upsdrv_cleanup(void) { upsdebugx(1, "Cleanup: release references"); - CFRelease(g_power_key); + CFRelease(g_power_source_name); /* free(dynamic_mem); */ /* ser_close(upsfd, device_path); */ diff --git a/drivers/mge-hid.c b/drivers/mge-hid.c index dfc62c9..a3f10af 100644 --- a/drivers/mge-hid.c +++ b/drivers/mge-hid.c @@ -37,7 +37,7 @@ #include "usbhid-ups.h" #include "mge-hid.h" -#define MGE_HID_VERSION "MGE HID 1.38" +#define MGE_HID_VERSION "MGE HID 1.39" /* (prev. MGE Office Protection Systems, prev. MGE UPS SYSTEMS) */ /* Eaton */ @@ -52,6 +52,9 @@ /* Hewlett Packard */ #define HP_VENDORID 0x03f0 +/* AEG */ +#define AEG_VENDORID 0x2b2d + #ifndef SHUT_MODE #include "usb-common.h" @@ -75,6 +78,9 @@ static usb_device_id_t mge_usb_device_table[] = { { USB_DEVICE(HP_VENDORID, 0x1fe7), NULL }, { USB_DEVICE(HP_VENDORID, 0x1fe8), NULL }, + /* PROTECT B / NAS */ + { USB_DEVICE(AEG_VENDORID, 0xffff), NULL }, + /* Terminating entry */ { -1, -1, NULL } }; diff --git a/drivers/mge-mib.c b/drivers/mge-mib.c index e19816b..8dd2eeb 100644 --- a/drivers/mge-mib.c +++ b/drivers/mge-mib.c @@ -40,50 +40,50 @@ static info_lkp_t mge_lowbatt_info[] = { { 1, "LB" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_onbatt_info[] = { { 1, "OB" }, { 2, "OL" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_bypass_info[] = { { 1, "BYPASS" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_boost_info[] = { { 1, "BOOST" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_trim_info[] = { { 1, "TRIM" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_overload_info[] = { { 1, "OVER" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_replacebatt_info[] = { { 1, "RB" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_output_util_off_info[] = { { 1, "OFF" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t mge_transfer_reason_info[] = { @@ -91,7 +91,7 @@ static info_lkp_t mge_transfer_reason_info[] = { { 2, "input voltage out of range" }, { 3, "input frequency out of range" }, { 4, "utility off" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_test_result_info[] = { @@ -101,20 +101,20 @@ static info_lkp_t ietf_test_result_info[] = { { 4, "aborted" }, { 5, "in progress" }, { 6, "no test initiated" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_beeper_status_info[] = { { 1, "disabled" }, { 2, "enabled" }, { 3, "muted" }, - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t ietf_yes_no_info[] = { { 1, "yes" }, { 2, "no" }, - { 0, "NULL" } + { 0, NULL } }; /* FIXME: the below may introduce status redundancy, that needs to be @@ -129,7 +129,7 @@ static info_lkp_t ietf_power_source_info[] = { { 5, "OB" /* battery */ }, { 6, "BOOST" /* booster */ }, { 7, "TRIM" /* reducer */ }, - { 0, "NULL" } + { 0, NULL } }; /* Parameters default values */ @@ -271,4 +271,4 @@ static snmp_info_t mge_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } }; -mib2nut_info_t mge = { "mge", MGE_MIB_VERSION, "", MGE_OID_MODEL_NAME, mge_mib, MGE_SYSOID }; +mib2nut_info_t mge = { "mge", MGE_MIB_VERSION, NULL, MGE_OID_MODEL_NAME, mge_mib, MGE_SYSOID }; diff --git a/drivers/mge-xml.c b/drivers/mge-xml.c index 560d432..8ca4dd3 100644 --- a/drivers/mge-xml.c +++ b/drivers/mge-xml.c @@ -31,7 +31,7 @@ #include "netxml-ups.h" #include "mge-xml.h" -#define MGE_XML_VERSION "MGEXML/0.23" +#define MGE_XML_VERSION "MGEXML/0.25" #define MGE_XML_INITUPS "/" #define MGE_XML_INITINFO "/mgeups/product.xml /product.xml /ws/product.xml" @@ -579,6 +579,7 @@ static xml_info_t mge_xml2nut[] = { /* Not used for now; might however be used in future for history & stats collection { "System.History.Log.Interval", ST_FLAG_RW, 0, "System.History.Log.Interval", 0, 0, NULL }, */ +#if (0) /* not interresting for NUT */ { "System.Environment.Log.Interval", ST_FLAG_RW, 0, "System.Environment.Log.Interval", 0, 0, NULL }, { "System.Outlet[1].iName", ST_FLAG_RW, 0, "System.Outlet[1].iName", 0, 0, NULL }, /* Mapped as ups.delay.shutdown @@ -622,7 +623,6 @@ static xml_info_t mge_xml2nut[] = { { "System.Password", ST_FLAG_RW, 0, "System.Password", 0, 0, NULL }, { "System.Security", ST_FLAG_RW, 0, "System.Security", 0, 0, NULL }, { "System.FirmwareUpgrade", ST_FLAG_RW, 0, "System.FirmwareUpgrade", 0, 0, NULL }, -#if (0) /* not interresting for NUT */ { "System.Network.SNMP.ReadCommunity", ST_FLAG_RW, 0, "System.Network.SNMP.ReadCommunity", 0, 0, NULL }, { "System.Network.SNMP.ReadCommunityName", 0, 0, "System.Network.SNMP.ReadCommunityName", 0, 0, NULL }, { "System.Network.SNMP.ReadCommunitySecurityLevel", 0, 0, "System.Network.SNMP.ReadCommunitySecurityLevel", 0, 0, NULL }, @@ -813,19 +813,14 @@ static xml_info_t mge_xml2nut[] = { { "System.ClientCfg.ShutdownDuration", ST_FLAG_RW, 0, "System.ClientCfg.ShutdownDuration", 0, 0, NULL }, { "System.ClientCfg.BroadcastAdmins", ST_FLAG_RW, 0, "System.ClientCfg.BroadcastAdmins", 0, 0, NULL }, { "System.ClientCfg.BroadcastUsers", ST_FLAG_RW, 0, "System.ClientCfg.BroadcastUsers", 0, 0, NULL }, -#endif /* not interresting for NUT */ { "Environment.iName", ST_FLAG_RW, 0, "Environment.iName", 0, 0, NULL }, { "Environment.Temperature.Unit", ST_FLAG_RW, 0, "Environment.Temperature.Unit", 0, 0, NULL }, - { "Environment.Temperature.HighThreshold", ST_FLAG_RW, 0, "Environment.Temperature.HighThreshold", 0, 0, NULL }, - { "Environment.Temperature.LowThreshold", ST_FLAG_RW, 0, "Environment.Temperature.LowThreshold", 0, 0, NULL }, { "Environment.Temperature.Hysteresis", ST_FLAG_RW, 0, "Environment.Temperature.Hysteresis", 0, 0, NULL }, { "Environment.Temperature.Offset", ST_FLAG_RW, 0, "Environment.Temperature.Offset", 0, 0, NULL }, { "Environment.Temperature.HighNotify", ST_FLAG_RW, 0, "Environment.Temperature.HighNotify", 0, 0, NULL }, { "Environment.Temperature.LowNotify", ST_FLAG_RW, 0, "Environment.Temperature.LowNotify", 0, 0, NULL }, { "Environment.Temperature.HighShutdown", ST_FLAG_RW, 0, "Environment.Temperature.HighShutdown", 0, 0, NULL }, { "Environment.Temperature.LowShutdown", ST_FLAG_RW, 0, "Environment.Temperature.LowShutdown", 0, 0, NULL }, - { "Environment.Humidity.HighThreshold", ST_FLAG_RW, 0, "Environment.Humidity.HighThreshold", 0, 0, NULL }, - { "Environment.Humidity.LowThreshold", ST_FLAG_RW, 0, "Environment.Humidity.LowThreshold", 0, 0, NULL }, { "Environment.Humidity.Hysteresis", ST_FLAG_RW, 0, "Environment.Humidity.Hysteresis", 0, 0, NULL }, { "Environment.Humidity.Offset", ST_FLAG_RW, 0, "Environment.Humidity.Offset", 0, 0, NULL }, { "Environment.Humidity.HighNotify", ST_FLAG_RW, 0, "Environment.Humidity.HighNotify", 0, 0, NULL }, @@ -850,6 +845,7 @@ static xml_info_t mge_xml2nut[] = { { "System.TimeNtp", ST_FLAG_RW, 0, "System.TimeNtp", 0, 0, NULL }, { "System.TimeZone", ST_FLAG_RW, 0, "System.TimeZone", 0, 0, NULL }, { "System.TimeDaylight", ST_FLAG_RW, 0, "System.TimeDaylight", 0, 0, NULL }, +#endif /* not interresting for NUT */ /* Special case: boolean values that are mapped to ups.status and ups.alarm */ { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", 0, 0, online_info }, @@ -1013,13 +1009,13 @@ static xml_info_t mge_xml2nut[] = { /* Ambient page */ { "ambient.humidity", 0, 0, "Environment.Humidity", 0, 0, NULL }, - { "ambient.humidity.high", 0, 0, "Environment.Humidity.HighThreshold", 0, 0, NULL }, - { "ambient.humidity.low", 0, 0, "Environment.Humidity.LowThreshold", 0, 0, NULL }, + { "ambient.humidity.high", ST_FLAG_RW, 0, "Environment.Humidity.HighThreshold", 0, 0, NULL }, + { "ambient.humidity.low", ST_FLAG_RW, 0, "Environment.Humidity.LowThreshold", 0, 0, NULL }, { "ambient.humidity.maximum", 0, 0, "Environment.PresentStatus.HighHumidity", 0, 0, mge_ambient_info }, { "ambient.humidity.minimum", 0, 0, "Environment.PresentStatus.LowHumidity", 0, 0, mge_ambient_info }, { "ambient.temperature", 0, 0, "Environment.Temperature", 0, 0, NULL }, - { "ambient.temperature.high", 0, 0, "Environment.Temperature.HighThreshold", 0, 0, NULL }, - { "ambient.temperature.low", 0, 0, "Environment.Temperature.LowThreshold", 0, 0, NULL }, + { "ambient.temperature.high", ST_FLAG_RW, 0, "Environment.Temperature.HighThreshold", 0, 0, NULL }, + { "ambient.temperature.low", ST_FLAG_RW, 0, "Environment.Temperature.LowThreshold", 0, 0, NULL }, { "ambient.temperature.maximum", 0, 0, "Environment.PresentStatus.HighTemperature", 0, 0, mge_ambient_info }, { "ambient.temperature.minimum", 0, 0, "Environment.PresentStatus.LowTemperature", 0, 0, mge_ambient_info }, @@ -1107,7 +1103,7 @@ static int mge_xml_startelm_cb(void *userdata, int parent, const char *nspace, c snprintfcat(val, sizeof(val), "/%s", atts[i+1]); s = strstr(val, " (SN "); if (s) { - dstate_setinfo("ups.serial", "%s", rtrim(s + 5, ')')); + dstate_setinfo("ups.serial", "%s", str_rtrim(s + 5, ')')); s[0] = '\0'; } dstate_setinfo("ups.firmware.aux", "%s", val); diff --git a/drivers/netvision-mib.c b/drivers/netvision-mib.c index 31801f7..0640163 100644 --- a/drivers/netvision-mib.c +++ b/drivers/netvision-mib.c @@ -44,14 +44,14 @@ static info_lkp_t netvision_batt_info[] = { { 4, "LB" }, /* battery depleted */ { 5, "DISCHRG" }, /* battery discharging */ { 6, "RB" }, /* battery failure */ - { 0, "NULL" } + { 0, NULL } }; /* Battery status: upsAlarmOnBattery */ static info_lkp_t netvision_onbatt_info[] = { { 0, "OL" }, /* Online */ { 1, "OB" }, /* On battery */ - { 0, "NULL" } + { 0, NULL } }; #define NETVISION_OID_SECONDSONBATTERY ".1.3.6.1.4.1.4555.1.1.1.1.2.2.0" @@ -110,7 +110,7 @@ static info_lkp_t netvision_output_info[] = { { 7, "OL TRIM" }, /* output source reducer */ { 8, "OL" }, /* output source standby */ { 9, "" }, /* output source ecomode */ - { 0, "NULL" } + { 0, NULL } }; /* Snmp2NUT lookup table */ @@ -181,4 +181,4 @@ static snmp_info_t netvision_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } }; -mib2nut_info_t netvision = { "netvision", NETVISION_MIB_VERSION, "", NETVISION_OID_UPSIDENTMODEL, netvision_mib, NETVISION_SYSOID }; +mib2nut_info_t netvision = { "netvision", NETVISION_MIB_VERSION, NULL, NETVISION_OID_UPSIDENTMODEL, netvision_mib, NETVISION_SYSOID }; diff --git a/drivers/nut-libfreeipmi.c b/drivers/nut-libfreeipmi.c index dd06369..06e955e 100644 --- a/drivers/nut-libfreeipmi.c +++ b/drivers/nut-libfreeipmi.c @@ -67,6 +67,7 @@ struct ipmi_monitoring_ipmi_config ipmi_config; ipmi_sdr_ctx_t sdr_ctx = NULL; ipmi_fru_ctx_t fru_ctx = NULL; #define SDR_PARSE_CTX sdr_ctx + #define NUT_IPMI_SDR_CACHE_DEFAULTS IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT #else ipmi_sdr_cache_ctx_t sdr_ctx = NULL; ipmi_sdr_parse_ctx_t sdr_parse_ctx = NULL; @@ -99,6 +100,7 @@ struct ipmi_monitoring_ipmi_config ipmi_config; #define IPMI_FRU_AREA_TYPE_BOARD_INFO_AREA IPMI_FRU_PARSE_AREA_TYPE_BOARD_INFO_AREA #define IPMI_FRU_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION #define IPMI_FRU_AREA_STRING_MAX IPMI_FRU_PARSE_AREA_STRING_MAX + #define NUT_IPMI_SDR_CACHE_DEFAULTS IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT, IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT #endif /* HAVE_FREEIPMI_11X_12X */ /* FIXME: freeipmi auto selects a cache based on the hostname you are @@ -342,8 +344,8 @@ static int libfreeipmi_get_psu_info (const void *areabuf, { /* FIXME: directly use ipmi_dev fields */ unsigned int overall_capacity; - unsigned int low_end_input_voltage_range_1; - unsigned int high_end_input_voltage_range_1; + int low_end_input_voltage_range_1; + int high_end_input_voltage_range_1; unsigned int low_end_input_frequency_range; unsigned int high_end_input_frequency_range; unsigned int voltage_1; @@ -352,8 +354,8 @@ static int libfreeipmi_get_psu_info (const void *areabuf, unsigned int peak_va; unsigned int inrush_current; unsigned int inrush_interval; - unsigned int low_end_input_voltage_range_2; - unsigned int high_end_input_voltage_range_2; + int low_end_input_voltage_range_2; + int high_end_input_voltage_range_2; unsigned int ac_dropout_tolerance; unsigned int predictive_fail_support; unsigned int power_factor_correction; @@ -554,10 +556,7 @@ static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev) { if (ipmi_sdr_cache_create (sdr_ctx, ipmi_ctx, CACHE_LOCATION, - IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT, -#ifndef HAVE_FREEIPMI_11X_12X - IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT, -#endif + NUT_IPMI_SDR_CACHE_DEFAULTS, NULL, NULL) < 0) { libfreeipmi_cleanup(); diff --git a/drivers/nutdrv_qx.c b/drivers/nutdrv_qx.c index 8b71a31..bb52660 100644 --- a/drivers/nutdrv_qx.c +++ b/drivers/nutdrv_qx.c @@ -33,7 +33,7 @@ * */ -#define DRIVER_VERSION "0.17" +#define DRIVER_VERSION "0.28" #include "main.h" @@ -475,6 +475,75 @@ static int cypress_command(const char *cmd, char *buf, size_t buflen) return i; } +/* SGS communication subdriver */ +static int sgs_command(const char *cmd, char *buf, size_t buflen) +{ + char tmp[SMALLBUF]; + int ret; + size_t cmdlen, i; + + /* Send command */ + cmdlen = strlen(cmd); + + for (i = 0; i < cmdlen; i += ret) { + + memset(tmp, 0, sizeof(tmp)); + + ret = (cmdlen - i) < 7 ? (cmdlen - i) : 7; + + tmp[0] = ret; + memcpy(&tmp[1], &cmd[i], ret); + + /* Write data in 8-byte chunks */ + ret = usb_control_msg(udev, USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0x09, 0x200, 0, tmp, 8, 5000); + + if (ret <= 0) { + upsdebugx(3, "send: %s (%d)", ret ? usb_strerror() : "timeout", ret); + return ret; + } + + ret--; + + } + + upsdebugx(3, "send: %.*s", (int)strcspn(cmd, "\r"), cmd); + + /* Read reply */ + memset(buf, 0, buflen); + + for (i = 0; i <= buflen - 8; i += ret) { + + memset(tmp, 0, sizeof(tmp)); + + /* Read data in 8-byte chunks */ + ret = usb_interrupt_read(udev, 0x81, tmp, 8, 1000); + + /* No error!!! */ + if (ret == -110) + break; + + /* Any errors here mean that we are unable to read a reply (which will happen after successfully writing a command to the UPS) */ + if (ret <= 0) { + upsdebugx(3, "read: %s (%d)", ret ? usb_strerror() : "timeout", ret); + return ret; + } + + /* Every call to read returns 8 bytes + * -> actually returned bytes: */ + ret = tmp[0] <= 7 ? tmp[0] : 7; + + if (ret > 0) + memcpy(&buf[i], &tmp[1], ret); + + snprintf(tmp, sizeof(tmp), "read [% 3d]", (int)i); + upsdebug_hex(5, tmp, &buf[i], ret); + + } + + upsdebugx(3, "read: %.*s", (int)strcspn(buf, "\r"), buf); + return i; +} + /* Phoenix communication subdriver */ static int phoenix_command(const char *cmd, char *buf, size_t buflen) { @@ -693,7 +762,10 @@ static int krauler_command(const char *cmd, char *buf, size_t buflen) } /* "UPS No Ack" has a special meaning */ - if (!strcasecmp(buf, "UPS No Ack")) { + if ( + strcspn(buf, "\r") == 10 && + !strncasecmp(buf, "UPS No Ack", 10) + ) { upsdebugx(3, "read: %.*s", (int)strcspn(buf, "\r"), buf); continue; } @@ -799,9 +871,14 @@ static int fabula_command(const char *cmd, char *buf, size_t buflen) upsdebugx(3, "read: %.*s", (int)strcspn(buf, "\r"), buf); /* The UPS always replies "UPS No Ack" when a supported command is issued (either if it fails or if it succeeds).. */ - if (!strcasecmp(buf, "UPS No Ack")) - /* ..because of that, always return 0 (as if it was a timeout): queries will see it as a failure, instant commands ('megatec' protocol) as a success */ + if ( + strcspn(buf, "\r") == 10 && + !strncasecmp(buf, "UPS No Ack", 10) + ) { + /* ..because of that, always return 0 (with buf empty, as if it was a timeout): queries will see it as a failure, instant commands ('megatec' protocol) as a success */ + memset(buf, 0, buflen); return 0; + } return ret; } @@ -936,6 +1013,12 @@ static void *cypress_subdriver(USBDevice_t *device) return NULL; } +static void *sgs_subdriver(USBDevice_t *device) +{ + subdriver_command = &sgs_command; + return NULL; +} + static void *ippon_subdriver(USBDevice_t *device) { subdriver_command = &ippon_command; @@ -988,6 +1071,7 @@ static qx_usb_device_id_t qx_usb_id[] = { { USB_DEVICE(0x06da, 0x0601), NULL, NULL, &phoenix_subdriver }, /* Online Zinto A */ { USB_DEVICE(0x0f03, 0x0001), NULL, NULL, &cypress_subdriver }, /* Unitek Alpha 1200Sx */ { USB_DEVICE(0x14f0, 0x00c9), NULL, NULL, &phoenix_subdriver }, /* GE EP series */ + { USB_DEVICE(0x0483, 0x0035), NULL, NULL, &sgs_subdriver }, /* TS Shara UPSes */ { USB_DEVICE(0x0001, 0x0000), "MEC", "MEC0003", &fabula_subdriver }, /* Fideltronik/MEC LUPUS 500 USB */ { USB_DEVICE(0x0001, 0x0000), "ATCL FOR UPS", "ATCL FOR UPS", &fuji_subdriver }, /* Fuji UPSes */ { USB_DEVICE(0x0001, 0x0000), NULL, NULL, &krauler_subdriver }, /* Krauler UP-M500VA */ @@ -1056,7 +1140,7 @@ static USBDeviceMatcher_t device_matcher = { /* == Driver functions implementations == */ -/* Process instant command and take action. */ +/* See header file for details. */ int instcmd(const char *cmdname, const char *extradata) { item_t *item; @@ -1136,7 +1220,7 @@ int instcmd(const char *cmdname, const char *extradata) return STAT_INSTCMD_INVALID; } - /* If extradata is empty, use the default value from the QX to NUT table */ + /* If extradata is empty, use the default value from the QX to NUT table, if any */ extradata = extradata ? extradata : item->dfl; snprintf(value, sizeof(value), "%s", extradata ? extradata : ""); @@ -1180,7 +1264,7 @@ int instcmd(const char *cmdname, const char *extradata) return STAT_INSTCMD_HANDLED; } -/* Set r/w variable to a value. */ +/* See header file for details. */ int setvar(const char *varname, const char *val) { item_t *item; @@ -1840,6 +1924,7 @@ void upsdrv_initups(void) { "krauler", &krauler_command }, { "fabula", &fabula_command }, { "fuji", &fuji_command }, + { "sgs", &sgs_command }, { NULL } }; @@ -2168,7 +2253,7 @@ static int qx_command(const char *cmd, char *buf, size_t buflen) #endif /* TESTING */ } -/* Update ups_status to remember this status item. +/* See header file for details. * Interpretation is done in ups_status_set(). */ void update_status(const char *value) { @@ -2600,9 +2685,7 @@ static void ups_status_set(void) } } -/* Find element definition in qx2nut array by NUT varname optionally filtered by its qxflags: - * - 'flag': flags that have to be set in the item, i.e. if one of the flags is absent in the item it won't be returned - * - 'noflag': flags that have to be absent in the item, i.e. if at least one of the flags is set in the item it won't be returned */ +/* See header file for details. */ item_t *find_nut_info(const char *varname, const unsigned long flag, const unsigned long noflag) { item_t *item; @@ -2647,6 +2730,12 @@ static int qx_process_answer(item_t *item, const int len) return -1; } + /* Check boundaries */ + if (item->to && item->to < item->from) { + upsdebugx(1, "%s: in %s, starting char's position (%d) follows ending char's one (%d)", __func__, item->info_type, item->from, item->to); + return -1; + } + /* Get value */ if (strlen(item->answer)) { snprintf(item->value, sizeof(item->value), "%.*s", item->to ? 1 + item->to - item->from : (int)strcspn(item->answer, "\r") - item->from, item->answer + item->from); @@ -2657,23 +2746,39 @@ static int qx_process_answer(item_t *item, const int len) return 0; } -/* Send the command to the UPS and process the reply. - * Return -1 on errors, 0 on success */ +/* See header file for details. */ int qx_process(item_t *item, const char *command) { - char buf[SMALLBUF] = ""; + char buf[sizeof(item->answer) - 1] = "", + cmd[command ? (strlen(command) >= SMALLBUF ? strlen(command) + 1 : SMALLBUF) : (item->command && strlen(item->command) >= SMALLBUF ? strlen(item->command) + 1 : SMALLBUF)]; + int len; + + /* Prepare the command to be used */ + memset(cmd, 0, sizeof(cmd)); + snprintf(cmd, sizeof(cmd), "%s", command ? command : item->command); + + /* Preprocess the command */ + if ( + item->preprocess_command != NULL && + item->preprocess_command(item, cmd, sizeof(cmd)) == -1 + ) { + upsdebugx(4, "%s: failed to preprocess command [%s]", __func__, item->info_type); + return -1; + } /* Send the command */ - int len = qx_command(command ? command : item->command, buf, sizeof(buf)); + len = qx_command(cmd, buf, sizeof(buf)); memset(item->answer, 0, sizeof(item->answer)); - memcpy(item->answer, buf, sizeof(item->answer) <= sizeof(buf) ? sizeof(item->answer) - 1 : sizeof(buf)); + memcpy(item->answer, buf, sizeof(buf)); /* Preprocess the answer */ if (item->preprocess_answer != NULL) { len = item->preprocess_answer(item, len); if (len == -1) { upsdebugx(4, "%s: failed to preprocess answer [%s]", __func__, item->info_type); + /* Clear answer, preventing it from being reused by next items with same command */ + memset(item->answer, 0, sizeof(item->answer)); return -1; } } @@ -2682,10 +2787,7 @@ int qx_process(item_t *item, const char *command) return qx_process_answer(item, len); } -/* Process the value we got back (set status bits and set the value of other parameters) and execute: - * - item-specific preprocessing, if any, otherwise - * - the standard preprocessing (including trimming if QX_FLAG_TRIM is set). - * Return -1 on failure, 0 for a status update and 1 in all other cases */ +/* See header file for details. */ int ups_infoval_set(item_t *item) { char value[SMALLBUF] = ""; @@ -2719,7 +2821,7 @@ int ups_infoval_set(item_t *item) /* Cover most of the cases: either left/right filled with hashes, spaces or a mix of both */ if (item->qxflags & QX_FLAG_TRIM) - rtrim_m(ltrim_m(value, "# "), "# "); + str_trim_m(value, "# "); if (strcasecmp(item->dfl, "%s")) { @@ -2754,7 +2856,7 @@ int ups_infoval_set(item_t *item) return 1; } -/* Return actual status */ +/* See header file for details. */ int qx_status(void) { return ups_status; diff --git a/drivers/nutdrv_qx.h b/drivers/nutdrv_qx.h index 7672c76..73238e0 100644 --- a/drivers/nutdrv_qx.h +++ b/drivers/nutdrv_qx.h @@ -53,9 +53,9 @@ typedef int bool_t; /* Structure for rw vars */ typedef struct { - char value[SMALLBUF]; /* Value for enum/range, or length for ST_FLAG_STRING */ - int (*preprocess)(char *value, size_t len); /* Optional function to preprocess range/enum value. - * This function will be given value and its size_t and must return either 0 if value is supported or -1 if not supported. */ + char value[SMALLBUF]; /* Value for enum/range, or length for ST_FLAG_STRING */ + int (*preprocess)(char *value, const size_t len); /* Optional function to preprocess range/enum value. + * This function will be given value and its size_t and must return either 0 if value is supported or -1 if not supported. */ } info_rw_t; /* Structure containing information about how to get/set data from/to the UPS and convert these to/from NUT standard */ @@ -88,11 +88,19 @@ typedef struct item_t { unsigned long qxflags; /* Driver's own flags */ - int (*preprocess_answer)(struct item_t *item, const int len); /* Function to preprocess the answer we got from the UPS before we do anything else (e.g. for CRC, decoding, ...) + int (*preprocess_command)(struct item_t *item, char *command, const size_t commandlen); + /* Last chance to preprocess the command to be sent to the UPS (e.g. to add CRC, ...). + * This function is given the currently processed item (item), the command to be sent to the UPS (command) and its size_t (commandlen). + * Return -1 in case of errors, else 0. + * command must be filled with the actual command to be sent to the UPS. */ + + int (*preprocess_answer)(struct item_t *item, const int len); + /* Function to preprocess the answer we got from the UPS before we do anything else (e.g. for CRC, decoding, ...). * This function is given the currently processed item (item) with the answer we got from the UPS unmolested and already stored in item->answer and the length of that answer (len). * Return -1 in case of errors, else the length of the newly allocated item->answer (from now on, treated as a null-terminated string). */ - int (*preprocess)(struct item_t *item, char *value, size_t valuelen); /* Function to preprocess the data from/to the UPS + int (*preprocess)(struct item_t *item, char *value, const size_t valuelen); + /* Function to preprocess the data from/to the UPS * This function is given the currently processed item (item), a char array (value) and its size_t (valuelen). * Return -1 in case of errors, else 0. * If QX_FLAG_SETVAR/QX_FLAG_CMD -> process command before it is sent: value must be filled with the command to be sent to the UPS. @@ -149,7 +157,11 @@ typedef struct { } subdriver_t; /* The following functions are exported for the benefit of subdrivers */ - /* Execute an instant command. Return STAT_INSTCMD_INVALID if the command is invalid, STAT_INSTCMD_FAILED if it failed, STAT_INSTCMD_HANDLED on success. */ + /* Execute an instant command. In detail: + * - look up the given 'cmdname' in the qx2nut data structure (if not found, try to fallback to commonly known commands); + * - if 'cmdname' is found, call its preprocess function, passing to it 'extradata', if any, otherwise its dfl value, if any; + * - send the command to the device and check the reply. + * Return STAT_INSTCMD_INVALID if the command is invalid, STAT_INSTCMD_FAILED if it failed, STAT_INSTCMD_HANDLED on success. */ int instcmd(const char *cmdname, const char *extradata); /* Set r/w variable to a value after it has been checked against its info_rw structure. Return STAT_SET_HANDLED on success, otherwise STAT_SET_UNKNOWN. */ int setvar(const char *varname, const char *val); @@ -157,9 +169,9 @@ int setvar(const char *varname, const char *val); * - 'flag': flags that have to be set in the item, i.e. if one of the flags is absent in the item it won't be returned * - 'noflag': flags that have to be absent in the item, i.e. if at least one of the flags is set in the item it won't be returned */ item_t *find_nut_info(const char *varname, const unsigned long flag, const unsigned long noflag); - /* Send 'command' or, if it is NULL, send the command stored in the item to the UPS and process the reply. Return -1 on errors, 0 on success. */ + /* Send 'command' (a null-terminated byte string) or, if it is NULL, send the command stored in the item to the UPS and process the reply, saving it in item->answer. Return -1 on errors, 0 on success. */ int qx_process(item_t *item, const char *command); - /* Process the value we got back from the UPS (set status bits and set the value of other parameters), calling its preprocess function, if any, otherwise executing the standard preprocessing (including trimming if QX_FLAG_TRIM is set). + /* Process the value we got back from the UPS (set status bits and set the value of other parameters), calling the item-specific preprocess function, if any, otherwise executing the standard preprocessing (including trimming if QX_FLAG_TRIM is set). * Return -1 on failure, 0 for a status update and 1 in all other cases. */ int ups_infoval_set(item_t *item); /* Return the currently processed status so that it can be checked with one of the status_bit_t passed to the STATUS() macro. */ diff --git a/drivers/nutdrv_qx_bestups.c b/drivers/nutdrv_qx_bestups.c index 1e15b27..1d4955c 100644 --- a/drivers/nutdrv_qx_bestups.c +++ b/drivers/nutdrv_qx_bestups.c @@ -29,7 +29,7 @@ #include "nutdrv_qx_bestups.h" -#define BESTUPS_VERSION "BestUPS 0.04" +#define BESTUPS_VERSION "BestUPS 0.06" /* Support functions */ static int bestups_claim(void); @@ -40,14 +40,14 @@ static void bestups_makevartable(void); static int bestups_preprocess_id_answer(item_t *item, const int len); /* Preprocess functions */ -static int bestups_process_setvar(item_t *item, char *value, size_t valuelen); -static int bestups_process_bbb_status_bit(item_t *item, char *value, size_t valuelen); -static int bestups_manufacturer(item_t *item, char *value, size_t valuelen); -static int bestups_model(item_t *item, char *value, size_t valuelen); -static int bestups_batt_runtime(item_t *item, char *value, size_t valuelen); -static int bestups_batt_packs(item_t *item, char *value, size_t valuelen); -static int bestups_get_pins_shutdown_mode(item_t *item, char *value, size_t valuelen); -static int bestups_voltage_settings(item_t *item, char *value, size_t valuelen); +static int bestups_process_setvar(item_t *item, char *value, const size_t valuelen); +static int bestups_process_bbb_status_bit(item_t *item, char *value, const size_t valuelen); +static int bestups_manufacturer(item_t *item, char *value, const size_t valuelen); +static int bestups_model(item_t *item, char *value, const size_t valuelen); +static int bestups_batt_runtime(item_t *item, char *value, const size_t valuelen); +static int bestups_batt_packs(item_t *item, char *value, const size_t valuelen); +static int bestups_get_pins_shutdown_mode(item_t *item, char *value, const size_t valuelen); +static int bestups_voltage_settings(item_t *item, char *value, const size_t valuelen); /* ups.conf settings */ static int pins_shutdown_mode; @@ -97,22 +97,22 @@ static item_t bestups_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ -/* { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, *//* Beeper status: not supported; always 0 */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, bestups_process_bbb_status_bit }, /* Bypass/Boost or Buck Active - keep this one at the end as it needs the processed data from the previous items */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ +/* { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, *//* Beeper status: not supported; always 0 */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, bestups_process_bbb_status_bit }, /* Bypass/Boost or Buck Active - keep this one at the end as it needs the processed data from the previous items */ /* Query UPS for ratings and model infos * > [ID\r] @@ -124,13 +124,13 @@ static item_t bestups_qx2nut[] = { * 0 1 2 */ - { "device.mfr", 0, NULL, "ID\r", "", 28, 0, "", 0, 2, "%s", QX_FLAG_STATIC, bestups_preprocess_id_answer, bestups_manufacturer }, - { "device.model", 0, NULL, "ID\r", "", 28, 0, "", 0, 2, "%s", QX_FLAG_STATIC, bestups_preprocess_id_answer, bestups_model }, - { "ups.power.nominal", 0, NULL, "ID\r", "", 28, 0, "", 4, 7, "%.0f", QX_FLAG_STATIC, bestups_preprocess_id_answer, NULL }, - { "input.voltage.nominal", 0, NULL, "ID\r", "", 28, 0, "", 9, 11, "%.0f", QX_FLAG_STATIC, bestups_preprocess_id_answer, NULL }, - { "output.voltage.nominal", 0, NULL, "ID\r", "", 28, 0, "", 13, 15, "%.0f", QX_FLAG_STATIC, bestups_preprocess_id_answer, NULL }, - { "battery.voltage.low", 0, NULL, "ID\r", "", 28, 0, "", 17, 20, "%.1f", QX_FLAG_SEMI_STATIC, bestups_preprocess_id_answer, NULL }, - { "battery.voltage.high", 0, NULL, "ID\r", "", 28, 0, "", 22, 26, "%.1f", QX_FLAG_SEMI_STATIC, bestups_preprocess_id_answer, NULL }, + { "device.mfr", 0, NULL, "ID\r", "", 28, 0, "", 0, 2, "%s", QX_FLAG_STATIC, NULL, bestups_preprocess_id_answer, bestups_manufacturer }, + { "device.model", 0, NULL, "ID\r", "", 28, 0, "", 0, 2, "%s", QX_FLAG_STATIC, NULL, bestups_preprocess_id_answer, bestups_model }, + { "ups.power.nominal", 0, NULL, "ID\r", "", 28, 0, "", 4, 7, "%.0f", QX_FLAG_STATIC, NULL, bestups_preprocess_id_answer, NULL }, + { "input.voltage.nominal", 0, NULL, "ID\r", "", 28, 0, "", 9, 11, "%.0f", QX_FLAG_STATIC, NULL, bestups_preprocess_id_answer, NULL }, + { "output.voltage.nominal", 0, NULL, "ID\r", "", 28, 0, "", 13, 15, "%.0f", QX_FLAG_STATIC, NULL, bestups_preprocess_id_answer, NULL }, + { "battery.voltage.low", 0, NULL, "ID\r", "", 28, 0, "", 17, 20, "%.1f", QX_FLAG_SEMI_STATIC, NULL, bestups_preprocess_id_answer, NULL }, + { "battery.voltage.high", 0, NULL, "ID\r", "", 28, 0, "", 22, 26, "%.1f", QX_FLAG_SEMI_STATIC, NULL, bestups_preprocess_id_answer, NULL }, /* Query UPS for battery runtime (not available on the Patriot Pro/Sola 320 model series) * > [RT\r] @@ -139,7 +139,7 @@ static item_t bestups_qx2nut[] = { * 0 */ - { "battery.runtime", 0, NULL, "RT\r", "", 4, 0, "", 0, 2, "%.0f", QX_FLAG_SKIP, NULL, bestups_batt_runtime }, + { "battery.runtime", 0, NULL, "RT\r", "", 4, 0, "", 0, 2, "%.0f", QX_FLAG_SKIP, NULL, NULL, bestups_batt_runtime }, /* Query UPS for number of battery packs (available only on the Axxium/Sola 620 model series) * > [BP?\r] @@ -148,14 +148,14 @@ static item_t bestups_qx2nut[] = { * 0 */ - { "battery.packs", ST_FLAG_RW, bestups_r_batt_packs, "BP?\r", "", 3, 0, "", 0, 1, "%d", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, bestups_batt_packs }, + { "battery.packs", ST_FLAG_RW, bestups_r_batt_packs, "BP?\r", "", 3, 0, "", 0, 1, "%d", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, bestups_batt_packs }, /* Set number of battery packs to n (integer, 0-5) (available only on the Axxium/Sola 620 model series) * > [BPn\r] * < [] */ - { "battery.packs", 0, bestups_r_batt_packs, "BP%.0f\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, bestups_process_setvar }, + { "battery.packs", 0, bestups_r_batt_packs, "BP%.0f\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, bestups_process_setvar }, /* Query UPS for shutdown mode functionality of Pin 1 and Pin 7 on the UPS DB9 communication port (Per Best Power’s EPS-0059) * > [SS?\r] @@ -164,14 +164,14 @@ static item_t bestups_qx2nut[] = { * 0 */ - { "pins_shutdown_mode", ST_FLAG_RW, bestups_r_pins_shutdown_mode, "SS?\r", "", 2, 0, "", 0, 0, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, bestups_get_pins_shutdown_mode }, + { "pins_shutdown_mode", ST_FLAG_RW, bestups_r_pins_shutdown_mode, "SS?\r", "", 2, 0, "", 0, 0, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, NULL, bestups_get_pins_shutdown_mode }, /* Set shutdown mode functionality of Pin 1 and Pin 7 on the UPS DB9 communication port (Per Best Power’s EPS-0059) to n (integer, 0-6) * > [SSn\r] * < [] */ - { "pins_shutdown_mode", 0, bestups_r_pins_shutdown_mode, "SS%.0f\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, bestups_process_setvar }, + { "pins_shutdown_mode", 0, bestups_r_pins_shutdown_mode, "SS%.0f\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, bestups_process_setvar }, /* Query UPS for voltage settings * > [M\r] @@ -180,32 +180,32 @@ static item_t bestups_qx2nut[] = { * 0 */ - { "input.transfer.low", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "input.transfer.boost.low", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "input.transfer.boost.high", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "input.voltage.nominal", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "output.voltage.nominal", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "input.transfer.trim.low", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "input.transfer.trim.high", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, - { "input.transfer.high", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, bestups_voltage_settings }, + { "input.transfer.low", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "input.transfer.boost.low", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "input.transfer.boost.high", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "input.voltage.nominal", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "output.voltage.nominal", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "input.transfer.trim.low", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "input.transfer.trim.high", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, + { "input.transfer.high", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%d", 0, NULL, NULL, bestups_voltage_settings }, /* Instant commands */ - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, bestups_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, bestups_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, bestups_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, bestups_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; @@ -354,7 +354,7 @@ static int bestups_preprocess_id_answer(item_t *item, const int len) /* == Preprocess functions == */ /* *SETVAR(/NONUT)* Preprocess setvars */ -static int bestups_process_setvar(item_t *item, char *value, size_t valuelen) +static int bestups_process_setvar(item_t *item, char *value, const size_t valuelen) { if (!strlen(value)) { upsdebugx(2, "%s: value not given for %s", __func__, item->info_type); @@ -378,7 +378,7 @@ static int bestups_process_setvar(item_t *item, char *value, size_t valuelen) } /* Bypass/Boost or Buck status */ -static int bestups_process_bbb_status_bit(item_t *item, char *value, size_t valuelen) +static int bestups_process_bbb_status_bit(item_t *item, char *value, const size_t valuelen) { /* Bypass/Boost/Buck bit is not reliable when a battery test, shutdown or on battery condition occurs: always ignore it in these cases */ if (!(qx_status() & STATUS(OL)) || (qx_status() & (STATUS(CAL) | STATUS(FSD)))) { @@ -405,7 +405,7 @@ static int bestups_process_bbb_status_bit(item_t *item, char *value, size_t valu } /* Identify UPS manufacturer */ -static int bestups_manufacturer(item_t *item, char *value, size_t valuelen) +static int bestups_manufacturer(item_t *item, char *value, const size_t valuelen) { /* Best Power devices */ if ( @@ -435,7 +435,7 @@ static int bestups_manufacturer(item_t *item, char *value, size_t valuelen) } /* Identify UPS model and unskip qx2nut table's items accordingly */ -static int bestups_model(item_t *item, char *value, size_t valuelen) +static int bestups_model(item_t *item, char *value, const size_t valuelen) { item_t *unskip; @@ -514,7 +514,7 @@ static int bestups_model(item_t *item, char *value, size_t valuelen) } /* Battery runtime */ -static int bestups_batt_runtime(item_t *item, char *value, size_t valuelen) +static int bestups_batt_runtime(item_t *item, char *value, const size_t valuelen) { double runtime; @@ -532,7 +532,7 @@ static int bestups_batt_runtime(item_t *item, char *value, size_t valuelen) } /* Battery packs */ -static int bestups_batt_packs(item_t *item, char *value, size_t valuelen) +static int bestups_batt_packs(item_t *item, char *value, const size_t valuelen) { item_t *unskip; @@ -556,7 +556,7 @@ static int bestups_batt_packs(item_t *item, char *value, size_t valuelen) } /* *NONUT* Get shutdown mode functionality of Pin 1 and Pin 7 on the UPS DB9 communication port (Per Best Power’s EPS-0059) as set in the UPS */ -static int bestups_get_pins_shutdown_mode(item_t *item, char *value, size_t valuelen) +static int bestups_get_pins_shutdown_mode(item_t *item, char *value, const size_t valuelen) { item_t *unskip; @@ -586,7 +586,7 @@ static int bestups_get_pins_shutdown_mode(item_t *item, char *value, size_t valu } /* Voltage settings */ -static int bestups_voltage_settings(item_t *item, char *value, size_t valuelen) +static int bestups_voltage_settings(item_t *item, char *value, const size_t valuelen) { int index, val; const char *nominal_voltage; diff --git a/drivers/nutdrv_qx_blazer-common.c b/drivers/nutdrv_qx_blazer-common.c index 04fb7ae..feecad1 100644 --- a/drivers/nutdrv_qx_blazer-common.c +++ b/drivers/nutdrv_qx_blazer-common.c @@ -189,7 +189,7 @@ void blazer_initups_light(item_t *qx2nut) /* == Preprocess functions == */ /* Preprocess setvars */ -int blazer_process_setvar(item_t *item, char *value, size_t valuelen) +int blazer_process_setvar(item_t *item, char *value, const size_t valuelen) { if (!strlen(value)) { upsdebugx(2, "%s: value not given for %s", __func__, item->info_type); @@ -229,7 +229,7 @@ int blazer_process_setvar(item_t *item, char *value, size_t valuelen) } /* Preprocess instant commands */ -int blazer_process_command(item_t *item, char *value, size_t valuelen) +int blazer_process_command(item_t *item, char *value, const size_t valuelen) { if (!strcasecmp(item->info_type, "shutdown.return")) { @@ -307,7 +307,7 @@ int blazer_process_command(item_t *item, char *value, size_t valuelen) } /* Process status bits */ -int blazer_process_status_bits(item_t *item, char *value, size_t valuelen) +int blazer_process_status_bits(item_t *item, char *value, const size_t valuelen) { char *val = ""; diff --git a/drivers/nutdrv_qx_blazer-common.h b/drivers/nutdrv_qx_blazer-common.h index 1cab5be..c331599 100644 --- a/drivers/nutdrv_qx_blazer-common.h +++ b/drivers/nutdrv_qx_blazer-common.h @@ -33,9 +33,9 @@ int blazer_claim(void); int blazer_claim_light(void); /* Preprocess functions */ -int blazer_process_command(item_t *item, char *value, size_t valuelen); -int blazer_process_setvar(item_t *item, char *value, size_t valuelen); -int blazer_process_status_bits(item_t *item, char *value, size_t valuelen); +int blazer_process_command(item_t *item, char *value, const size_t valuelen); +int blazer_process_setvar(item_t *item, char *value, const size_t valuelen); +int blazer_process_status_bits(item_t *item, char *value, const size_t valuelen); /* Ranges */ extern info_rw_t blazer_r_ondelay[]; diff --git a/drivers/nutdrv_qx_mecer.c b/drivers/nutdrv_qx_mecer.c index 7386754..2e2bacf 100644 --- a/drivers/nutdrv_qx_mecer.c +++ b/drivers/nutdrv_qx_mecer.c @@ -25,15 +25,15 @@ #include "nutdrv_qx_mecer.h" -#define MECER_VERSION "Mecer 0.05" +#define MECER_VERSION "Mecer 0.07" /* Support functions */ static int mecer_claim(void); static void mecer_initups(void); /* Preprocess functions */ -static int voltronic_p98_protocol(item_t *item, char *value, size_t valuelen); -static int mecer_process_test_battery(item_t *item, char *value, size_t valuelen); +static int voltronic_p98_protocol(item_t *item, char *value, const size_t valuelen); +static int mecer_process_test_battery(item_t *item, char *value, const size_t valuelen); /* == qx2nut lookup table == */ @@ -46,7 +46,7 @@ static item_t mecer_qx2nut[] = { * 0 */ - { "ups.firmware.aux", 0, NULL, "QPI\r", "", 6, '(', "", 1, 4, "%s", QX_FLAG_STATIC, NULL, voltronic_p98_protocol }, + { "ups.firmware.aux", 0, NULL, "QPI\r", "", 6, '(', "", 1, 4, "%s", QX_FLAG_STATIC, NULL, NULL, voltronic_p98_protocol }, /* * > [Q1\r] @@ -55,22 +55,22 @@ static item_t mecer_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* * > [F\r] @@ -79,10 +79,10 @@ static item_t mecer_qx2nut[] = { * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* * > [I\r] @@ -91,30 +91,30 @@ static item_t mecer_qx2nut[] = { * 0 1 2 3 */ - { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Instant commands * The UPS will reply '(ACK\r' in case of success, '(NAK\r' if the command is rejected or invalid */ - { "beeper.toggle", 0, NULL, "Q\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, mecer_process_test_battery }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, mecer_process_test_battery }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; @@ -208,7 +208,7 @@ static void mecer_initups(void) /* == Preprocess functions == */ /* Protocol used by the UPS */ -static int voltronic_p98_protocol(item_t *item, char *value, size_t valuelen) +static int voltronic_p98_protocol(item_t *item, char *value, const size_t valuelen) { if (strcasecmp(item->value, "PI98")) { upslogx(LOG_ERR, "Protocol [%s] is not supported by this driver", item->value); @@ -221,7 +221,7 @@ static int voltronic_p98_protocol(item_t *item, char *value, size_t valuelen) } /* *CMD* Preprocess 'test.battery.start' instant command */ -static int mecer_process_test_battery(item_t *item, char *value, size_t valuelen) +static int mecer_process_test_battery(item_t *item, char *value, const size_t valuelen) { const char *protocol = dstate_getinfo("ups.firmware.aux"); char buf[SMALLBUF] = ""; diff --git a/drivers/nutdrv_qx_megatec-old.c b/drivers/nutdrv_qx_megatec-old.c index ce39926..4b6fdde 100644 --- a/drivers/nutdrv_qx_megatec-old.c +++ b/drivers/nutdrv_qx_megatec-old.c @@ -25,7 +25,7 @@ #include "nutdrv_qx_megatec-old.h" -#define MEGATEC_OLD_VERSION "Megatec/old 0.05" +#define MEGATEC_OLD_VERSION "Megatec/old 0.07" /* qx2nut lookup table */ static item_t megatec_old_qx2nut[] = { @@ -37,22 +37,22 @@ static item_t megatec_old_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "D\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "D\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "D\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "D\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "D\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "D\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "D\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "D\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "D\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "D\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "D\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "D\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "D\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "D\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "D\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "D\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "D\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "D\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "D\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "D\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "D\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* * > [F\r] @@ -61,10 +61,10 @@ static item_t megatec_old_qx2nut[] = { * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* * > [I\r] @@ -73,28 +73,28 @@ static item_t megatec_old_qx2nut[] = { * 0 1 2 3 */ - { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; /* Testing table */ diff --git a/drivers/nutdrv_qx_megatec.c b/drivers/nutdrv_qx_megatec.c index f0f02f1..e22979a 100644 --- a/drivers/nutdrv_qx_megatec.c +++ b/drivers/nutdrv_qx_megatec.c @@ -25,7 +25,7 @@ #include "nutdrv_qx_megatec.h" -#define MEGATEC_VERSION "Megatec 0.04" +#define MEGATEC_VERSION "Megatec 0.06" /* qx2nut lookup table */ static item_t megatec_qx2nut[] = { @@ -37,22 +37,22 @@ static item_t megatec_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* * > [F\r] @@ -61,10 +61,10 @@ static item_t megatec_qx2nut[] = { * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* * > [I\r] @@ -73,28 +73,28 @@ static item_t megatec_qx2nut[] = { * 0 1 2 3 */ - { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; /* Testing table */ diff --git a/drivers/nutdrv_qx_mustek.c b/drivers/nutdrv_qx_mustek.c index 17b8eb6..7990b41 100644 --- a/drivers/nutdrv_qx_mustek.c +++ b/drivers/nutdrv_qx_mustek.c @@ -25,7 +25,7 @@ #include "nutdrv_qx_mustek.h" -#define MUSTEK_VERSION "Mustek 0.05" +#define MUSTEK_VERSION "Mustek 0.07" /* qx2nut lookup table */ static item_t mustek_qx2nut[] = { @@ -37,22 +37,22 @@ static item_t mustek_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "QS\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "QS\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "QS\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "QS\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "QS\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "QS\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "QS\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "QS\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "QS\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "QS\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "QS\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "QS\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "QS\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "QS\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "QS\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "QS\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "QS\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "QS\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "QS\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "QS\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* * > [F\r] @@ -61,10 +61,10 @@ static item_t mustek_qx2nut[] = { * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* * > [I\r] @@ -73,28 +73,28 @@ static item_t mustek_qx2nut[] = { * 0 1 2 3 */ - { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; /* Testing table */ diff --git a/drivers/nutdrv_qx_q1.c b/drivers/nutdrv_qx_q1.c index be37018..bf3e253 100644 --- a/drivers/nutdrv_qx_q1.c +++ b/drivers/nutdrv_qx_q1.c @@ -35,7 +35,7 @@ #include "nutdrv_qx_q1.h" -#define Q1_VERSION "Q1 0.05" +#define Q1_VERSION "Q1 0.07" /* qx2nut lookup table */ static item_t q1_qx2nut[] = { @@ -47,41 +47,41 @@ static item_t q1_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; /* Testing table */ diff --git a/drivers/nutdrv_qx_voltronic-qs-hex.c b/drivers/nutdrv_qx_voltronic-qs-hex.c index 551182b..6b21acd 100644 --- a/drivers/nutdrv_qx_voltronic-qs-hex.c +++ b/drivers/nutdrv_qx_voltronic-qs-hex.c @@ -25,7 +25,7 @@ #include "nutdrv_qx_voltronic-qs-hex.h" -#define VOLTRONIC_QS_HEX_VERSION "Voltronic-QS-Hex 0.03" +#define VOLTRONIC_QS_HEX_VERSION "Voltronic-QS-Hex 0.10" /* Support functions */ static int voltronic_qs_hex_claim(void); @@ -33,15 +33,15 @@ static void voltronic_qs_hex_initups(void); /* Answer preprocess functions */ static int voltronic_qs_hex_preprocess_qs_answer(item_t *item, const int len); -static int voltronic_qs_hex_status_char_to_binary(const unsigned char value); +static int voltronic_qs_hex_char_to_binary(const unsigned char value); /* Preprocess functions */ -static int voltronic_qs_hex_protocol(item_t *item, char *value, size_t valuelen); -static int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, size_t valuelen); -static int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, size_t valuelen); -static int voltronic_qs_hex_load(item_t *item, char *value, size_t valuelen); -static int voltronic_qs_hex_frequency(item_t *item, char *value, size_t valuelen); -static int voltronic_qs_hex_battery_voltage(item_t *item, char *value, size_t valuelen); +static int voltronic_qs_hex_protocol(item_t *item, char *value, const size_t valuelen); +static int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, const size_t valuelen); +static int voltronic_qs_hex_load(item_t *item, char *value, const size_t valuelen); +static int voltronic_qs_hex_frequency(item_t *item, char *value, const size_t valuelen); +static int voltronic_qs_hex_battery_voltage(item_t *item, char *value, const size_t valuelen); +static int voltronic_qs_hex_process_ratings_bits(item_t *item, char *value, const size_t valuelen); /* == Ranges == */ @@ -71,45 +71,52 @@ static item_t voltronic_qs_hex_qx2nut[] = { * 0 */ - { "ups.firmware.aux", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "PMV-%s", QX_FLAG_STATIC, NULL, voltronic_qs_hex_protocol }, + { "ups.firmware.aux", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "PM-%s", QX_FLAG_STATIC, NULL, NULL, voltronic_qs_hex_protocol }, /* Query UPS for status * > [QS\r] - * < [#6C01 35 6C01 35 03 519A 1312D0 E6 1E 00001001\r] (after being preprocessed) - * 01234567890123456789012345678901234567890123456 - * 0 1 2 3 4 + * < [#6C01 35 6C01 35 03 519A 1312D0 E6 1E 00001001\r] ('P' protocol, after being preprocessed) + * < [#6901 6C 6802 6C 00 5FD7 12C000 E4 1E 00001001 00000010\r] ('T' protocol, after being preprocessed) + * 01234567890123456789012345678901234567890123456789012345 + * 0 1 2 3 4 5 */ - { "input.voltage", 0, NULL, "QS\r", "", 47, '#', "", 1, 7, "%.1f", 0, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_input_output_voltage }, - { "output.voltage", 0, NULL, "QS\r", "", 47, '#', "", 9, 15, "%.1f", 0, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_input_output_voltage }, - { "ups.load", 0, NULL, "QS\r", "", 47, '#', "", 17, 18, "%d", 0, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_load }, - { "output.frequency", 0, NULL, "QS\r", "", 47, '#', "", 20, 30, "%.1f", 0, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_frequency }, - { "battery.voltage", 0, NULL, "QS\r", "", 47, '#', "", 32, 36, "%.2f", 0, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_battery_voltage }, + { "input.voltage", 0, NULL, "QS\r", "", 47, '#', "", 1, 7, "%.1f", 0, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_input_output_voltage }, + { "output.voltage", 0, NULL, "QS\r", "", 47, '#', "", 9, 15, "%.1f", 0, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_input_output_voltage }, + { "ups.load", 0, NULL, "QS\r", "", 47, '#', "", 17, 18, "%d", 0, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_load }, + { "output.frequency", 0, NULL, "QS\r", "", 47, '#', "", 20, 30, "%.1f", 0, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_frequency }, + { "battery.voltage", 0, NULL, "QS\r", "", 47, '#', "", 32, 36, "%.2f", 0, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_battery_voltage }, /* Status bits */ - { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "QS\r", "", 47, '#', "", 41, 41, NULL, 0, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "QS\r", "", 47, '#', "", 42, 42, "%s", QX_FLAG_STATIC, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "QS\r", "", 47, '#', "", 45, 45, "%s", 0, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "QS\r", "", 47, '#', "", 41, 41, NULL, 0, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "QS\r", "", 47, '#', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "QS\r", "", 47, '#', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "QS\r", "", 47, '#', "", 45, 45, "%s", 0, NULL, voltronic_qs_hex_preprocess_qs_answer, blazer_process_status_bits }, /* Beeper status */ + /* Ratings bits */ + { "output.frequency.nominal", 0, NULL, "QS\r", "", 56, '#', "", 47, 47, "%.1f", QX_FLAG_SKIP, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_process_ratings_bits }, + { "battery.voltage.nominal", 0, NULL, "QS\r", "", 56, '#', "", 48, 49, "%.1f", QX_FLAG_SKIP, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_process_ratings_bits }, +/* { "reserved.1", 0, NULL, "QS\r", "", 56, '#', "", 50, 50, "%s", QX_FLAG_SKIP, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_process_ratings_bits }, *//* Reserved */ +/* { "reserved.2", 0, NULL, "QS\r", "", 56, '#', "", 51, 51, "%s", QX_FLAG_SKIP, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_process_ratings_bits }, *//* Reserved */ + { "output.voltage.nominal", 0, NULL, "QS\r", "", 56, '#', "", 52, 54, "%.1f", QX_FLAG_SKIP, NULL, voltronic_qs_hex_preprocess_qs_answer, voltronic_qs_hex_process_ratings_bits }, /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, voltronic_qs_hex_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, voltronic_qs_hex_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, voltronic_qs_hex_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, voltronic_qs_hex_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; @@ -119,14 +126,11 @@ static testing_t voltronic_qs_hex_testing[] = { { "QS\r", "#\x6C\x01 \x35 \x6C\x01 \x35 \x03 \x51\x9A \x28\x02\x12\xD0 \xE6 \x1E \x09\r", 27 }, { "M\r", "P\r", -1 }, { "Q\r", "", -1 }, - { "S03\r", "", -1 }, + { "S00R0000\r", "", -1 }, { "C\r", "", -1 }, { "S02R0005\r", "", -1 }, { "S.5R0000\r", "N\r", -1 }, - { "T04\r", "", -1 }, - { "TL\r", "", -1 }, { "T\r", "", -1 }, - { "CT\r", "", -1 }, { NULL } }; #endif /* TESTING */ @@ -235,10 +239,10 @@ static int voltronic_qs_hex_preprocess_qs_answer(item_t *item, const int len) snprintfcat(refined, sizeof(refined), "%02x", 0x20); break; default: - if (token != 10) + if (token != 10 && token != 11) snprintfcat(refined, sizeof(refined), "%02x", ((unsigned char *)item->answer)[i]); else - snprintfcat(refined, sizeof(refined), "%08d", voltronic_qs_hex_status_char_to_binary(((unsigned char *)item->answer)[i])); + snprintfcat(refined, sizeof(refined), "%08d", voltronic_qs_hex_char_to_binary(((unsigned char *)item->answer)[i])); continue; } @@ -251,14 +255,19 @@ static int voltronic_qs_hex_preprocess_qs_answer(item_t *item, const int len) if (item->answer[i] == 0x0D) break; - if (token != 10) + if (token != 10 && token != 11) snprintfcat(refined, sizeof(refined), "%02x", ((unsigned char *)item->answer)[i]); else - snprintfcat(refined, sizeof(refined), "%08d", voltronic_qs_hex_status_char_to_binary(((unsigned char *)item->answer)[i])); + snprintfcat(refined, sizeof(refined), "%08d", voltronic_qs_hex_char_to_binary(((unsigned char *)item->answer)[i])); } - if (token != 10 || strlen(refined) != 46) { + if ( + token < 10 || + token > 11 || + (token == 10 && strlen(refined) != 46) || + (token == 11 && strlen(refined) != 55) + ) { upsdebugx(2, "noncompliant reply: %s", refined); return -1; } @@ -269,8 +278,8 @@ static int voltronic_qs_hex_preprocess_qs_answer(item_t *item, const int len) return snprintf(item->answer, sizeof(item->answer), "%s\r", refined); } -/* Transform the QS 'status' char into its binary form (as an int) */ -static int voltronic_qs_hex_status_char_to_binary(const unsigned char value) +/* Transform a char into its binary form (as an int) */ +static int voltronic_qs_hex_char_to_binary(const unsigned char value) { unsigned char remainder = value; int ret = 0, @@ -293,39 +302,51 @@ static int voltronic_qs_hex_status_char_to_binary(const unsigned char value) /* == Preprocess functions == */ /* Protocol used by the UPS */ -static int voltronic_qs_hex_protocol(item_t *item, char *value, size_t valuelen) +static int voltronic_qs_hex_protocol(item_t *item, char *value, const size_t valuelen) { item_t *unskip; + int i; + const struct { + const char *info_type; /* info_type of the item to be unskipped */ + const unsigned long flags; /* qxflags that have to be set in the item */ + const unsigned long noflags; /* qxflags that have to be absent in the item */ + } items_to_be_unskipped[] = { + { "test.battery.start.quick", QX_FLAG_CMD, 0 }, + { "output.frequency.nominal", 0, 0 }, + { "battery.voltage.nominal", 0, 0 }, + { "output.voltage.nominal", 0, 0 }, + { NULL, 0, 0 } + }; - if (strcasecmp(item->value, "P") && strcasecmp(item->value, "T") && strcasecmp(item->value, "V")) { + if (strcasecmp(item->value, "P") && strcasecmp(item->value, "T")) { upsdebugx(2, "%s: invalid protocol [%s]", __func__, item->value); return -1; } snprintf(value, valuelen, item->dfl, item->value); - /* 'P' UPSes don't support 'T\r' command (battery test) -> leave test.battery.start.quick skipped */ + /* Unskip items supported only by devices that implement 'T' protocol */ + if (!strcasecmp(item->value, "P")) return 0; - /* Unskip test.battery.start.quick */ - unskip = find_nut_info("test.battery.start.quick", QX_FLAG_CMD, 0); - - /* Don't know what happened */ - if (!unskip) - return -1; - - unskip->qxflags &= ~QX_FLAG_SKIP; + for (i = 0; items_to_be_unskipped[i].info_type; i++) { + unskip = find_nut_info(items_to_be_unskipped[i].info_type, items_to_be_unskipped[i].flags, items_to_be_unskipped[i].noflags); + /* Don't know what happened */ + if (!unskip) + return -1; + unskip->qxflags &= ~QX_FLAG_SKIP; + } return 0; } /* Input/Output voltage */ -int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, size_t valuelen) +static int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, const size_t valuelen) { int val; double ret; - char *str_end, buf[SMALLBUF] = ""; + char *str_end; if (strspn(item->value, "0123456789ABCDEFabcdef ") != strlen(item->value)) { upsdebugx(2, "%s: non numerical value [%s: %s]", __func__, item->info_type, item->value); @@ -333,11 +354,7 @@ int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, size_t valu } val = strtol(item->value, &str_end, 16) * strtol(str_end, NULL, 16) / 51; - snprintf(buf, sizeof(buf), "%06x", val); - - ret = strtol(buf + 4, NULL, 16) / 256.0; - buf[4] = '\0'; - ret += strtol(buf, NULL, 16); + ret = val / 256.0; snprintf(value, valuelen, item->dfl, ret); @@ -345,7 +362,7 @@ int voltronic_qs_hex_input_output_voltage(item_t *item, char *value, size_t valu } /* Device load */ -int voltronic_qs_hex_load(item_t *item, char *value, size_t valuelen) +static int voltronic_qs_hex_load(item_t *item, char *value, const size_t valuelen) { if (strspn(item->value, "0123456789ABCDEFabcdef") != strlen(item->value)) { upsdebugx(2, "%s: non numerical value [%s: %s]", __func__, item->info_type, item->value); @@ -358,7 +375,7 @@ int voltronic_qs_hex_load(item_t *item, char *value, size_t valuelen) } /* Output frequency */ -int voltronic_qs_hex_frequency(item_t *item, char *value, size_t valuelen) +static int voltronic_qs_hex_frequency(item_t *item, char *value, const size_t valuelen) { double val1, val2, ret; char *str_end; @@ -380,7 +397,7 @@ int voltronic_qs_hex_frequency(item_t *item, char *value, size_t valuelen) } /* Battery voltage */ -int voltronic_qs_hex_battery_voltage(item_t *item, char *value, size_t valuelen) +static int voltronic_qs_hex_battery_voltage(item_t *item, char *value, const size_t valuelen) { int val1, val2; char *str_end; @@ -398,6 +415,74 @@ int voltronic_qs_hex_battery_voltage(item_t *item, char *value, size_t valuelen) return 0; } +/* Ratings bits */ +static int voltronic_qs_hex_process_ratings_bits(item_t *item, char *value, const size_t valuelen) +{ + int val; + double ret; + + if (strspn(item->value, "01") != strlen(item->value)) { + upsdebugx(3, "%s: unexpected value %s@%d->%s", __func__, item->info_type, item->from, item->value); + return -1; + } + + val = strtol(item->value, NULL, 10); + + switch (item->from) + { + case 47: /* Nominal output frequency */ + if (val == 0) /* 0 -> 50 Hz */ + ret = 50; + else /* 1 -> 60 Hz */ + ret = 60; + break; + case 48: /* Nominal battery voltage */ + if (val == 0) /* 0 -> 12 V */ + ret = 12; + else if (val == 1) /* 1 -> 24 V */ + ret = 24; + else if (val == 10) /* 10 -> 36 V */ + ret = 36; + else /* 11 -> 48 V */ + ret = 48; + break; +/* case 50: *//* Reserved */ +/* break;*/ +/* case 51: *//* Reserved */ +/* break;*/ + case 52: /* Nominal output voltage */ + switch (val) + { + case 0: + ret = 110; + break; + case 1: + ret = 120; + break; + case 10: + ret = 220; + break; + case 11: + ret = 230; + break; + case 100: + ret = 240; + break; + default: + /* Unknown */ + return -1; + } + break; + default: + /* Don't know what happened */ + return -1; + } + + snprintf(value, valuelen, item->dfl, ret); + + return 0; +} + /* == Subdriver interface == */ subdriver_t voltronic_qs_hex_subdriver = { diff --git a/drivers/nutdrv_qx_voltronic-qs.c b/drivers/nutdrv_qx_voltronic-qs.c index fca3ed8..4437925 100644 --- a/drivers/nutdrv_qx_voltronic-qs.c +++ b/drivers/nutdrv_qx_voltronic-qs.c @@ -25,14 +25,14 @@ #include "nutdrv_qx_voltronic-qs.h" -#define VOLTRONIC_QS_VERSION "Voltronic-QS 0.04" +#define VOLTRONIC_QS_VERSION "Voltronic-QS 0.07" /* Support functions */ static int voltronic_qs_claim(void); static void voltronic_qs_initups(void); /* Preprocess functions */ -static int voltronic_qs_protocol(item_t *item, char *value, size_t valuelen); +static int voltronic_qs_protocol(item_t *item, char *value, const size_t valuelen); /* == Ranges == */ @@ -62,7 +62,7 @@ static item_t voltronic_qs_qx2nut[] = { * 0 */ - { "ups.firmware.aux", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "%s", QX_FLAG_STATIC, NULL, voltronic_qs_protocol }, + { "ups.firmware.aux", 0, NULL, "M\r", "", 2, 0, "", 0, 0, "PM-%s", QX_FLAG_STATIC, NULL, NULL, voltronic_qs_protocol }, /* Query UPS for status * > [QS\r] @@ -71,50 +71,50 @@ static item_t voltronic_qs_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "QS\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "QS\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "QS\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "QS\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "QS\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "QS\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "QS\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "QS\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "QS\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "QS\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "QS\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "output.frequency", 0, NULL, "QS\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "QS\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "QS\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "QS\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "QS\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "QS\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "QS\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "QS\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "QS\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "QS\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* Query UPS for ratings * > [F\r] - * < [#220.0 000 024.0 50.0\r] + * < [#220.0 003 12.00 50.0\r] * 0123456789012345678901 * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL }, + { "output.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "output.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "output.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, voltronic_qs_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, voltronic_qs_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, voltronic_qs_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, voltronic_qs_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; @@ -122,7 +122,7 @@ static item_t voltronic_qs_qx2nut[] = { #ifdef TESTING static testing_t voltronic_qs_testing[] = { { "QS\r", "(215.0 195.0 230.0 014 49.0 22.7 30.0 00000000\r", -1 }, - { "F\r", "#230.0 000 024.0 50.0\r", -1 }, + { "F\r", "#220.0 003 12.00 50.0\r", -1 }, { "M\r", "V\r", -1 }, { "Q\r", "", -1 }, { "C\r", "", -1 }, @@ -189,14 +189,14 @@ static void voltronic_qs_initups(void) /* == Preprocess functions == */ /* Protocol used by the UPS */ -static int voltronic_qs_protocol(item_t *item, char *value, size_t valuelen) +static int voltronic_qs_protocol(item_t *item, char *value, const size_t valuelen) { if (strcasecmp(item->value, "V")) { upsdebugx(2, "%s: invalid protocol [%s]", __func__, item->value); return -1; } - snprintf(value, valuelen, item->dfl, "PMV"); + snprintf(value, valuelen, item->dfl, item->value); return 0; } @@ -210,8 +210,8 @@ subdriver_t voltronic_qs_subdriver = { voltronic_qs_initups, NULL, blazer_makevartable_light, - "ACK", - "(NAK\r", + NULL, + NULL, #ifdef TESTING voltronic_qs_testing, #endif /* TESTING */ diff --git a/drivers/nutdrv_qx_voltronic.c b/drivers/nutdrv_qx_voltronic.c index adfb6b1..3ab33a6 100644 --- a/drivers/nutdrv_qx_voltronic.c +++ b/drivers/nutdrv_qx_voltronic.c @@ -24,7 +24,7 @@ #include "nutdrv_qx_voltronic.h" -#define VOLTRONIC_VERSION "Voltronic 0.03" +#define VOLTRONIC_VERSION "Voltronic 0.06" /* Support functions */ static int voltronic_claim(void); @@ -32,44 +32,44 @@ static void voltronic_makevartable(void); static void voltronic_massive_unskip(const int protocol); /* Range/enum functions */ -static int voltronic_batt_low(char *value, size_t len); -static int voltronic_bypass_volt_max(char *value, size_t len); -static int voltronic_bypass_volt_min(char *value, size_t len); -static int voltronic_bypass_freq_max(char *value, size_t len); -static int voltronic_bypass_freq_min(char *value, size_t len); -static int voltronic_eco_freq_min(char *value, size_t len); -static int voltronic_eco_freq_max(char *value, size_t len); +static int voltronic_batt_low(char *value, const size_t len); +static int voltronic_bypass_volt_max(char *value, const size_t len); +static int voltronic_bypass_volt_min(char *value, const size_t len); +static int voltronic_bypass_freq_max(char *value, const size_t len); +static int voltronic_bypass_freq_min(char *value, const size_t len); +static int voltronic_eco_freq_min(char *value, const size_t len); +static int voltronic_eco_freq_max(char *value, const size_t len); /* Preprocess functions */ -static int voltronic_process_setvar(item_t *item, char *value, size_t valuelen); -static int voltronic_process_command(item_t *item, char *value, size_t valuelen); -static int voltronic_capability(item_t *item, char *value, size_t valuelen); -static int voltronic_capability_set(item_t *item, char *value, size_t valuelen); -static int voltronic_capability_set_nonut(item_t *item, char *value, size_t valuelen); -static int voltronic_capability_reset(item_t *item, char *value, size_t valuelen); -static int voltronic_eco_volt(item_t *item, char *value, size_t valuelen); -static int voltronic_eco_volt_range(item_t *item, char *value, size_t valuelen); -static int voltronic_eco_freq(item_t *item, char *value, size_t valuelen); -static int voltronic_bypass(item_t *item, char *value, size_t valuelen); -static int voltronic_batt_numb(item_t *item, char *value, size_t valuelen); -static int voltronic_batt_runtime(item_t *item, char *value, size_t valuelen); -static int voltronic_protocol(item_t *item, char *value, size_t valuelen); -static int voltronic_fault(item_t *item, char *value, size_t valuelen); -static int voltronic_warning(item_t *item, char *value, size_t valuelen); -static int voltronic_mode(item_t *item, char *value, size_t valuelen); -static int voltronic_status(item_t *item, char *value, size_t valuelen); -static int voltronic_output_powerfactor(item_t *item, char *value, size_t valuelen); -static int voltronic_serial_numb(item_t *item, char *value, size_t valuelen); -static int voltronic_outlet(item_t *item, char *value, size_t valuelen); -static int voltronic_outlet_delay(item_t *item, char *value, size_t valuelen); -static int voltronic_outlet_delay_set(item_t *item, char *value, size_t valuelen); -static int voltronic_p31b(item_t *item, char *value, size_t valuelen); -static int voltronic_p31b_set(item_t *item, char *value, size_t valuelen); -static int voltronic_p31g(item_t *item, char *value, size_t valuelen); -static int voltronic_p31g_set(item_t *item, char *value, size_t valuelen); -static int voltronic_phase(item_t *item, char *value, size_t valuelen); -static int voltronic_phase_set(item_t *item, char *value, size_t valuelen); -static int voltronic_parallel(item_t *item, char *value, size_t valuelen); +static int voltronic_process_setvar(item_t *item, char *value, const size_t valuelen); +static int voltronic_process_command(item_t *item, char *value, const size_t valuelen); +static int voltronic_capability(item_t *item, char *value, const size_t valuelen); +static int voltronic_capability_set(item_t *item, char *value, const size_t valuelen); +static int voltronic_capability_set_nonut(item_t *item, char *value, const size_t valuelen); +static int voltronic_capability_reset(item_t *item, char *value, const size_t valuelen); +static int voltronic_eco_volt(item_t *item, char *value, const size_t valuelen); +static int voltronic_eco_volt_range(item_t *item, char *value, const size_t valuelen); +static int voltronic_eco_freq(item_t *item, char *value, const size_t valuelen); +static int voltronic_bypass(item_t *item, char *value, const size_t valuelen); +static int voltronic_batt_numb(item_t *item, char *value, const size_t valuelen); +static int voltronic_batt_runtime(item_t *item, char *value, const size_t valuelen); +static int voltronic_protocol(item_t *item, char *value, const size_t valuelen); +static int voltronic_fault(item_t *item, char *value, const size_t valuelen); +static int voltronic_warning(item_t *item, char *value, const size_t valuelen); +static int voltronic_mode(item_t *item, char *value, const size_t valuelen); +static int voltronic_status(item_t *item, char *value, const size_t valuelen); +static int voltronic_output_powerfactor(item_t *item, char *value, const size_t valuelen); +static int voltronic_serial_numb(item_t *item, char *value, const size_t valuelen); +static int voltronic_outlet(item_t *item, char *value, const size_t valuelen); +static int voltronic_outlet_delay(item_t *item, char *value, const size_t valuelen); +static int voltronic_outlet_delay_set(item_t *item, char *value, const size_t valuelen); +static int voltronic_p31b(item_t *item, char *value, const size_t valuelen); +static int voltronic_p31b_set(item_t *item, char *value, const size_t valuelen); +static int voltronic_p31g(item_t *item, char *value, const size_t valuelen); +static int voltronic_p31g_set(item_t *item, char *value, const size_t valuelen); +static int voltronic_phase(item_t *item, char *value, const size_t valuelen); +static int voltronic_phase_set(item_t *item, char *value, const size_t valuelen); +static int voltronic_parallel(item_t *item, char *value, const size_t valuelen); /* Capability vars */ static char *bypass_alarm, @@ -129,7 +129,7 @@ static info_rw_t voltronic_r_batt_low[] = { }; /* Preprocess range value for battery low voltage */ -static int voltronic_batt_low(char *value, size_t len) +static int voltronic_batt_low(char *value, const size_t len) { int val = strtol(value, NULL, 10); const char *ovn = dstate_getinfo("output.voltage.nominal"), @@ -209,7 +209,7 @@ static info_rw_t voltronic_r_bypass_volt_max[] = { }; /* Preprocess range value for Bypass Mode maximum voltage */ -static int voltronic_bypass_volt_max(char *value, size_t len) +static int voltronic_bypass_volt_max(char *value, const size_t len) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10), val = strtol(value, NULL, 10), @@ -363,7 +363,7 @@ static info_rw_t voltronic_r_bypass_volt_min[] = { }; /* Preprocess range value for Bypass Mode minimum voltage */ -static int voltronic_bypass_volt_min(char *value, size_t len) +static int voltronic_bypass_volt_min(char *value, const size_t len) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10), val = strtol(value, NULL, 10), @@ -509,7 +509,7 @@ static info_rw_t voltronic_r_bypass_freq_max[] = { }; /* Preprocess range value for Bypass Mode maximum frequency */ -static int voltronic_bypass_freq_max(char *value, size_t len) +static int voltronic_bypass_freq_max(char *value, const size_t len) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10), val = strtol(value, NULL, 10); @@ -607,7 +607,7 @@ static info_rw_t voltronic_r_bypass_freq_min[] = { }; /* Preprocess range value for Bypass Mode minimum frequency */ -static int voltronic_bypass_freq_min(char *value, size_t len) +static int voltronic_bypass_freq_min(char *value, const size_t len) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10), val = strtol(value, NULL, 10); @@ -721,7 +721,7 @@ static info_rw_t voltronic_r_eco_freq_min[] = { }; /* Preprocess range value for ECO Mode minimum frequency */ -static int voltronic_eco_freq_min(char *value, size_t len) +static int voltronic_eco_freq_min(char *value, const size_t len) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10), val = strtol(value, NULL, 10); @@ -841,7 +841,7 @@ static info_rw_t voltronic_r_eco_freq_max[] = { }; /* Preprocess range value for ECO Mode maximum frequency */ -static int voltronic_eco_freq_max(char *value, size_t len) +static int voltronic_eco_freq_max(char *value, const size_t len) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10), val = strtol(value, NULL, 10); @@ -972,7 +972,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "ups.firmware.aux", 0, NULL, "QPI\r", "", 6, '(', "", 1, 4, "%s", QX_FLAG_STATIC, NULL, voltronic_protocol }, + { "ups.firmware.aux", 0, NULL, "QPI\r", "", 6, '(', "", 1, 4, "%s", QX_FLAG_STATIC, NULL, NULL, voltronic_protocol }, /* Query UPS for ratings * > [QRI\r] @@ -981,10 +981,10 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 */ - { "output.voltage.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 1, 5, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "output.current.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 7, 9, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 11, 15, "%.1f", QX_FLAG_SEMI_STATIC, NULL, NULL }, /* as *per battery pack*: the value will change when the number of batteries is changed (battery_number through BATNn) */ - { "output.frequency.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 17, 20, "%.1f", QX_FLAG_STATIC, NULL, NULL }, + { "output.voltage.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 1, 5, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "output.current.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 7, 9, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 11, 15, "%.1f", QX_FLAG_SEMI_STATIC, NULL, NULL, NULL }, /* as *per battery pack*: the value will change when the number of batteries is changed (battery_number through BATNn) */ + { "output.frequency.nominal", 0, NULL, "QRI\r", "", 22, '(', "", 17, 20, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* Query UPS for ratings * > [QMD\r] @@ -993,15 +993,15 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 3 4 */ - { "device.model", 0, NULL, "QMD\r", "", 48, '(', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.power.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 17, 23, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "output.powerfactor", 0, NULL, "QMD\r", "", 48, '(', "", 25, 26, "%.1f", QX_FLAG_STATIC, NULL, voltronic_output_powerfactor }, - { "input.phases", 0, NULL, "QMD\r", "", 48, '(', "", 28, 28, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "output.phases", 0, NULL, "QMD\r", "", 48, '(', "", 30, 30, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.voltage.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 32, 34, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "output.voltage.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 36, 38, "%.1f", QX_FLAG_STATIC, NULL, NULL }, /* redundant with value from QRI */ -/* { "battery_number", ST_FLAG_RW, voltronic_r_batt_numb, "QMD\r", "", 48, '(', "", 40, 41, "%d", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, voltronic_batt_numb }, *//* redundant with value from QBV */ -/* { "battery.voltage.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 43, 46, "%.1f", QX_FLAG_STATIC, NULL, NULL }, *//* as *per battery* vs *per pack* reported by QRI */ + { "device.model", 0, NULL, "QMD\r", "", 48, '(', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.power.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 17, 23, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "output.powerfactor", 0, NULL, "QMD\r", "", 48, '(', "", 25, 26, "%.1f", QX_FLAG_STATIC, NULL, NULL, voltronic_output_powerfactor }, + { "input.phases", 0, NULL, "QMD\r", "", 48, '(', "", 28, 28, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "output.phases", 0, NULL, "QMD\r", "", 48, '(', "", 30, 30, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 32, 34, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "output.voltage.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 36, 38, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* redundant with value from QRI */ +/* { "battery_number", ST_FLAG_RW, voltronic_r_batt_numb, "QMD\r", "", 48, '(', "", 40, 41, "%d", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, NULL, voltronic_batt_numb }, *//* redundant with value from QBV */ +/* { "battery.voltage.nominal", 0, NULL, "QMD\r", "", 48, '(', "", 43, 46, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, *//* as *per battery* vs *per pack* reported by QRI */ /* Query UPS for ratings * > [F\r] @@ -1010,10 +1010,10 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.1f", QX_FLAG_STATIC, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* Query UPS for manufacturer * > [QMF\r] @@ -1022,7 +1022,7 @@ static item_t voltronic_qx2nut[] = { * 0 1 */ - { "device.mfr", 0, NULL, "QMF\r", "", 2, '(', "", 1, 0, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "QMF\r", "", 2, '(', "", 1, 0, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Query UPS for firmware version * > [QVFW\r] @@ -1031,7 +1031,7 @@ static item_t voltronic_qx2nut[] = { * 0 1 */ - { "ups.firmware", 0, NULL, "QVFW\r", "", 16, '(', "", 7, 14, "%s", QX_FLAG_STATIC, NULL, NULL }, + { "ups.firmware", 0, NULL, "QVFW\r", "", 16, '(', "", 7, 14, "%s", QX_FLAG_STATIC, NULL, NULL, NULL }, /* Query UPS for serial number * > [QID\r] @@ -1040,7 +1040,7 @@ static item_t voltronic_qx2nut[] = { * 0 1 */ - { "device.serial", 0, NULL, "QID\r", "", 2, '(', "", 1, 0, "%s", QX_FLAG_STATIC, NULL, voltronic_serial_numb }, + { "device.serial", 0, NULL, "QID\r", "", 2, '(', "", 1, 0, "%s", QX_FLAG_STATIC, NULL, NULL, voltronic_serial_numb }, /* Query UPS for vendor infos * > [I\r] @@ -1049,9 +1049,9 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 3 */ - { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "I\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "device.model", 0, NULL, "I\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.firmware", 0, NULL, "I\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Query UPS for status * > [QGS\r] @@ -1060,29 +1060,29 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 3 4 5 6 7 */ - { "input.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "QGS\r", "", 76, '(', "", 7, 10, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 12, 16, "%.1f", 0, NULL, NULL }, - { "output.frequency", 0, NULL, "QGS\r", "", 76, '(', "", 18, 21, "%.1f", 0, NULL, NULL }, - { "output.current", 0, NULL, "QGS\r", "", 76, '(', "", 23, 27, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "QGS\r", "", 76, '(', "", 29, 31, "%.0f", 0, NULL, NULL }, -/* { "unknown.1", 0, NULL, "QGS\r", "", 76, '(', "", 33, 37, "%.1f", 0, NULL, NULL }, *//* Unknown */ -/* { "unknown.2", 0, NULL, "QGS\r", "", 76, '(', "", 39, 43, "%.1f", 0, NULL, NULL }, *//* Unknown */ - { "battery.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 45, 49, "%.2f", 0, NULL, NULL }, -/* { "unknown.3", 0, NULL, "QGS\r", "", 76, '(', "", 51, 55, "%.1f", 0, NULL, NULL }, *//* Unknown */ - { "ups.temperature", 0, NULL, "QGS\r", "", 76, '(', "", 57, 61, "%.1f", 0, NULL, NULL }, - { "ups.type", 0, NULL, "QGS\r", "", 76, '(', "", 63, 64, "%s", QX_FLAG_SEMI_STATIC, NULL, voltronic_status }, - { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 65, 65, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 66, 66, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status }, /* Battery Low */ - { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 67, 67, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "QGS\r", "", 76, '(', "", 67, 67, "%s", 0, NULL, voltronic_status }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "QGS\r", "", 76, '(', "", 68, 68, "%s", 0, NULL, voltronic_status }, /* UPS Fault */ -/* { "unknown.4", 0, NULL, "QGS\r", "", 76, '(', "", 69, 69, "%s", 0, NULL, voltronic_status }, *//* Unknown */ - { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 70, 70, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status }, /* Test in Progress */ - { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 71, 71, "%s", QX_FLAG_QUICK_POLL, NULL, voltronic_status }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "QGS\r", "", 76, '(', "", 72, 72, "%s", 0, NULL, voltronic_status }, /* Beeper status - ups.beeper.status */ -/* { "unknown.5", 0, NULL, "QGS\r", "", 76, '(', "", 73, 73, "%s", 0, NULL, voltronic_status }, *//* Unknown */ -/* { "unknown.6", 0, NULL, "QGS\r", "", 76, '(', "", 74, 74, "%s", 0, NULL, voltronic_status }, *//* Unknown */ + { "input.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "QGS\r", "", 76, '(', "", 7, 10, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 12, 16, "%.1f", 0, NULL, NULL, NULL }, + { "output.frequency", 0, NULL, "QGS\r", "", 76, '(', "", 18, 21, "%.1f", 0, NULL, NULL, NULL }, + { "output.current", 0, NULL, "QGS\r", "", 76, '(', "", 23, 27, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "QGS\r", "", 76, '(', "", 29, 31, "%.0f", 0, NULL, NULL, NULL }, +/* { "unknown.1", 0, NULL, "QGS\r", "", 76, '(', "", 33, 37, "%.1f", 0, NULL, NULL, NULL }, *//* Unknown */ +/* { "unknown.2", 0, NULL, "QGS\r", "", 76, '(', "", 39, 43, "%.1f", 0, NULL, NULL, NULL }, *//* Unknown */ + { "battery.voltage", 0, NULL, "QGS\r", "", 76, '(', "", 45, 49, "%.2f", 0, NULL, NULL, NULL }, +/* { "unknown.3", 0, NULL, "QGS\r", "", 76, '(', "", 51, 55, "%.1f", 0, NULL, NULL, NULL }, *//* Unknown */ + { "ups.temperature", 0, NULL, "QGS\r", "", 76, '(', "", 57, 61, "%.1f", 0, NULL, NULL, NULL }, + { "ups.type", 0, NULL, "QGS\r", "", 76, '(', "", 63, 64, "%s", QX_FLAG_SEMI_STATIC, NULL, NULL, voltronic_status }, + { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 65, 65, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 66, 66, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status }, /* Battery Low */ + { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 67, 67, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "QGS\r", "", 76, '(', "", 67, 67, "%s", 0, NULL, NULL, voltronic_status }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "QGS\r", "", 76, '(', "", 68, 68, "%s", 0, NULL, NULL, voltronic_status }, /* UPS Fault */ +/* { "unknown.4", 0, NULL, "QGS\r", "", 76, '(', "", 69, 69, "%s", 0, NULL, NULL, voltronic_status }, *//* Unknown */ + { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 70, 70, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status }, /* Test in Progress */ + { "ups.status", 0, NULL, "QGS\r", "", 76, '(', "", 71, 71, "%s", QX_FLAG_QUICK_POLL, NULL, NULL, voltronic_status }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "QGS\r", "", 76, '(', "", 72, 72, "%s", 0, NULL, NULL, voltronic_status }, /* Beeper status - ups.beeper.status */ +/* { "unknown.5", 0, NULL, "QGS\r", "", 76, '(', "", 73, 73, "%s", 0, NULL, NULL, voltronic_status }, *//* Unknown */ +/* { "unknown.6", 0, NULL, "QGS\r", "", 76, '(', "", 74, 74, "%s", 0, NULL, NULL, voltronic_status }, *//* Unknown */ /* Query UPS for actual working mode * > [QMOD\r] @@ -1091,8 +1091,8 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "ups.alarm", 0, NULL, "QMOD\r", "", 3, '(', "", 1, 1, "%s", 0, NULL, voltronic_mode }, - { "ups.status", 0, NULL, "QMOD\r", "", 3, '(', "", 1, 1, "%s", 0, NULL, voltronic_mode }, + { "ups.alarm", 0, NULL, "QMOD\r", "", 3, '(', "", 1, 1, "%s", 0, NULL, NULL, voltronic_mode }, + { "ups.status", 0, NULL, "QMOD\r", "", 3, '(', "", 1, 1, "%s", 0, NULL, NULL, voltronic_mode }, /* Query UPS for faults and their type. Unskipped when a fault is found in 12bit flag of QGS, otherwise you'll get a fake reply. * > [QFS\r] @@ -1104,7 +1104,7 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 3 4 5 6 */ - { "ups.alarm", 0, NULL, "QFS\r", "", 4, '(', "", 1, 2, "%s", QX_FLAG_SKIP, NULL, voltronic_fault }, + { "ups.alarm", 0, NULL, "QFS\r", "", 4, '(', "", 1, 2, "%s", QX_FLAG_SKIP, NULL, NULL, voltronic_fault }, /* Query UPS for warnings and their type * > [QWS\r] @@ -1113,7 +1113,7 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 3 4 5 6 */ - { "ups.alarm", 0, NULL, "QWS\r", "", 66, '(', "", 1, 64, "%s", 0, NULL, voltronic_warning }, + { "ups.alarm", 0, NULL, "QWS\r", "", 66, '(', "", 1, 64, "%s", 0, NULL, NULL, voltronic_warning }, /* Query UPS for actual infos about battery * > [QBV\r] @@ -1122,11 +1122,11 @@ static item_t voltronic_qx2nut[] = { * 0 1 2 */ - { "battery.voltage", 0, NULL, "QBV\r", "", 21, '(', "", 1, 5, "%.2f", 0, NULL, NULL }, - { "battery_number", ST_FLAG_RW, voltronic_r_batt_numb, "QBV\r", "", 21, '(', "", 7, 9, "%d", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, voltronic_batt_numb }, /* Number of batteries that make a pack */ - { "battery.packs", ST_FLAG_RW, voltronic_r_batt_packs, "QBV\r", "", 21, '(', "", 10, 11, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE, NULL, NULL }, /* Number of battery packs in parallel */ - { "battery.charge", 0, NULL, "QBV\r", "", 21, '(', "", 13, 15, "%.0f", 0, NULL, NULL }, - { "battery.runtime", 0, NULL, "QBV\r", "", 21, '(', "", 17, 19, "%.0f", 0, NULL, voltronic_batt_runtime }, + { "battery.voltage", 0, NULL, "QBV\r", "", 21, '(', "", 1, 5, "%.2f", 0, NULL, NULL, NULL }, + { "battery_number", ST_FLAG_RW, voltronic_r_batt_numb, "QBV\r", "", 21, '(', "", 7, 9, "%d", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, NULL, voltronic_batt_numb }, /* Number of batteries that make a pack */ + { "battery.packs", ST_FLAG_RW, voltronic_r_batt_packs, "QBV\r", "", 21, '(', "", 10, 11, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE, NULL, NULL, NULL }, /* Number of battery packs in parallel */ + { "battery.charge", 0, NULL, "QBV\r", "", 21, '(', "", 13, 15, "%.0f", 0, NULL, NULL, NULL }, + { "battery.runtime", 0, NULL, "QBV\r", "", 21, '(', "", 17, 19, "%.0f", 0, NULL, NULL, voltronic_batt_runtime }, /* Query UPS for last seen min/max load level * > [QLDL\r] @@ -1135,8 +1135,8 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "output.power.minimum.percent", 0, NULL, "QLDL\r", "", 9, '(', "", 1, 3, "%.0f", 0, NULL, NULL }, - { "output.power.maximum.percent", 0, NULL, "QLDL\r", "", 9, '(', "", 5, 7, "%.0f", 0, NULL, NULL }, + { "output.power.minimum.percent", 0, NULL, "QLDL\r", "", 9, '(', "", 1, 3, "%.0f", 0, NULL, NULL, NULL }, + { "output.power.maximum.percent", 0, NULL, "QLDL\r", "", 9, '(', "", 5, 7, "%.0f", 0, NULL, NULL, NULL }, /* Query UPS for multi-phase voltages/frequencies * > [Q3**\r] @@ -1169,50 +1169,50 @@ static item_t voltronic_qx2nut[] = { */ /* From Q3PV */ - { "input.L1-N.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L2-N.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L3-N.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L1-L2.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 19, 23, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L2-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L1-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL }, -/* { "input.L1-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ -/* { "input.L2-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ + { "input.L1-N.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L2-N.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L3-N.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L1-L2.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 19, 23, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L2-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L1-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, +/* { "input.L1-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ +/* { "input.L2-L3.voltage", 0, NULL, "Q3PV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ /* From Q3PC */ - { "input.L1.current", 0, NULL, "Q3PC\r", "", 13, '(', "", 1, 3, "%.0f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L2.current", 0, NULL, "Q3PC\r", "", 13, '(', "", 5, 7, "%.0f", QX_FLAG_SKIP, NULL, NULL }, - { "input.L3.current", 0, NULL, "Q3PC\r", "", 13, '(', "", 9, 11, "%.0f", QX_FLAG_SKIP, NULL, NULL }, + { "input.L1.current", 0, NULL, "Q3PC\r", "", 13, '(', "", 1, 3, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L2.current", 0, NULL, "Q3PC\r", "", 13, '(', "", 5, 7, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "input.L3.current", 0, NULL, "Q3PC\r", "", 13, '(', "", 9, 11, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, /* From Q3OV */ - { "output.L1-N.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L2-N.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L3-N.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L1-L2.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 19, 23, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L2-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L1-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL }, -/* { "output.L1-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ -/* { "output.L2-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ + { "output.L1-N.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L2-N.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L3-N.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L1-L2.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 19, 23, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L2-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L1-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, +/* { "output.L1-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ +/* { "output.L2-L3.voltage", 0, NULL, "Q3OV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ /* From Q3OC */ - { "output.L1.current", 0, NULL, "Q3OC\r", "", 13, '(', "", 1, 3, "%.0f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L2.current", 0, NULL, "Q3OC\r", "", 13, '(', "", 5, 7, "%.0f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L3.current", 0, NULL, "Q3OC\r", "", 13, '(', "", 9, 11, "%.0f", QX_FLAG_SKIP, NULL, NULL }, + { "output.L1.current", 0, NULL, "Q3OC\r", "", 13, '(', "", 1, 3, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L2.current", 0, NULL, "Q3OC\r", "", 13, '(', "", 5, 7, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L3.current", 0, NULL, "Q3OC\r", "", 13, '(', "", 9, 11, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, /* From Q3LD */ - { "output.L1.power.percent", 0, NULL, "Q3LD\r", "", 13, '(', "", 1, 3, "%.0f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L2.power.percent", 0, NULL, "Q3LD\r", "", 13, '(', "", 5, 7, "%.0f", QX_FLAG_SKIP, NULL, NULL }, - { "output.L3.power.percent", 0, NULL, "Q3LD\r", "", 13, '(', "", 9, 11, "%.0f", QX_FLAG_SKIP, NULL, NULL }, + { "output.L1.power.percent", 0, NULL, "Q3LD\r", "", 13, '(', "", 1, 3, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L2.power.percent", 0, NULL, "Q3LD\r", "", 13, '(', "", 5, 7, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.L3.power.percent", 0, NULL, "Q3LD\r", "", 13, '(', "", 9, 11, "%.0f", QX_FLAG_SKIP, NULL, NULL, NULL }, /* From Q3YV */ - { "output.bypass.L1-N.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.bypass.L2-N.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.bypass.L3-N.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.bypass.L1-N.voltage", 0, NULL, "Q3YV\r", "", 19, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL }, /* P09 */ - { "output.bypass.L2-N.voltage", 0, NULL, "Q3YV\r", "", 19, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL }, /* P09 */ -/* { "output.bypass.L3-N.voltage", 0, NULL, "Q3YV\r", "", 19, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ - { "output.bypass.L1-L2.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 19, 23, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.bypass.L2-L3.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL }, - { "output.bypass.L1-L3.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL }, + { "output.bypass.L1-N.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.bypass.L2-N.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.bypass.L3-N.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.bypass.L1-N.voltage", 0, NULL, "Q3YV\r", "", 19, '(', "", 1, 5, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, /* P09 */ + { "output.bypass.L2-N.voltage", 0, NULL, "Q3YV\r", "", 19, '(', "", 7, 11, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, /* P09 */ +/* { "output.bypass.L3-N.voltage", 0, NULL, "Q3YV\r", "", 19, '(', "", 13, 17, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, *//* P09 *//* Commented out because P09 should be two-phase input/output UPSes */ + { "output.bypass.L1-L2.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 19, 23, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.bypass.L2-L3.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 25, 29, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, + { "output.bypass.L1-L3.voltage", 0, NULL, "Q3YV\r", "", 37, '(', "", 31, 35, "%.1f", QX_FLAG_SKIP, NULL, NULL, NULL }, /* Query UPS for capability - total options available: 23; only those whom the UPS is capable of are reported as Enabled or Disabled * > [QFLAG\r] @@ -1221,24 +1221,24 @@ static item_t voltronic_qx2nut[] = { * 0 1 * min length = ( + E + D + \r = 4 */ - { "ups.start.auto", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_capability }, - { "battery.protection", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_capability }, - { "battery.energysave", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_capability }, - { "ups.start.battery", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_capability }, - { "outlet.0.switchable", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, voltronic_capability }, + { "ups.start.auto", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_capability }, + { "battery.protection", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_capability }, + { "battery.energysave", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_capability }, + { "ups.start.battery", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_capability }, + { "outlet.0.switchable", ST_FLAG_RW, voltronic_e_cap, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM, NULL, NULL, voltronic_capability }, /* Not available in NUT */ - { "bypass_alarm", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "battery_alarm", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "bypass_when_off", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "alarm_control", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "converter_mode", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "eco_mode", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "battery_open_status_check", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "bypass_forbidding", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "site_fault_detection", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "advanced_eco_mode", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "constant_phase_angle", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, - { "limited_runtime_on_battery", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_capability }, + { "bypass_alarm", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "battery_alarm", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "bypass_when_off", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "alarm_control", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "converter_mode", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "eco_mode", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "battery_open_status_check", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "bypass_forbidding", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "site_fault_detection", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "advanced_eco_mode", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "constant_phase_angle", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, + { "limited_runtime_on_battery", 0, NULL, "QFLAG\r", "", 4, '(', "", 1, 0, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_capability }, /* Enable or Disable or Reset to safe default values capability options * > [PEX\r] > [PDX\r] > [PF\r] @@ -1247,25 +1247,25 @@ static item_t voltronic_qx2nut[] = { * 0 0 0 */ - { "ups.start.auto", 0, voltronic_e_cap, "P%sR\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_capability_set }, - { "battery.protection", 0, voltronic_e_cap, "P%sS\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_capability_set }, - { "battery.energysave", 0, voltronic_e_cap, "P%sG\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_capability_set }, - { "ups.start.battery", 0, voltronic_e_cap, "P%sC\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_capability_set }, - { "outlet.0.switchable", 0, voltronic_e_cap, "P%sJ\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_capability_set }, + { "ups.start.auto", 0, voltronic_e_cap, "P%sR\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set }, + { "battery.protection", 0, voltronic_e_cap, "P%sS\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set }, + { "battery.energysave", 0, voltronic_e_cap, "P%sG\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set }, + { "ups.start.battery", 0, voltronic_e_cap, "P%sC\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set }, + { "outlet.0.switchable", 0, voltronic_e_cap, "P%sJ\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set }, /* Not available in NUT */ - { "reset_to_default", 0, NULL, "PF\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_reset }, - { "bypass_alarm", 0, voltronic_e_cap_nonut, "P%sP\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "battery_alarm", 0, voltronic_e_cap_nonut, "P%sB\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "bypass_when_off", 0, voltronic_e_cap_nonut, "P%sO\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "alarm_control", 0, voltronic_e_cap_nonut, "P%sA\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "converter_mode", 0, voltronic_e_cap_nonut, "P%sV\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "eco_mode", 0, voltronic_e_cap_nonut, "P%sE\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "battery_open_status_check", 0, voltronic_e_cap_nonut, "P%sD\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "bypass_forbidding", 0, voltronic_e_cap_nonut, "P%sF\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "site_fault_detection", 0, voltronic_e_cap_nonut, "P%sL\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "advanced_eco_mode", 0, voltronic_e_cap_nonut, "P%sN\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "constant_phase_angle", 0, voltronic_e_cap_nonut, "P%sQ\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, - { "limited_runtime_on_battery", 0, voltronic_e_cap_nonut, "P%sW\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_capability_set_nonut }, + { "reset_to_default", 0, NULL, "PF\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_reset }, + { "bypass_alarm", 0, voltronic_e_cap_nonut, "P%sP\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "battery_alarm", 0, voltronic_e_cap_nonut, "P%sB\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "bypass_when_off", 0, voltronic_e_cap_nonut, "P%sO\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "alarm_control", 0, voltronic_e_cap_nonut, "P%sA\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "converter_mode", 0, voltronic_e_cap_nonut, "P%sV\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "eco_mode", 0, voltronic_e_cap_nonut, "P%sE\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "battery_open_status_check", 0, voltronic_e_cap_nonut, "P%sD\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "bypass_forbidding", 0, voltronic_e_cap_nonut, "P%sF\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "site_fault_detection", 0, voltronic_e_cap_nonut, "P%sL\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "advanced_eco_mode", 0, voltronic_e_cap_nonut, "P%sN\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "constant_phase_angle", 0, voltronic_e_cap_nonut, "P%sQ\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, + { "limited_runtime_on_battery", 0, voltronic_e_cap_nonut, "P%sW\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_capability_set_nonut }, /* Query UPS for programmable outlet (1-4) status * > [QSK1\r] @@ -1274,14 +1274,14 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "outlet.1.switchable", 0, NULL, "QSK1\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.1.status", 0, NULL, "QSK1\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.2.switchable", 0, NULL, "QSK2\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.2.status", 0, NULL, "QSK2\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.3.switchable", 0, NULL, "QSK3\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.3.status", 0, NULL, "QSK3\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.4.switchable", 0, NULL, "QSK4\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, - { "outlet.4.status", 0, NULL, "QSK4\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_outlet }, + { "outlet.1.switchable", 0, NULL, "QSK1\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.1.status", 0, NULL, "QSK1\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.2.switchable", 0, NULL, "QSK2\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.2.status", 0, NULL, "QSK2\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.3.switchable", 0, NULL, "QSK3\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.3.status", 0, NULL, "QSK3\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.4.switchable", 0, NULL, "QSK4\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, + { "outlet.4.status", 0, NULL, "QSK4\r", "", 3, '(', "", 1, 1, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet }, /* Query UPS for programmable outlet n (1-4) delay time before it shuts down the load when on battery mode * > [QSKT1\r] @@ -1290,10 +1290,10 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "outlet.1.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT1\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay }, - { "outlet.2.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT2\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay }, - { "outlet.3.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT3\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay }, - { "outlet.4.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT4\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay }, + { "outlet.1.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT1\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay }, + { "outlet.2.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT2\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay }, + { "outlet.3.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT3\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay }, + { "outlet.4.delay.shutdown", ST_FLAG_RW, voltronic_r_outlet_delay, "QSKT4\r", "", 5, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay }, /* Set delay time for programmable outlets * > [PSK1nnn\r] n = 0..9 @@ -1302,10 +1302,10 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "outlet.1.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK1%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay_set }, - { "outlet.2.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK2%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay_set }, - { "outlet.3.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK3%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay_set }, - { "outlet.4.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK4%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_outlet_delay_set }, + { "outlet.1.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK1%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay_set }, + { "outlet.2.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK2%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay_set }, + { "outlet.3.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK3%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay_set }, + { "outlet.4.delay.shutdown", 0, voltronic_r_outlet_delay, "PSK4%03d\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_outlet_delay_set }, /* Query UPS for ECO Mode voltage limits * > [QHE\r] @@ -1314,12 +1314,12 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "input.transfer.high", ST_FLAG_RW, voltronic_r_eco_volt_max, "QHE\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_eco_volt }, - { "input.transfer.low", ST_FLAG_RW, voltronic_r_eco_volt_min, "QHE\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_eco_volt }, - { "input.transfer.low.min", 0, NULL, "QHE\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_eco_volt_range }, - { "input.transfer.low.max", 0, NULL, "QHE\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_eco_volt_range }, - { "input.transfer.high.min", 0, NULL, "QHE\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_eco_volt_range }, - { "input.transfer.high.max", 0, NULL, "QHE\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, voltronic_eco_volt_range }, + { "input.transfer.high", ST_FLAG_RW, voltronic_r_eco_volt_max, "QHE\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_volt }, + { "input.transfer.low", ST_FLAG_RW, voltronic_r_eco_volt_min, "QHE\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_volt }, + { "input.transfer.low.min", 0, NULL, "QHE\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_volt_range }, + { "input.transfer.low.max", 0, NULL, "QHE\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_volt_range }, + { "input.transfer.high.min", 0, NULL, "QHE\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_volt_range }, + { "input.transfer.high.max", 0, NULL, "QHE\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_volt_range }, /* Set ECO Mode voltage limits * > [HEHnnn\r] > [HELnnn\r] n = 0..9 @@ -1328,8 +1328,8 @@ static item_t voltronic_qx2nut[] = { * 0 0 */ - { "input.transfer.high", 0, voltronic_r_eco_volt_max, "HEH%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, - { "input.transfer.low", 0, voltronic_r_eco_volt_min, "HEL%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, + { "input.transfer.high", 0, voltronic_r_eco_volt_max, "HEH%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, + { "input.transfer.low", 0, voltronic_r_eco_volt_min, "HEL%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, /* Query UPS for ECO Mode frequency limits * > [QFRE\r] @@ -1338,8 +1338,8 @@ static item_t voltronic_qx2nut[] = { * 0 1 */ - { "input.frequency.high", ST_FLAG_RW, voltronic_r_eco_freq_max, "QFRE\r", "", 11, '(', "", 1, 4, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_eco_freq }, - { "input.frequency.low", ST_FLAG_RW, voltronic_r_eco_freq_min, "QFRE\r", "", 11, '(', "", 6, 9, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_eco_freq }, + { "input.frequency.high", ST_FLAG_RW, voltronic_r_eco_freq_max, "QFRE\r", "", 11, '(', "", 1, 4, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_freq }, + { "input.frequency.low", ST_FLAG_RW, voltronic_r_eco_freq_min, "QFRE\r", "", 11, '(', "", 6, 9, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_eco_freq }, /* Set ECO Mode frequency limits * > [FREHnn.n\r] > [FRELnn.n\r] n = 0..9 @@ -1348,8 +1348,8 @@ static item_t voltronic_qx2nut[] = { * 0 0 */ - { "input.frequency.high", 0, voltronic_r_eco_freq_max, "FREH%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, - { "input.frequency.low", 0, voltronic_r_eco_freq_min, "FREL%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, + { "input.frequency.high", 0, voltronic_r_eco_freq_max, "FREH%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, + { "input.frequency.low", 0, voltronic_r_eco_freq_min, "FREL%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, /* Query UPS for Bypass Mode voltage limits * > [QBYV\r] @@ -1358,8 +1358,8 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "max_bypass_volt", ST_FLAG_RW, voltronic_r_bypass_volt_max, "QBYV\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_bypass }, - { "min_bypass_volt", ST_FLAG_RW, voltronic_r_bypass_volt_min, "QBYV\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_bypass }, + { "max_bypass_volt", ST_FLAG_RW, voltronic_r_bypass_volt_max, "QBYV\r", "", 9, '(', "", 1, 3, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_bypass }, + { "min_bypass_volt", ST_FLAG_RW, voltronic_r_bypass_volt_min, "QBYV\r", "", 9, '(', "", 5, 7, "%.0f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_bypass }, /* Set Bypass Mode voltage limits * > [PHVnnn\r] > [PLVnnn\r] n = 0..9 @@ -1368,8 +1368,8 @@ static item_t voltronic_qx2nut[] = { * 0 0 */ - { "max_bypass_volt", 0, voltronic_r_bypass_volt_max, "PHV%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, - { "min_bypass_volt", 0, voltronic_r_bypass_volt_min, "PLV%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, + { "max_bypass_volt", 0, voltronic_r_bypass_volt_max, "PHV%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, + { "min_bypass_volt", 0, voltronic_r_bypass_volt_min, "PLV%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, /* Query UPS for Bypass Mode frequency limits * > [QBYF\r] @@ -1378,8 +1378,8 @@ static item_t voltronic_qx2nut[] = { * 0 1 */ - { "max_bypass_freq", ST_FLAG_RW, voltronic_r_bypass_freq_max, "QBYF\r", "", 11, '(', "", 1, 4, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_bypass }, - { "min_bypass_freq", ST_FLAG_RW, voltronic_r_bypass_freq_min, "QBYF\r", "", 11, '(', "", 6, 9, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_bypass }, + { "max_bypass_freq", ST_FLAG_RW, voltronic_r_bypass_freq_max, "QBYF\r", "", 11, '(', "", 1, 4, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_bypass }, + { "min_bypass_freq", ST_FLAG_RW, voltronic_r_bypass_freq_min, "QBYF\r", "", 11, '(', "", 6, 9, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_bypass }, /* Set Bypass Mode frequency limits * > [PGFnn.n\r] > [PSFnn.n\r] n = 0..9 @@ -1388,8 +1388,8 @@ static item_t voltronic_qx2nut[] = { * 0 0 */ - { "max_bypass_freq", 0, voltronic_r_bypass_freq_max, "PGF%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, - { "min_bypass_freq", 0, voltronic_r_bypass_freq_min, "PSF%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_process_setvar }, + { "max_bypass_freq", 0, voltronic_r_bypass_freq_max, "PGF%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, + { "min_bypass_freq", 0, voltronic_r_bypass_freq_min, "PSF%04.1f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_process_setvar }, /* Set number of batteries that make a pack to n (integer, 1-9). NOTE: changing the number of batteries will change the UPS's estimation on battery charge/runtime * > [BATNn\r] @@ -1398,7 +1398,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "battery_number", 0, voltronic_r_batt_numb, "BATN%1.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, voltronic_process_setvar }, + { "battery_number", 0, voltronic_r_batt_numb, "BATN%1.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE | QX_FLAG_NONUT, NULL, NULL, voltronic_process_setvar }, /* Set number of battery packs in parallel to n (integer, 01-99). NOTE: changing the number of battery packs will change the UPS's estimation on battery charge/runtime * > [BATGNn\r] @@ -1407,7 +1407,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "battery.packs", 0, voltronic_r_batt_packs, "BATGN%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, voltronic_process_setvar }, + { "battery.packs", 0, voltronic_r_batt_packs, "BATGN%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, voltronic_process_setvar }, /* Query UPS for battery type (Only P31) * > [QBT\r] @@ -1416,7 +1416,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "battery.type", ST_FLAG_RW, voltronic_e_batt_type, "QBT\r", "", 4, '(', "", 1, 2, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_p31b }, + { "battery.type", ST_FLAG_RW, voltronic_e_batt_type, "QBT\r", "", 4, '(', "", 1, 2, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_p31b }, /* Set battery type (Only P31) * > [PBTnn\r] nn = 00/01/02 @@ -1425,7 +1425,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "battery.type", 0, voltronic_e_batt_type, "PBT%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, voltronic_p31b_set }, + { "battery.type", 0, voltronic_e_batt_type, "PBT%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_SKIP, NULL, NULL, voltronic_p31b_set }, /* Query UPS for device grid working range (Only P31) * > [QGR\r] @@ -1434,7 +1434,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "work_range_type", ST_FLAG_RW, voltronic_e_work_range, "QGR\r", "", 4, '(', "", 1, 2, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_p31g }, + { "work_range_type", ST_FLAG_RW, voltronic_e_work_range, "QGR\r", "", 4, '(', "", 1, 2, "%s", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_p31g }, /* Set device grid working range type (Only P31) * > [PBTnn\r] nn = 00/01 @@ -1443,7 +1443,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "work_range_type", 0, voltronic_e_work_range, "PGR%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_p31g_set }, + { "work_range_type", 0, voltronic_e_work_range, "PGR%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_p31g_set }, /* Query UPS for battery low voltage * > [RE0\r] @@ -1452,7 +1452,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "battery.voltage.low", ST_FLAG_RW, voltronic_r_batt_low, "RE0\r", "", 3, '#', "", 1, 2, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE, NULL, NULL }, + { "battery.voltage.low", ST_FLAG_RW, voltronic_r_batt_low, "RE0\r", "", 3, '#', "", 1, 2, "%.1f", QX_FLAG_SEMI_STATIC | QX_FLAG_RANGE, NULL, NULL, NULL }, /* Set voltage for battery low to n (integer, 20..24/20..28). NOTE: changing the battery low voltage will change the UPS's estimation on battery charge/runtime * > [W0En\r] @@ -1461,7 +1461,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "battery.voltage.low", 0, voltronic_r_batt_low, "W0E%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, voltronic_process_setvar }, + { "battery.voltage.low", 0, voltronic_r_batt_low, "W0E%02.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, voltronic_process_setvar }, /* Query UPS for Phase Angle * > [QPD\r] @@ -1470,8 +1470,8 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "input_phase_angle", 0, NULL, "QPD\r", "", 9, '(', "", 1, 3, "%03d", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, voltronic_phase }, - { "output_phase_angle", ST_FLAG_RW, voltronic_e_phase, "QPD\r", "", 9, '(', "", 5, 7, "%03d", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, voltronic_phase }, + { "input_phase_angle", 0, NULL, "QPD\r", "", 9, '(', "", 1, 3, "%03d", QX_FLAG_SEMI_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_phase }, + { "output_phase_angle", ST_FLAG_RW, voltronic_e_phase, "QPD\r", "", 9, '(', "", 5, 7, "%03d", QX_FLAG_SEMI_STATIC | QX_FLAG_ENUM | QX_FLAG_NONUT, NULL, NULL, voltronic_phase }, /* Set output phase angle * > [PPDn\r] n = (000, 120, 180 or 240) @@ -1480,7 +1480,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "output_phase_angle", 0, voltronic_e_phase, "PPD%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, voltronic_phase_set }, + { "output_phase_angle", 0, voltronic_e_phase, "PPD%03.0f\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_SETVAR | QX_FLAG_ENUM | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, voltronic_phase_set }, /* Query UPS for master/slave for a system of UPSes in parallel * > [QPAR\r] @@ -1489,7 +1489,7 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "voltronic_parallel", 0, NULL, "QPAR\r", "", 5, '(', "", 1, 3, "%s", QX_FLAG_STATIC | QX_FLAG_NONUT, NULL, voltronic_parallel }, + { "voltronic_parallel", 0, NULL, "QPAR\r", "", 5, '(', "", 1, 3, "%s", QX_FLAG_STATIC | QX_FLAG_NONUT, NULL, NULL, voltronic_parallel }, /* Query UPS for ?? * > [QBDR\r] @@ -1498,46 +1498,46 @@ static item_t voltronic_qx2nut[] = { * 0 */ - { "unknown.7", 0, NULL, "QBDR\r", "", 5, '(', "", 1, 0, "%s", QX_FLAG_STATIC | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL }, + { "unknown.7", 0, NULL, "QBDR\r", "", 5, '(', "", 1, 0, "%s", QX_FLAG_STATIC | QX_FLAG_NONUT | QX_FLAG_SKIP, NULL, NULL, NULL }, /* Instant commands */ - { "load.off", 0, NULL, "SOFF\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "SON\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, + { "load.off", 0, NULL, "SOFF\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "SON\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, voltronic_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, voltronic_process_command }, - { "shutdown.stop", 0, NULL, "CS\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, voltronic_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, voltronic_process_command }, + { "shutdown.stop", 0, NULL, "CS\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, voltronic_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, voltronic_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, - { "beeper.toggle", 0, NULL, "BZ%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, voltronic_process_command }, + { "beeper.toggle", 0, NULL, "BZ%s\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD, NULL, NULL, voltronic_process_command }, /* Enable/disable beeper: unskipped if the UPS can control alarm (capability) */ - { "beeper.enable", 0, NULL, "PEA\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "beeper.disable", 0, NULL, "PDA\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, + { "beeper.enable", 0, NULL, "PEA\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "beeper.disable", 0, NULL, "PDA\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, /* Outlet control: unskipped if the outlets are manageable */ - { "outlet.1.load.off", 0, NULL, "SKOFF1\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.1.load.on", 0, NULL, "SKON1\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.2.load.off", 0, NULL, "SKOFF2\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.2.load.on", 0, NULL, "SKON2\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.3.load.off", 0, NULL, "SKOFF3\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.3.load.on", 0, NULL, "SKON3\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.4.load.off", 0, NULL, "SKOFF4\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "outlet.4.load.on", 0, NULL, "SKON4\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, + { "outlet.1.load.off", 0, NULL, "SKOFF1\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.1.load.on", 0, NULL, "SKON1\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.2.load.off", 0, NULL, "SKOFF2\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.2.load.on", 0, NULL, "SKON2\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.3.load.off", 0, NULL, "SKOFF3\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.3.load.on", 0, NULL, "SKON3\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.4.load.off", 0, NULL, "SKOFF4\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "outlet.4.load.on", 0, NULL, "SKON4\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, /* Bypass: unskipped if the UPS is capable of ECO Mode */ - { "bypass.start", 0, NULL, "PEE\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, - { "bypass.stop", 0, NULL, "PDE\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL }, + { "bypass.start", 0, NULL, "PEE\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, + { "bypass.stop", 0, NULL, "PDE\r", "", 5, '(', "", 1, 3, NULL, QX_FLAG_CMD | QX_FLAG_SKIP, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, voltronic_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, voltronic_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, voltronic_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, voltronic_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, voltronic_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, voltronic_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, voltronic_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, voltronic_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; @@ -1843,14 +1843,16 @@ static void voltronic_massive_unskip(const int protocol) /* == Preprocess functions == */ /* *SETVAR(/NONUT)* Preprocess setvars */ -static int voltronic_process_setvar(item_t *item, char *value, size_t valuelen) +static int voltronic_process_setvar(item_t *item, char *value, const size_t valuelen) { + double val; + if (!strlen(value)) { upsdebugx(2, "%s: value not given for %s", __func__, item->info_type); return -1; } - double val = strtod(value, NULL); + val = strtod(value, NULL); if (!strcasecmp(item->info_type, "ups.delay.start")) { @@ -1917,7 +1919,7 @@ static int voltronic_process_setvar(item_t *item, char *value, size_t valuelen) } /* *CMD* Preprocess instant commands */ -static int voltronic_process_command(item_t *item, char *value, size_t valuelen) +static int voltronic_process_command(item_t *item, char *value, const size_t valuelen) { char buf[SMALLBUF] = ""; @@ -2049,7 +2051,7 @@ static int voltronic_process_command(item_t *item, char *value, size_t valuelen) } /* UPS capabilities */ -static int voltronic_capability(item_t *item, char *value, size_t valuelen) +static int voltronic_capability(item_t *item, char *value, const size_t valuelen) { char rawval[SMALLBUF], *enabled, *disabled, *val = NULL, *saveptr = NULL; item_t *unskip; @@ -2377,7 +2379,7 @@ static int voltronic_capability(item_t *item, char *value, size_t valuelen) } /* *SETVAR* Set UPS capability options */ -static int voltronic_capability_set(item_t *item, char *value, size_t valuelen) +static int voltronic_capability_set(item_t *item, char *value, const size_t valuelen) { if (!strcasecmp(value, "yes")) { snprintf(value, valuelen, item->command, "E"); @@ -2396,7 +2398,7 @@ static int voltronic_capability_set(item_t *item, char *value, size_t valuelen) } /* *SETVAR/NONUT* Change UPS capability according to user configuration in ups.conf */ -static int voltronic_capability_set_nonut(item_t *item, char *value, size_t valuelen) +static int voltronic_capability_set_nonut(item_t *item, char *value, const size_t valuelen) { const char *match = NULL; int i; @@ -2454,7 +2456,7 @@ static int voltronic_capability_set_nonut(item_t *item, char *value, size_t valu } /* *SETVAR/NONUT* Reset capability options and their limits to safe default values */ -static int voltronic_capability_reset(item_t *item, char *value, size_t valuelen) +static int voltronic_capability_reset(item_t *item, char *value, const size_t valuelen) { /* Nothing to do */ if (!testvar("reset_to_default")) @@ -2472,7 +2474,7 @@ static int voltronic_capability_reset(item_t *item, char *value, size_t valuelen } /* Voltage limits for ECO Mode */ -static int voltronic_eco_volt(item_t *item, char *value, size_t valuelen) +static int voltronic_eco_volt(item_t *item, char *value, const size_t valuelen) { const int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10); int ovn; @@ -2595,7 +2597,7 @@ static int voltronic_eco_volt(item_t *item, char *value, size_t valuelen) } /* Voltage limits for ECO Mode (max, min) */ -static int voltronic_eco_volt_range(item_t *item, char *value, size_t valuelen) +static int voltronic_eco_volt_range(item_t *item, char *value, const size_t valuelen) { char *buf; int i; @@ -2644,7 +2646,7 @@ static int voltronic_eco_volt_range(item_t *item, char *value, size_t valuelen) } /* Frequency limits for ECO Mode */ -static int voltronic_eco_freq(item_t *item, char *value, size_t valuelen) +static int voltronic_eco_freq(item_t *item, char *value, const size_t valuelen) { item_t *unskip; @@ -2668,7 +2670,7 @@ static int voltronic_eco_freq(item_t *item, char *value, size_t valuelen) } /* *NONUT* Voltage/frequency limits for Bypass Mode */ -static int voltronic_bypass(item_t *item, char *value, size_t valuelen) +static int voltronic_bypass(item_t *item, char *value, const size_t valuelen) { item_t *unskip; double val; @@ -2720,7 +2722,7 @@ static int voltronic_bypass(item_t *item, char *value, size_t valuelen) } /* *NONUT* Number of batteries */ -static int voltronic_batt_numb(item_t *item, char *value, size_t valuelen) +static int voltronic_batt_numb(item_t *item, char *value, const size_t valuelen) { item_t *unskip; @@ -2750,7 +2752,7 @@ static int voltronic_batt_numb(item_t *item, char *value, size_t valuelen) } /* Battery runtime */ -static int voltronic_batt_runtime(item_t *item, char *value, size_t valuelen) +static int voltronic_batt_runtime(item_t *item, char *value, const size_t valuelen) { double runtime; @@ -2768,7 +2770,7 @@ static int voltronic_batt_runtime(item_t *item, char *value, size_t valuelen) } /* Protocol used by the UPS */ -static int voltronic_protocol(item_t *item, char *value, size_t valuelen) +static int voltronic_protocol(item_t *item, char *value, const size_t valuelen) { int protocol; @@ -2818,7 +2820,7 @@ static int voltronic_protocol(item_t *item, char *value, size_t valuelen) /* Fault reported by the UPS: * When the UPS is queried for status (QGS), if it reports a fault (6th bit of 12bit flag of the reply to QGS set to 1), the driver unskips the QFS item in qx2nut array: this function processes the reply to QFS query */ -static int voltronic_fault(item_t *item, char *value, size_t valuelen) +static int voltronic_fault(item_t *item, char *value, const size_t valuelen) { int protocol = strtol(dstate_getinfo("ups.firmware.aux")+1, NULL, 10); @@ -3185,7 +3187,7 @@ static int voltronic_fault(item_t *item, char *value, size_t valuelen) } /* Warnings reported by the UPS */ -static int voltronic_warning(item_t *item, char *value, size_t valuelen) +static int voltronic_warning(item_t *item, char *value, const size_t valuelen) { char warn[SMALLBUF] = "", unk[SMALLBUF] = "", bitwarns[SMALLBUF] = "", warns[4096] = ""; int i; @@ -3591,7 +3593,7 @@ static int voltronic_warning(item_t *item, char *value, size_t valuelen) } /* Working mode reported by the UPS */ -static int voltronic_mode(item_t *item, char *value, size_t valuelen) +static int voltronic_mode(item_t *item, char *value, const size_t valuelen) { char *status = NULL, *alarm = NULL; @@ -3669,7 +3671,7 @@ static int voltronic_mode(item_t *item, char *value, size_t valuelen) } /* Process status bits */ -static int voltronic_status(item_t *item, char *value, size_t valuelen) +static int voltronic_status(item_t *item, char *value, const size_t valuelen) { char *val = ""; @@ -3845,7 +3847,7 @@ static int voltronic_status(item_t *item, char *value, size_t valuelen) } /* Output power factor */ -static int voltronic_output_powerfactor(item_t *item, char *value, size_t valuelen) +static int voltronic_output_powerfactor(item_t *item, char *value, const size_t valuelen) { double opf; @@ -3863,7 +3865,7 @@ static int voltronic_output_powerfactor(item_t *item, char *value, size_t valuel } /* UPS serial number */ -static int voltronic_serial_numb(item_t *item, char *value, size_t valuelen) +static int voltronic_serial_numb(item_t *item, char *value, const size_t valuelen) { /* If the UPS report a 00..0 serial we'll log it but we won't store it in device.serial */ if (strspn(item->value, "0") == strlen(item->value)) { @@ -3876,7 +3878,7 @@ static int voltronic_serial_numb(item_t *item, char *value, size_t valuelen) } /* Outlet status */ -static int voltronic_outlet(item_t *item, char *value, size_t valuelen) +static int voltronic_outlet(item_t *item, char *value, const size_t valuelen) { const char *status, *switchable; char number = item->info_type[7], @@ -3956,7 +3958,7 @@ static int voltronic_outlet(item_t *item, char *value, size_t valuelen) } /* Outlet delay time */ -static int voltronic_outlet_delay(item_t *item, char *value, size_t valuelen) +static int voltronic_outlet_delay(item_t *item, char *value, const size_t valuelen) { char number = item->info_type[7], buf[SMALLBUF]; @@ -3988,7 +3990,7 @@ static int voltronic_outlet_delay(item_t *item, char *value, size_t valuelen) } /* *SETVAR* Outlet delay time */ -static int voltronic_outlet_delay_set(item_t *item, char *value, size_t valuelen) +static int voltronic_outlet_delay_set(item_t *item, char *value, const size_t valuelen) { int delay = strtol(value, NULL, 10); @@ -4001,7 +4003,7 @@ static int voltronic_outlet_delay_set(item_t *item, char *value, size_t valuelen } /* Type of battery */ -static int voltronic_p31b(item_t *item, char *value, size_t valuelen) +static int voltronic_p31b(item_t *item, char *value, const size_t valuelen) { int val; @@ -4020,7 +4022,7 @@ static int voltronic_p31b(item_t *item, char *value, size_t valuelen) } /* *SETVAR* Type of battery */ -static int voltronic_p31b_set(item_t *item, char *value, size_t valuelen) +static int voltronic_p31b_set(item_t *item, char *value, const size_t valuelen) { int i; @@ -4043,7 +4045,7 @@ static int voltronic_p31b_set(item_t *item, char *value, size_t valuelen) } /* *NONUT* Actual device grid working range type for P31 UPSes */ -static int voltronic_p31g(item_t *item, char *value, size_t valuelen) +static int voltronic_p31g(item_t *item, char *value, const size_t valuelen) { int val; @@ -4063,7 +4065,7 @@ static int voltronic_p31g(item_t *item, char *value, size_t valuelen) } /* *SETVAR/NONUT* Device grid working range type for P31 UPSes */ -static int voltronic_p31g_set(item_t *item, char *value, size_t valuelen) +static int voltronic_p31g_set(item_t *item, char *value, const size_t valuelen) { int i; @@ -4091,7 +4093,7 @@ static int voltronic_p31g_set(item_t *item, char *value, size_t valuelen) } /* *NONUT* UPS actual input/output phase angles */ -static int voltronic_phase(item_t *item, char *value, size_t valuelen) +static int voltronic_phase(item_t *item, char *value, const size_t valuelen) { int angle; @@ -4130,7 +4132,7 @@ static int voltronic_phase(item_t *item, char *value, size_t valuelen) } /* *SETVAR/NONUT* Output phase angle */ -static int voltronic_phase_set(item_t *item, char *value, size_t valuelen) +static int voltronic_phase_set(item_t *item, char *value, const size_t valuelen) { int i; @@ -4158,7 +4160,7 @@ static int voltronic_phase_set(item_t *item, char *value, size_t valuelen) } /* *NONUT* UPS is master/slave in a system of UPSes in parallel */ -static int voltronic_parallel(item_t *item, char *value, size_t valuelen) +static int voltronic_parallel(item_t *item, char *value, const size_t valuelen) { char *type; diff --git a/drivers/nutdrv_qx_zinto.c b/drivers/nutdrv_qx_zinto.c index 62f3209..d039ccd 100644 --- a/drivers/nutdrv_qx_zinto.c +++ b/drivers/nutdrv_qx_zinto.c @@ -25,7 +25,7 @@ #include "nutdrv_qx_zinto.h" -#define ZINTO_VERSION "Zinto 0.04" +#define ZINTO_VERSION "Zinto 0.06" /* qx2nut lookup table */ static item_t zinto_qx2nut[] = { @@ -37,22 +37,22 @@ static item_t zinto_qx2nut[] = { * 0 1 2 3 4 */ - { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL }, - { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL }, - { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL }, - { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL }, - { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL }, - { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL }, - { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL }, + { "input.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 1, 5, "%.1f", 0, NULL, NULL, NULL }, + { "input.voltage.fault", 0, NULL, "Q1\r", "", 47, '(', "", 7, 11, "%.1f", 0, NULL, NULL, NULL }, + { "output.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 13, 17, "%.1f", 0, NULL, NULL, NULL }, + { "ups.load", 0, NULL, "Q1\r", "", 47, '(', "", 19, 21, "%.0f", 0, NULL, NULL, NULL }, + { "input.frequency", 0, NULL, "Q1\r", "", 47, '(', "", 23, 26, "%.1f", 0, NULL, NULL, NULL }, + { "battery.voltage", 0, NULL, "Q1\r", "", 47, '(', "", 28, 31, "%.2f", 0, NULL, NULL, NULL }, + { "ups.temperature", 0, NULL, "Q1\r", "", 47, '(', "", 33, 36, "%.1f", 0, NULL, NULL, NULL }, /* Status bits */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Battery Low */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ - { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, blazer_process_status_bits }, /* UPS Failed */ - { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, blazer_process_status_bits }, /* UPS Type */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Test in Progress */ - { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, blazer_process_status_bits }, /* Shutdown Active */ - { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, blazer_process_status_bits }, /* Beeper status */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 38, 38, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Utility Fail (Immediate) */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 39, 39, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Battery Low */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 40, 40, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Bypass/Boost or Buck Active */ + { "ups.alarm", 0, NULL, "Q1\r", "", 47, '(', "", 41, 41, NULL, 0, NULL, NULL, blazer_process_status_bits }, /* UPS Failed */ + { "ups.type", 0, NULL, "Q1\r", "", 47, '(', "", 42, 42, "%s", QX_FLAG_STATIC, NULL, NULL, blazer_process_status_bits }, /* UPS Type */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 43, 43, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Test in Progress */ + { "ups.status", 0, NULL, "Q1\r", "", 47, '(', "", 44, 44, NULL, QX_FLAG_QUICK_POLL, NULL, NULL, blazer_process_status_bits }, /* Shutdown Active */ + { "ups.beeper.status", 0, NULL, "Q1\r", "", 47, '(', "", 45, 45, "%s", 0, NULL, NULL, blazer_process_status_bits }, /* Beeper status */ /* * > [F\r] @@ -61,10 +61,10 @@ static item_t zinto_qx2nut[] = { * 0 1 2 */ - { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL }, - { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL }, - { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL }, + { "input.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 1, 5, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.current.nominal", 0, NULL, "F\r", "", 22, '#', "", 7, 9, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "battery.voltage.nominal", 0, NULL, "F\r", "", 22, '#', "", 11, 15, "%.1f", QX_FLAG_STATIC, NULL, NULL, NULL }, + { "input.frequency.nominal", 0, NULL, "F\r", "", 22, '#', "", 17, 20, "%.0f", QX_FLAG_STATIC, NULL, NULL, NULL }, /* * > [FW?\r] @@ -73,28 +73,28 @@ static item_t zinto_qx2nut[] = { * 0 1 2 3 */ - { "device.mfr", 0, NULL, "FW?\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "device.model", 0, NULL, "FW?\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, - { "ups.firmware", 0, NULL, "FW?\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL }, + { "device.mfr", 0, NULL, "FW?\r", "", 39, '#', "", 1, 15, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "device.model", 0, NULL, "FW?\r", "", 39, '#', "", 17, 26, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, + { "ups.firmware", 0, NULL, "FW?\r", "", 39, '#', "", 28, 37, "%s", QX_FLAG_STATIC | QX_FLAG_TRIM, NULL, NULL, NULL }, /* Instant commands */ - { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, blazer_process_command }, - { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, - { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL }, + { "beeper.toggle", 0, NULL, "Q\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.off", 0, NULL, "S00R0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "load.on", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "shutdown.return", 0, NULL, "S%s\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stayoff", 0, NULL, "S%sR0000\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "shutdown.stop", 0, NULL, "C\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start", 0, NULL, "T%02d\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, blazer_process_command }, + { "test.battery.start.deep", 0, NULL, "TL\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.start.quick", 0, NULL, "T\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, + { "test.battery.stop", 0, NULL, "CT\r", "", 0, 0, "", 0, 0, NULL, QX_FLAG_CMD, NULL, NULL, NULL }, /* Server-side settable vars */ - { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, - { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, blazer_process_setvar }, + { "ups.delay.start", ST_FLAG_RW, blazer_r_ondelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_ONDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, + { "ups.delay.shutdown", ST_FLAG_RW, blazer_r_offdelay, NULL, "", 0, 0, "", 0, 0, DEFAULT_OFFDELAY, QX_FLAG_ABSENT | QX_FLAG_SETVAR | QX_FLAG_RANGE, NULL, NULL, blazer_process_setvar }, /* End of structure. */ - { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL } + { NULL, 0, NULL, NULL, "", 0, 0, "", 0, 0, NULL, 0, NULL, NULL, NULL } }; /* Testing table */ diff --git a/drivers/powercom.c b/drivers/powercom.c index 573a234..edf2b9b 100644 --- a/drivers/powercom.c +++ b/drivers/powercom.c @@ -9,6 +9,7 @@ * -OptiUPS VS 575C * * Copyrights: + * (C) 2015 Arnaud Quette * (C) 2013 Florian Bruhin * (C) 2002 Simon Rozman * (C) 1999 Peter Bieringer @@ -69,6 +70,10 @@ * * Tested on: IMP-625AP * + * rev 0.16: Arnaud Quette + * - Fixed the processing of input/output voltages for KIN models + * (https://github.com/networkupstools/nut/issues/187) + * */ #include "main.h" @@ -77,7 +82,7 @@ #include "math.h" #define DRIVER_NAME "PowerCom protocol UPS driver" -#define DRIVER_VERSION "0.14" +#define DRIVER_VERSION "0.17" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -86,7 +91,8 @@ upsdrv_info_t upsdrv_info = { "Simon Rozman \n" \ "Peter Bieringer \n" \ "Alexey Sidorov \n" \ - "Florian Bruhin ", + "Florian Bruhin \n" \ + "Arnaud Quette ", DRV_STABLE, { NULL } }; @@ -415,12 +421,24 @@ static float input_voltage(void) tmp=2.2*raw_data[INPUT_VOLTAGE]-24; } else if ( !strcmp(types[type].name, "KIN")) { model=KINmodels[raw_data[MODELNUMBER]/16]; - if (model<=625){ - tmp=1.79*raw_data[INPUT_VOLTAGE]+3.35; - } else if (model<2000){ - tmp=1.61*raw_data[INPUT_VOLTAGE]; - } else { - tmp=1.625*raw_data[INPUT_VOLTAGE]; + /* Process input voltage, according to line voltage and model rating */ + if (linevoltage < 200) { + if (model <= 625) { + tmp = 0.89 * raw_data[INPUT_VOLTAGE] + 6.18; + } else if ((model >= 800) && (model < 2000)) { + tmp = 1.61 * raw_data[INPUT_VOLTAGE] / 2.0; + } else { + tmp = 1.625 * raw_data[INPUT_VOLTAGE] / 2.0; + } + } + if (linevoltage >= 200) { + if (model <= 625) { + tmp = 1.79 * raw_data[INPUT_VOLTAGE] + 3.35; + } else if ((model >= 800) && (model < 2000)) { + tmp = 1.61 * raw_data[INPUT_VOLTAGE]; + } else { + tmp = 1.625 * raw_data[INPUT_VOLTAGE]; + } } } else if ( !strcmp(types[type].name, "IMP") || !strcmp(types[type].name, "OPTI")) { tmp=raw_data[INPUT_VOLTAGE]*2.0; @@ -437,10 +455,13 @@ static float output_voltage(void) { float tmp,rdatax,rdatay,rdataz,boostdata; unsigned int statINV = 0,statAVR = 0,statAVRMode = 0,model,t; - static float datax[]={0,1.0,1.0,1.0,1.0,1.89,1.89,1.89,0.127,0.127,1.89,1.89,1.89,0.256}; - static float datay[]={0,1.73,1.74,1.74,1.77,0.9,0.9,0.9,13.204,13.204,0.88,0.88,0.88,6.645}; - static float dataz[]={0,1.15,0.9,0.9,0.75,1.1,1.1,1.1,0.8,0.8,0.86,0.86,0.86,0.7}; - + static float datax1[]={0,1.0,1.0,1.0,1.0,0.945,0.945,0.945,0.127,0.127,0.945,0.945,0.945,0.256}; + static float datay1[]={0,0.85,0.85,0.85,0.88,0.9,0.9,0.9,6.6,6.6,0.87,0.87,0.87,3.29}; + static float dataz1[]={0,1.03,0.78,0.78,0.72,0.55,0.55,0.55,0.5,0.5,0.43,0.43,0.43,0.3}; + static float datax2[]={0,1.0,1.0,1.0,1.0,1.89,1.89,1.89,0.127,0.127,1.89,1.89,1.89,0.256}; + static float datay2[]={0,1.73,1.74,1.74,1.77,0.9,0.9,0.9,13.204,13.204,0.88,0.88,0.88,6.645}; + static float dataz2[]={0,1.15,0.9,0.9,0.75,1.1,1.1,1.1,0.8,0.8,0.86,0.86,0.86,0.7}; + if ( !strcmp(types[type].name, "BNT") || !strcmp(types[type].name, "KIN")) { statINV=raw_data[STATUS_A] & ONLINE; statAVR=raw_data[STATUS_A] & AVR_ON; @@ -466,41 +487,78 @@ static float output_voltage(void) } } else if ( !strcmp(types[type].name, "KIN")) { model=KINmodels[raw_data[MODELNUMBER]/16]; - if (statINV==0) { - if (statAVR==0) { - if (model<=625) - tmp=1.79*raw_data[OUTPUT_VOLTAGE]+3.35; - else if (model<2000) - tmp=1.61*raw_data[OUTPUT_VOLTAGE]; - else - tmp=1.625*raw_data[OUTPUT_VOLTAGE]; - } else { - if (statAVRMode > 0){ - if (model<=525) - tmp=2.07*raw_data[OUTPUT_VOLTAGE]; - else if (model==625) - tmp=2.07*raw_data[OUTPUT_VOLTAGE]+5; + if (statINV == 0) { + if (statAVR == 0) { + // FIXME: miss test "if (iUPS == 1) {" + if (linevoltage >= 200) { + if (linevoltage <= 625) + tmp = 1.79*raw_data[OUTPUT_VOLTAGE] + 3.35; else if (model<2000) - tmp=1.87*raw_data[OUTPUT_VOLTAGE]; + tmp = 1.61*raw_data[OUTPUT_VOLTAGE]; else - tmp=1.87*raw_data[OUTPUT_VOLTAGE]; + tmp = 1.625*raw_data[OUTPUT_VOLTAGE]; } else { - if (model<=625) - tmp=1.571*raw_data[OUTPUT_VOLTAGE]; + if (linevoltage <= 625) + tmp = 0.89 * raw_data[OUTPUT_VOLTAGE] + 6.18; else if (model<2000) - tmp=1.37*raw_data[OUTPUT_VOLTAGE]; + tmp = 1.61 * raw_data[OUTPUT_VOLTAGE] / 2.0; else - tmp=1.4*raw_data[OUTPUT_VOLTAGE]; + tmp = 1.625 * raw_data[OUTPUT_VOLTAGE] / 2.0; + } + } + else if (statAVR == 1) { + // FIXME: miss test "if ((iUPS == 1) || (iUPS == 13)) {" + if (linevoltage >= 200) { + if (model <= 525) + tmp = 2.07 * raw_data[OUTPUT_VOLTAGE]; + else if (model == 625) + tmp = 2.07 * raw_data[OUTPUT_VOLTAGE]+5; + else if (model < 2000) + tmp = 1.87 * raw_data[OUTPUT_VOLTAGE]; + else + tmp = 1.87 * raw_data[OUTPUT_VOLTAGE]; + } else { + if (model <= 625) + tmp = 2.158 * raw_data[OUTPUT_VOLTAGE] / 2.0; + else if (model < 2000) + tmp = 1.842 * raw_data[OUTPUT_VOLTAGE] / 2.0; + else + tmp = 1.875 * raw_data[OUTPUT_VOLTAGE] / 2.0; + } + } else { + // FIXME: miss test "if ((iUPS == 1) || (iUPS == 13)) {" + if (linevoltage >= 200) { + if (model == 625) + tmp = 1.571 * raw_data[OUTPUT_VOLTAGE]; + else if (model < 2000) + tmp = 1.37 * raw_data[OUTPUT_VOLTAGE]; + else + tmp = 1.4 * raw_data[OUTPUT_VOLTAGE]; + } else { + if (model <= 625) + tmp = 1.635 * raw_data[OUTPUT_VOLTAGE] / 2.0; + else if (model < 2000) + tmp = 1.392 * raw_data[OUTPUT_VOLTAGE] / 2.0; + else + tmp = 1.392 * raw_data[OUTPUT_VOLTAGE] / 2.0; } } } else { - rdatax=datax[raw_data[MODELNUMBER]/16]; - rdatay=datay[raw_data[MODELNUMBER]/16]; - rdataz=dataz[raw_data[MODELNUMBER]/16]; - boostdata=1.0+statAVR*20.0/135.0; - t=raw_data[OUTPUT_FREQUENCY]/2; - tmp=0; - if (model>625){ + // FIXME: miss test "if ((iUPS == 1) && (T != 0))" + if (linevoltage < 200) { + rdatax = datax1[raw_data[MODELNUMBER]/16]; + rdatay = datay1[raw_data[MODELNUMBER]/16]; + rdataz = dataz1[raw_data[MODELNUMBER]/16]; + } else { + rdatax = datax2[raw_data[MODELNUMBER]/16]; + rdatay = datay2[raw_data[MODELNUMBER]/16]; + rdataz = dataz2[raw_data[MODELNUMBER]/16+1]; + } + + boostdata = 1.0 + statAVR * 20.0 / 135.0; + t = raw_data[OUTPUT_FREQUENCY]/2; + tmp = 0; + if (model > 625){ tmp=(raw_data[BATTERY_CHARGE]*rdatax)*(raw_data[BATTERY_CHARGE]*rdatax)* (t-raw_data[OUTPUT_VOLTAGE])/t; if (tmp>0) @@ -512,6 +570,7 @@ static float output_voltage(void) if (tmp>0) tmp=sqrt(tmp)*rdatay; } + // FIXME: may miss a last processing with ErrorVal = 5 | 10 } } else if ( !strcmp(types[type].name, "IMP") || !strcmp(types[type].name, "OPTI")) { tmp=raw_data[OUTPUT_VOLTAGE]*2.0; diff --git a/drivers/powerp-bin.c b/drivers/powerp-bin.c index b128369..ad6037d 100644 --- a/drivers/powerp-bin.c +++ b/drivers/powerp-bin.c @@ -341,7 +341,7 @@ static void powpan_initinfo(void) dstate_setinfo("ups.model", "%s", modeltab[i].model); } else { /* report model value as is */ - dstate_setinfo("ups.model", "%s", rtrim(s, ' ')); + dstate_setinfo("ups.model", "%s", str_rtrim(s, ' ')); } } if ((s = strtok(NULL, ".")) != NULL) { diff --git a/drivers/powerp-txt.c b/drivers/powerp-txt.c index 366514c..fa0353a 100644 --- a/drivers/powerp-txt.c +++ b/drivers/powerp-txt.c @@ -230,7 +230,7 @@ static void powpan_initinfo(void) * was used for autodetection of the UPS. No need to do it again. */ if ((s = strtok(&powpan_answer[1], ",")) != NULL) { - dstate_setinfo("ups.model", "%s", rtrim(s, ' ')); + dstate_setinfo("ups.model", "%s", str_rtrim(s, ' ')); } if ((s = strtok(NULL, ",")) != NULL) { dstate_setinfo("ups.firmware", "%s", s); @@ -239,7 +239,7 @@ static void powpan_initinfo(void) dstate_setinfo("ups.serial", "%s", s); } if ((s = strtok(NULL, ",")) != NULL) { - dstate_setinfo("ups.mfr", "%s", rtrim(s, ' ')); + dstate_setinfo("ups.mfr", "%s", str_rtrim(s, ' ')); } /* diff --git a/drivers/powerpanel.c b/drivers/powerpanel.c index c683c3f..45e1f1e 100644 --- a/drivers/powerpanel.c +++ b/drivers/powerpanel.c @@ -36,7 +36,7 @@ static subdriver_t *subdriver[] = { }; #define DRIVER_NAME "CyberPower text/binary protocol UPS driver" -#define DRIVER_VERSION "0.26" +#define DRIVER_VERSION "0.27" /* driver description structure */ upsdrv_info_t upsdrv_info = { diff --git a/drivers/powerware-mib.c b/drivers/powerware-mib.c index 54b3628..1c2f9f2 100644 --- a/drivers/powerware-mib.c +++ b/drivers/powerware-mib.c @@ -4,7 +4,7 @@ * Copyright (C) * 2005-2006 Olli Savia * 2005-2006 Niels Baggesen - * 2015 Arnaud Quette + * 2015-2016 Arnaud Quette * * 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 @@ -25,7 +25,7 @@ #include "powerware-mib.h" -#define PW_MIB_VERSION "0.7" +#define PW_MIB_VERSION "0.87" /* TODO: more sysOID and MIBs support: * @@ -37,6 +37,8 @@ /* Powerware UPS (Ingrasys X-SLOT and BD-SLOT) */ #define POWERWARE_SYSOID ".1.3.6.1.4.1.534.1" +/* Powerware UPS newer PXGX UPS cards (BladeUPS, ...) */ +#define EATON_PXGX_SYSOID ".1.3.6.1.4.1.534.2.12" /* SNMP OIDs set */ #define PW_OID_MFR_NAME "1.3.6.1.4.1.534.1.1.1.0" /* XUPS-MIB::xupsIdentManufacturer.0 */ @@ -68,10 +70,6 @@ #define PW_OID_BY_LINES "1.3.6.1.4.1.534.1.5.2.0" /* XUPS-MIB::xupsBypassNumPhases.0 */ #define PW_OID_BY_VOLTAGE "1.3.6.1.4.1.534.1.5.3.1.2" /* XUPS-MIB::xupsBypassVoltage */ -#define PW_OID_AMBIENT_TEMP "1.3.6.1.4.1.534.1.6.1.0" /* XUPS-MIB::xupsEnvAmbientTemp.0 */ -#define PW_OID_AMBIENT_LOW "1.3.6.1.4.1.534.1.6.2.0" /* XUPS-MIB::xupsEnvAmbientLowerLimit.0 */ -#define PW_OID_AMBIENT_HIGH "1.3.6.1.4.1.534.1.6.3.0" /* XUPS-MIB::xupsEnvAmbientUpperLimit.0 */ - #define PW_OID_BATTEST_START "1.3.6.1.4.1.534.1.8.1" /* XUPS-MIB::xupsTestBattery set to startTest(1) to initiate test*/ #define PW_OID_BATTEST_RES "1.3.6.1.4.1.534.1.8.2" /* XUPS-MIB::xupsTestBatteryStatus */ @@ -79,6 +77,7 @@ #define PW_OID_CONT_ONDELAY "1.3.6.1.4.1.534.1.9.2" /* XUPS-MIB::xupsControlOutputOnDelay */ #define PW_OID_CONT_OFFT_DEL "1.3.6.1.4.1.534.1.9.3" /* XUPS-MIB::xupsControlOutputOffTrapDelay */ #define PW_OID_CONT_ONT_DEL "1.3.6.1.4.1.534.1.9.4" /* XUPS-MIB::xupsControlOutputOnTrapDelay */ +#define PW_OID_CONT_LOAD_SHED_AND_RESTART "1.3.6.1.4.1.534.1.9.6" /* XUPS-MIB::xupsLoadShedSecsWithRestart */ #define PW_OID_CONF_OVOLTAGE "1.3.6.1.4.1.534.1.10.1.0" /* XUPS-MIB::xupsConfigOutputVoltage.0 */ #define PW_OID_CONF_IVOLTAGE "1.3.6.1.4.1.534.1.10.2.0" /* XUPS-MIB::xupsConfigInputVoltage.0 */ @@ -94,45 +93,69 @@ #define IETF_OID_CONF_OUT_VA "1.3.6.1.2.1.33.1.9.5.0" /* UPS-MIB::upsConfigOutputVA.0 */ #define IETF_OID_CONF_RUNTIME_LOW "1.3.6.1.2.1.33.1.9.7.0" /* UPS-MIB::upsConfigLowBattTime.0 */ #define IETF_OID_LOAD_LEVEL "1.3.6.1.2.1.33.1.4.4.1.5" /* UPS-MIB::upsOutputPercentLoad */ +#define IETF_OID_AUTO_RESTART "1.3.6.1.2.1.33.1.8.5.0" /* UPS-MIB::upsAutoRestart */ + +/* Delay before powering off in seconds */ +#define DEFAULT_OFFDELAY 30 +/* Delay before powering on in seconds */ +#define DEFAULT_ONDELAY 20 +/* Default shutdown.return delay in seconds */ +#define DEFAULT_SHUTDOWNDELAY 0 static info_lkp_t pw_alarm_ob[] = { { 1, "OB" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } } ; static info_lkp_t pw_alarm_lb[] = { { 1, "LB" }, { 2, "" }, - { 0, "NULL" } + { 0, NULL } } ; static info_lkp_t pw_pwr_info[] = { - { 1, "" /* other */ }, - { 2, "OFF" /* none */ }, - { 3, "OL" /* normal */ }, - { 4, "BYPASS" /* bypass */ }, - { 5, "OB" /* battery */ }, - { 6, "OL BOOST" /* booster */ }, - { 7, "OL TRIM" /* reducer */ }, - { 8, "OL" /* parallel capacity */ }, - { 9, "OL" /* parallel redundancy */ }, - {10, "OL" /* high efficiancy */ }, - { 0, "NULL" } + { 1, "" /* other */ }, + { 2, "OFF" /* none */ }, + { 3, "OL" /* normal */ }, + { 4, "BYPASS" /* bypass */ }, + { 5, "OB" /* battery */ }, + { 6, "OL BOOST" /* booster */ }, + { 7, "OL TRIM" /* reducer */ }, + { 8, "OL" /* parallel capacity */ }, + { 9, "OL" /* parallel redundancy */ }, + { 10, "OL" /* high efficiency */ }, + /* Extended status values */ + { 240, "OB" /* battery (0xF0) */ }, + { 100, "BYPASS" /* maintenanceBypass (0x64) */ }, + { 96, "BYPASS" /* Bypass (0x60) */ }, + { 81, "OL" /* high efficiency (0x51) */ }, + { 80, "OL" /* normal (0x50) */ }, + { 64, "OL" /* UPS supporting load, normal degraded mode (0x40) */ }, + { 16, "OFF" /* none (0x10) */ }, + { 0, NULL } }; static info_lkp_t pw_mode_info[] = { - { 1, "" }, - { 2, "" }, - { 3, "normal" }, - { 4, "" }, - { 5, "" }, - { 6, "" }, - { 7, "" }, - { 8, "parallel capacity" }, - { 9, "parallel redundancy" }, - {10, "high efficiency" }, - { 0, "NULL" } + { 1, "" }, + { 2, "" }, + { 3, "normal" }, + { 4, "" }, + { 5, "" }, + { 6, "" }, + { 7, "" }, + { 8, "parallel capacity" }, + { 9, "parallel redundancy" }, + { 10, "high efficiency" }, + /* Extended status values */ + { 240, "" /* battery (0xF0) */ }, + { 100, "" /* maintenanceBypass (0x64) */ }, + { 96, "" /* Bypass (0x60) */ }, + { 81, "high efficiency" /* high efficiency (0x51) */ }, + { 80, "normal" /* normal (0x50) */ }, + { 64, "" /* UPS supporting load, normal degraded mode (0x40) */ }, + { 16, "" /* none (0x10) */ }, + { 0, NULL } }; /* Legacy implementation */ @@ -142,7 +165,7 @@ static info_lkp_t pw_battery_abm_status[] = { /* { 3, "Floating" }, */ /* { 4, "Resting" }, */ /* { 5, "Unknown" }, */ - { 0, "NULL" } + { 0, NULL } } ; static info_lkp_t eaton_abm_status_info[] = { @@ -152,7 +175,7 @@ static info_lkp_t eaton_abm_status_info[] = { { 4, "resting" }, { 5, "unknown" }, /* Undefined - ABM is not activated */ { 6, "disabled" }, /* ABM Charger Disabled */ - { 0, "NULL" } + { 0, NULL } }; static info_lkp_t pw_batt_test_info[] = { @@ -163,13 +186,19 @@ static info_lkp_t pw_batt_test_info[] = { { 5, "Not supported" }, { 6, "Inhibited" }, { 7, "Scheduled" }, - { 0, "NULL" } + { 0, NULL } }; +static info_lkp_t ietf_yes_no_info[] = { + { 1, "yes" }, + { 2, "no" }, + { 0, NULL } +}; /* Snmp2NUT lookup table */ static snmp_info_t pw_mib[] = { + /* FIXME: miss device page! */ /* UPS page */ /* info_type, info_flags, info_len, OID, dfl, flags, oid2info, setvar */ { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, PW_OID_MFR_NAME, "", @@ -200,10 +229,19 @@ static snmp_info_t pw_mib[] = { 0, NULL }, { "ups.power.nominal", 0, 1.0, IETF_OID_CONF_OUT_VA, "", 0, NULL }, + /* XUPS-MIB::xupsEnvAmbientTemp.0 */ + { "ups.temperature", 0, 1.0, "1.3.6.1.4.1.534.1.6.1.0", "", 0, NULL }, + /* FIXME: These 2 data needs RFC! */ + /* XUPS-MIB::xupsEnvAmbientLowerLimit.0 */ + { "ups.temperature.low", ST_FLAG_RW, 1.0, "1.3.6.1.4.1.534.1.6.2.0", "", 0, NULL }, + /* XUPS-MIB::xupsEnvAmbientUpperLimit.0 */ + { "ups.temperature.high", ST_FLAG_RW, 1.0, "1.3.6.1.4.1.534.1.6.3.0", "", 0, NULL }, { "ups.test.result", ST_FLAG_STRING, SU_INFOSIZE, PW_OID_BATTEST_RES, "", 0, &pw_batt_test_info[0] }, + { "ups.start.auto", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, IETF_OID_AUTO_RESTART, "", + SU_FLAG_OK, &ietf_yes_no_info[0] }, { "battery.charger.status", ST_FLAG_STRING, SU_INFOSIZE, PW_OID_BATT_STATUS, "", - SU_STATUS_BATT, &eaton_abm_status_info[0] }, + SU_STATUS_BATT, &eaton_abm_status_info[0] }, /* Battery page */ { "battery.charge", 0, 1.0, PW_OID_BATT_CHARGE, "", @@ -246,6 +284,7 @@ static snmp_info_t pw_mib[] = { SU_OUTPUT_3, NULL }, { "output.L3.realpower", 0, 1.0, PW_OID_OUT_POWER ".3", "", SU_OUTPUT_3, NULL }, + /* FIXME: should better be output.Lx.load */ { "output.L1.power.percent", 0, 1.0, IETF_OID_LOAD_LEVEL ".1", "", SU_OUTPUT_3, NULL }, { "output.L2.power.percent", 0, 1.0, IETF_OID_LOAD_LEVEL ".2", "", @@ -302,25 +341,39 @@ static snmp_info_t pw_mib[] = { SU_INPUT_3, NULL }, /* Ambient page */ - { "ambient.temperature", 0, 1.0, PW_OID_AMBIENT_TEMP, "", - 0, NULL }, - { "ambient.temperature.low", 0, 1.0, PW_OID_AMBIENT_LOW, "", - 0, NULL }, - { "ambient.temperature.high", 0, 1.0, PW_OID_AMBIENT_HIGH, "", - 0, NULL }, + /* XUPS-MIB::xupsEnvRemoteTemp.0 */ + { "ambient.temperature", 0, 1.0, "1.3.6.1.4.1.534.1.6.5.0", "", 0, NULL }, + /* XUPS-MIB::xupsEnvRemoteTempLowerLimit.0 */ + { "ambient.temperature.low", ST_FLAG_RW, 1.0, "1.3.6.1.4.1.534.1.6.9.0", "", 0, NULL }, + /* XUPS-MIB::xupsEnvRemoteTempUpperLimit.0 */ + { "ambient.temperature.high", ST_FLAG_RW, 1.0, "1.3.6.1.4.1.534.1.6.10.0", "", 0, NULL }, + + /* XUPS-MIB::xupsEnvRemoteHumidity.0 */ + { "ambient.humidity", 0, 1.0, "1.3.6.1.4.1.534.1.6.6.0", "", 0, NULL }, + /* XUPS-MIB::xupsEnvRemoteHumidityLowerLimit.0 */ + { "ambient.humidity.low", ST_FLAG_RW, 1.0, "1.3.6.1.4.1.534.1.6.11.0", "", 0, NULL }, + /* XUPS-MIB::xupsEnvRemoteHumidityUpperLimit.0 */ + { "ambient.humidity.high", ST_FLAG_RW, 1.0, "1.3.6.1.4.1.534.1.6.12.0", "", 0, NULL }, /* instant commands */ { "test.battery.start.quick", 0, 1, PW_OID_BATTEST_START, "", SU_TYPE_CMD | SU_FLAG_OK, NULL }, - /* Cancel output off, by writing 0 to xupsControlOutputOffDelay */ + /* Shed load and restart when line power back on; cannot be canceled */ + { "shutdown.return", 0, DEFAULT_SHUTDOWNDELAY, PW_OID_CONT_LOAD_SHED_AND_RESTART, "", + SU_TYPE_CMD | SU_FLAG_OK, NULL }, + /* Cancel output off, by writing 0 to xupsControlOutputOffDelay */ { "shutdown.stop", 0, 0, PW_OID_CONT_OFFDELAY, "", SU_TYPE_CMD | SU_FLAG_OK, NULL }, - /* load off after 1 sec, shortest possible delay */ + /* load off after 1 sec, shortest possible delay; 0 cancels */ { "load.off", 0, 1, PW_OID_CONT_OFFDELAY, "", SU_TYPE_CMD | SU_FLAG_OK, NULL }, - /* load on after 1 sec, shortest possible delay */ + { "load.off.delay", 0, DEFAULT_OFFDELAY, PW_OID_CONT_OFFDELAY, "", + SU_TYPE_CMD | SU_FLAG_OK, NULL }, + /* load on after 1 sec, shortest possible delay; 0 cancels */ { "load.on", 0, 1, PW_OID_CONT_ONDELAY, "", SU_TYPE_CMD | SU_FLAG_OK, NULL }, + { "load.on.delay", 0, DEFAULT_ONDELAY, PW_OID_CONT_ONDELAY, "", + SU_TYPE_CMD | SU_FLAG_OK, NULL }, { "ups.alarms", 0, 1.0, PW_OID_ALARMS, "", 0, NULL }, @@ -330,10 +383,107 @@ static snmp_info_t pw_mib[] = { } ; static alarms_info_t pw_alarms[] = { - { PW_OID_ALARM_LB, "LB" }, + /* xupsLowBattery */ + { PW_OID_ALARM_LB, "LB", NULL }, + /* xupsOutputOverload */ + { ".1.3.6.1.4.1.534.1.7.7", "OVER", "Output overload!" }, + /* xupsInternalFailure */ + { ".1.3.6.1.4.1.534.1.7.8", NULL, "Internal failure!" }, + /* xupsBatteryDischarged */ + { ".1.3.6.1.4.1.534.1.7.9", NULL, "Battery discharged!" }, + /* xupsInverterFailure */ + { ".1.3.6.1.4.1.534.1.7.10", NULL, "Inverter failure!" }, + /* xupsOnBypass + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.11", "BYPASS", "On bypass!" }, + /* xupsBypassNotAvailable + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.12", NULL, "Bypass not available!" }, + /* xupsOutputOff + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.13", "OFF", "Output off!" }, + /* xupsInputFailure + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.14", NULL, "Input failure!" }, + /* xupsBuildingAlarm + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.15", NULL, "Building alarm!" }, + /* xupsShutdownImminent */ + { ".1.3.6.1.4.1.534.1.7.16", NULL, "Shutdown imminent!" }, + /* xupsOnInverter + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.17", NULL, "On inverter!" }, + /* xupsBreakerOpen + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.20", NULL, "Breaker open!" }, + /* xupsAlarmBatteryBad */ + { ".1.3.6.1.4.1.534.1.7.23", "RB", "Battery bad!" }, + /* xupsOutputOffAsRequested + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.24", "OFF", "Output off as requested!" }, + /* xupsDiagnosticTestFailed + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.25", NULL, "Diagnostic test failure!" }, + /* xupsCommunicationsLost */ + { ".1.3.6.1.4.1.534.1.7.26", NULL, "Communication with UPS lost!" }, + /* xupsUpsShutdownPending */ + { ".1.3.6.1.4.1.534.1.7.27", NULL, "Shutdown pending!" }, + /* xupsAmbientTempBad */ + { ".1.3.6.1.4.1.534.1.7.29", NULL, "Bad ambient temperature!" }, + /* xupsLossOfRedundancy */ + { ".1.3.6.1.4.1.534.1.7.30", NULL, "Redundancy lost!" }, + /* xupsAlarmTempBad */ + { ".1.3.6.1.4.1.534.1.7.31", NULL, "Bad temperature!" }, + /* xupsAlarmChargerFailed */ + { ".1.3.6.1.4.1.534.1.7.32", NULL, "Charger failure!" }, + /* xupsAlarmFanFailure */ + { ".1.3.6.1.4.1.534.1.7.33", NULL, "Fan failure!" }, + /* xupsAlarmFuseFailure */ + { ".1.3.6.1.4.1.534.1.7.34", NULL, "Fuse failure!" }, + /* xupsPowerSwitchBad */ + { ".1.3.6.1.4.1.534.1.7.35", NULL, "Powerswitch failure!" }, + /* xupsModuleFailure */ + { ".1.3.6.1.4.1.534.1.7.36", NULL, "Parallel or composite module failure!" }, + /* xupsOnAlternatePowerSource + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.37", NULL, "Using alternative power source!" }, + /* xupsAltPowerNotAvailable + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.38", NULL, "Alternative power source unavailable!" }, + /* xupsRemoteTempBad */ + { ".1.3.6.1.4.1.534.1.7.40", NULL, "Bad remote temperature!" }, + /* xupsRemoteHumidityBad */ + { ".1.3.6.1.4.1.534.1.7.41", NULL, "Bad remote humidity!" }, + /* xupsAlarmOutputBad */ + { ".1.3.6.1.4.1.534.1.7.42", NULL, "Bad output condition!" }, + /* xupsAlarmAwaitingPower + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? */ + { ".1.3.6.1.4.1.534.1.7.43", NULL, "Awaiting power!" }, + /* xupsOnMaintenanceBypass + * FIXME: informational (not an alarm), + * to RFC'ed for device.event? + * FIXME: NUT currently doesn't distinguish between Maintenance and + * Automatic Bypass (both published as "ups.alarm: BYPASS) + * Should we make the distinction? */ + { ".1.3.6.1.4.1.534.1.7.44", "BYPASS", "On maintenance bypass!" }, + + /* end of structure. */ - { NULL, NULL } + { NULL, NULL, NULL } } ; -mib2nut_info_t powerware = { "pw", PW_MIB_VERSION, "", PW_OID_MODEL_NAME, pw_mib, POWERWARE_SYSOID , pw_alarms }; +mib2nut_info_t powerware = { "pw", PW_MIB_VERSION, NULL, PW_OID_MODEL_NAME, pw_mib, POWERWARE_SYSOID , pw_alarms }; +mib2nut_info_t pxgx_ups = { "pxgx_ups", PW_MIB_VERSION, NULL, PW_OID_MODEL_NAME, pw_mib, EATON_PXGX_SYSOID , pw_alarms }; diff --git a/drivers/powerware-mib.h b/drivers/powerware-mib.h index 2bd9d28..7189a24 100644 --- a/drivers/powerware-mib.h +++ b/drivers/powerware-mib.h @@ -5,5 +5,6 @@ #include "snmp-ups.h" extern mib2nut_info_t powerware; +extern mib2nut_info_t pxgx_ups; #endif /* POWERWARE_MIB_H */ diff --git a/drivers/raritan-pdu-mib.c b/drivers/raritan-pdu-mib.c index fd832c1..255ab41 100644 --- a/drivers/raritan-pdu-mib.c +++ b/drivers/raritan-pdu-mib.c @@ -25,7 +25,7 @@ #include "raritan-pdu-mib.h" -#define RARITAN_MIB_VERSION "0.4" +#define RARITAN_MIB_VERSION "0.5" /* Raritan MIB * this one uses the same MIB as Eaton Revelation, @@ -57,6 +57,8 @@ static snmp_info_t raritan_mib[] = { 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.13742.1.1.6.0", "", + SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, /* UPS page */ { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "Raritan", @@ -71,8 +73,6 @@ static snmp_info_t raritan_mib[] = { 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.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.13742.1.1.6.0", "", - SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, { "ups.temperature", 0, 1, ".1.3.6.1.4.1.13742.1.3.1.5.0", NULL, 0, NULL, NULL }, /* Outlet page */ @@ -121,4 +121,4 @@ static snmp_info_t raritan_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } }; -mib2nut_info_t raritan = { "raritan", RARITAN_MIB_VERSION, "", RARITAN_OID_MODEL_NAME, raritan_mib, RARITAN_SYSOID }; +mib2nut_info_t raritan = { "raritan", RARITAN_MIB_VERSION, NULL, RARITAN_OID_MODEL_NAME, raritan_mib, RARITAN_SYSOID }; diff --git a/drivers/snmp-ups.c b/drivers/snmp-ups.c index e99615d..4eab02e 100644 --- a/drivers/snmp-ups.c +++ b/drivers/snmp-ups.c @@ -4,6 +4,7 @@ * * Copyright (C) * 2002 - 2014 Arnaud Quette + * 2015 - 2016 Arnaud Quette * 2002 - 2006 Dmitry Frolov * J.W. Hoogervorst * Niels Baggesen @@ -30,6 +31,7 @@ */ #include +#include /* for isprint() */ /* NUT SNMP common functions */ #include "main.h" @@ -48,8 +50,11 @@ #include "bestpower-mib.h" #include "cyberpower-mib.h" #include "delta_ups-mib.h" +#include "huawei-mib.h" #include "ietf-mib.h" #include "xppc-mib.h" +#include "eaton-ats-mib.h" +#include "apc-ats-mib.h" /* Address API change */ #ifndef usmAESPrivProtocol @@ -61,6 +66,7 @@ static mib2nut_info_t *mib2nut[] = { &mge, &netvision, &powerware, + &pxgx_ups, &aphel_genesisII, &aphel_revelation, &eaton_marlin, @@ -72,7 +78,11 @@ static mib2nut_info_t *mib2nut[] = { &bestpower, &cyberpower, &delta_ups, - &xppc, + &xppc, + &huawei, + &tripplite_ietf, + &eaton_ats, + &apc_ats, /* * Prepend vendor specific MIB mappings before IETF, so that * if a device supports both IETF and vendor specific MIB, @@ -97,16 +107,15 @@ alarms_info_t *alarms_info; const char *mibname; const char *mibvers; -static void disable_transfer_oids(void); - #define DRIVER_NAME "Generic SNMP UPS driver" -#define DRIVER_VERSION "0.72" +#define DRIVER_VERSION "0.97" /* driver description structure */ upsdrv_info_t upsdrv_info = { DRIVER_NAME, DRIVER_VERSION, "Arnaud Quette \n" \ + "Arnaud Quette \n" \ "Dmitry Frolov \n" \ "J.W. Hoogervorst \n" \ "Niels Baggesen \n" \ @@ -118,13 +127,18 @@ upsdrv_info_t upsdrv_info = { time_t lastpoll = 0; -/* outlet OID index start with 0 or 1, +/* template OIDs index start with 0 or 1 (estimated stable for a MIB), * automatically guessed at the first pass */ -int outlet_index_base = -1; +int template_index_base = -1; /* sysOID location */ #define SYSOID_OID ".1.3.6.1.2.1.1.2.0" +/* Forward functions declarations */ +static void disable_transfer_oids(void); +bool_t get_and_process_data(int mode, snmp_info_t *su_info_p); +int extract_template_number(int template_type, const char* varname); + /* --------------------------------------------- * driver functions implementations * --------------------------------------------- */ @@ -132,17 +146,18 @@ void upsdrv_initinfo(void) { snmp_info_t *su_info_p; - upsdebugx(1, "SNMP UPS driver : entering upsdrv_initinfo()"); + upsdebugx(1, "SNMP UPS driver: entering %s()", __func__); dstate_setinfo("driver.version.data", "%s MIB %s", mibname, mibvers); /* add instant commands to the info database. - * outlet commands are processed later, during initial walk */ + * outlet (and groups) commands are processed later, during initial walk */ for (su_info_p = &snmp_info[0]; su_info_p->info_type != NULL ; su_info_p++) { su_info_p->flags |= SU_FLAG_OK; if ((SU_TYPE(su_info_p) == SU_TYPE_CMD) - && !(su_info_p->flags & SU_OUTLET)) { + && !(su_info_p->flags & SU_OUTLET) + && !(su_info_p->flags & SU_OUTLET_GROUP)) { /* first check that this OID actually exists */ if (nut_snmp_get(su_info_p->OID) != NULL) { dstate_addcmd(su_info_p->info_type); @@ -155,7 +170,7 @@ void upsdrv_initinfo(void) disable_transfer_oids(); /* initialize all other INFO_ fields from list */ - if (snmp_ups_walk(SU_WALKMODE_INIT)) + if (snmp_ups_walk(SU_WALKMODE_INIT) == TRUE) dstate_dataok(); else dstate_datastale(); @@ -167,12 +182,13 @@ void upsdrv_initinfo(void) void upsdrv_updateinfo(void) { - upsdebugx(1,"SNMP UPS driver : entering upsdrv_updateinfo()"); + upsdebugx(1,"SNMP UPS driver: entering %s()", __func__); /* only update every pollfreq */ /* FIXME: only update status (SU_STATUS_*), à la usbhid-ups, in between */ if (time(NULL) > (lastpoll + pollfreq)) { + alarm_init(); status_init(); /* update all dynamic info fields */ @@ -181,6 +197,7 @@ void upsdrv_updateinfo(void) else dstate_datastale(); + alarm_commit(); status_commit(); /* store timestamp */ @@ -199,7 +216,7 @@ void upsdrv_shutdown(void) but a limitation of the interface used. */ - upsdebugx(1, "upsdrv_shutdown..."); + upsdebugx(1, "%s...", __func__); /* Try to shutdown with delay */ if (su_instcmd("shutdown.return", NULL) == STAT_INSTCMD_HANDLED) { @@ -224,13 +241,13 @@ void upsdrv_shutdown(void) void upsdrv_help(void) { - upsdebugx(1, "entering upsdrv_help"); + upsdebugx(1, "entering %s", __func__); } /* list flags and values that you want to receive via -x */ void upsdrv_makevartable(void) { - upsdebugx(1, "entering upsdrv_makevartable()"); + upsdebugx(1, "entering %s()", __func__); addvar(VAR_VALUE, SU_VAR_MIBS, "Set MIB compliance (default=ietf, allowed: mge,apcc,netvision,pw,cpqpower,...)"); @@ -240,6 +257,10 @@ void upsdrv_makevartable(void) "Set SNMP version (default=v1, allowed v2c)"); addvar(VAR_VALUE, SU_VAR_POLLFREQ, "Set polling frequency in seconds, to reduce network flow (default=30)"); + addvar(VAR_VALUE, SU_VAR_RETRIES, + "Specifies the number of Net-SNMP retries to be used in the requests (default=5)"); + addvar(VAR_VALUE, SU_VAR_TIMEOUT, + "Specifies the Net-SNMP timeout in seconds between retries (default=1)"); addvar(VAR_FLAG, "notransferoids", "Disable transfer OIDs (use on APCC Symmetras)"); addvar(VAR_VALUE, SU_VAR_SECLEVEL, @@ -260,10 +281,10 @@ void upsdrv_initups(void) { snmp_info_t *su_info_p; char model[SU_INFOSIZE]; - bool_t status; + bool_t status= FALSE; const char *mibs; - upsdebugx(1, "SNMP UPS driver : entering upsdrv_initups()"); + upsdebugx(1, "SNMP UPS driver: entering %s()", __func__); /* Retrieve user's parameters */ mibs = testvar(SU_VAR_MIBS) ? getval(SU_VAR_MIBS) : "auto"; @@ -284,7 +305,12 @@ void upsdrv_initups(void) /* Get UPS Model node to see if there's a MIB */ su_info_p = su_find_info("ups.model"); - status = nut_snmp_get_str(su_info_p->OID, model, sizeof(model), NULL); + /* Try to get device.model if ups.model is not available */ + if (su_info_p == NULL) + su_info_p = su_find_info("device.model"); + + if (su_info_p != NULL) + status = nut_snmp_get_str(su_info_p->OID, model, sizeof(model), NULL); if (status == TRUE) upslogx(0, "Detected %s on host %s (mib: %s %s)", @@ -325,8 +351,10 @@ void nut_snmp_init(const char *type, const char *hostname) const char *community, *version; const char *secLevel = NULL, *authPassword, *privPassword; const char *authProtocol, *privProtocol; + int snmp_retries = DEFAULT_NETSNMP_RETRIES; + long snmp_timeout = DEFAULT_NETSNMP_TIMEOUT; - upsdebugx(2, "SNMP UPS driver : entering nut_snmp_init(%s)", type); + upsdebugx(2, "SNMP UPS driver: entering %s(%s)", __func__, type); /* Force numeric OIDs resolution (ie, do not resolve to textual names) * This is mostly for the convenience of debug output */ @@ -343,6 +371,20 @@ void nut_snmp_init(const char *type, const char *hostname) g_snmp_sess.peername = xstrdup(hostname); + /* Net-SNMP timeout and retries */ + if (testvar(SU_VAR_RETRIES)) { + snmp_retries = atoi(getval(SU_VAR_RETRIES)); + } + g_snmp_sess.retries = snmp_retries; + upsdebugx(2, "Setting SNMP retries to %i", snmp_retries); + + if (testvar(SU_VAR_TIMEOUT)) { + snmp_timeout = atol(getval(SU_VAR_TIMEOUT)); + } + /* We have to convert from seconds to microseconds */ + g_snmp_sess.timeout = snmp_timeout * ONE_SEC; + upsdebugx(2, "Setting SNMP timeout to %ld second(s)", snmp_timeout); + /* Retrieve user parameters */ version = testvar(SU_VAR_VERSION) ? getval(SU_VAR_VERSION) : "v1"; @@ -505,12 +547,13 @@ struct snmp_pdu **nut_snmp_walk(const char *OID, int max_iteration) struct snmp_pdu ** ret_array = NULL; int type = SNMP_MSG_GET; - upsdebugx(3, "nut_snmp_walk(%s)", OID); + upsdebugx(3, "%s(%s)", __func__, OID); + upsdebugx(4, "%s: max. iteration = %i", __func__, max_iteration); /* create and send request. */ if (!snmp_parse_oid(OID, name, &name_len)) { - upsdebugx(2, "[%s] nut_snmp_walk: %s: %s", - upsname?upsname:device_name, OID, snmp_api_errstring(snmp_errno)); + upsdebugx(2, "[%s] %s: %s: %s", + upsname?upsname:device_name, __func__, OID, snmp_api_errstring(snmp_errno)); return NULL; } @@ -548,8 +591,8 @@ struct snmp_pdu **nut_snmp_walk(const char *OID, int max_iteration) if ((numerr == SU_ERR_LIMIT) || ((numerr % SU_ERR_RATE) == 0)) { upslogx(LOG_WARNING, "[%s] Warning: excessive poll " - "failures, limiting error reporting", - upsname?upsname:device_name); + "failures, limiting error reporting (OID = %s)", + upsname?upsname:device_name, OID); } if ((numerr < SU_ERR_LIMIT) || ((numerr % SU_ERR_RATE) == 0)) { @@ -558,7 +601,7 @@ struct snmp_pdu **nut_snmp_walk(const char *OID, int max_iteration) } else { nut_snmp_perror(g_snmp_sess_p, status, response, - "nut_snmp_walk: %s", OID); + "%s: %s", __func__, OID); } } @@ -591,7 +634,7 @@ struct snmp_pdu *nut_snmp_get(const char *OID) if (OID == NULL) return NULL; - upsdebugx(3, "nut_snmp_get(%s)", OID); + upsdebugx(3, "%s(%s)", __func__, OID); pdu_array = nut_snmp_walk(OID,1); @@ -606,8 +649,10 @@ struct snmp_pdu *nut_snmp_get(const char *OID) return ret_pdu; } -static bool_t decode_str(struct snmp_pdu *pdu, char *buf, size_t buf_len, info_lkp_t *oid2info) { +static bool_t decode_str(struct snmp_pdu *pdu, char *buf, size_t buf_len, info_lkp_t *oid2info) +{ size_t len = 0; + char tmp_buf[SU_LARGEBUF]; /* zero out buffer. */ memset(buf, 0, buf_len); @@ -617,8 +662,15 @@ static bool_t decode_str(struct snmp_pdu *pdu, char *buf, size_t buf_len, info_l case ASN_OPAQUE: len = pdu->variables->val_len > buf_len - 1 ? buf_len - 1 : pdu->variables->val_len; - memcpy(buf, pdu->variables->val.string, len); - buf[len] = '\0'; + if (len > 0) { + /* Test for hexadecimal values */ + if (!isprint(pdu->variables->val.string[0])) + snprint_hexstring(buf, buf_len, pdu->variables->val.string, pdu->variables->val_len); + else { + memcpy(buf, pdu->variables->val.string, len); + buf[len] = '\0'; + } + } break; case ASN_INTEGER: case ASN_COUNTER: @@ -642,7 +694,18 @@ static bool_t decode_str(struct snmp_pdu *pdu, char *buf, size_t buf_len, info_l len = snprintf(buf, buf_len, "%ld", *pdu->variables->val.integer / 100); break; case ASN_OBJECT_ID: - len = snprint_objid (buf, buf_len, pdu->variables->val.objid, pdu->variables->val_len / sizeof(oid)); + snprint_objid (tmp_buf, sizeof(tmp_buf), pdu->variables->val.objid, pdu->variables->val_len / sizeof(oid)); + upsdebugx(2, "Received an OID value: %s", tmp_buf); + /* Try to get the value of the pointed OID */ + if (nut_snmp_get_str(tmp_buf, buf, buf_len, oid2info) == FALSE) { + upsdebugx(3, "Failed to retrieve OID value, using fallback"); + /* Otherwise return the last part of the returned OID (ex: 1.2.3 => 3) */ + char *oid_leaf = strrchr(tmp_buf, '.'); + snprintf(buf, buf_len, "%s", oid_leaf+1); + upsdebugx(3, "Fallback value: %s", buf); + } + else + snprintf(buf, buf_len, "%s", tmp_buf); break; default: return FALSE; @@ -656,7 +719,7 @@ bool_t nut_snmp_get_str(const char *OID, char *buf, size_t buf_len, info_lkp_t * struct snmp_pdu *pdu; bool_t ret; - upsdebugx(3, "Entering nut_snmp_get_str()"); + upsdebugx(3, "Entering %s()", __func__); pdu = nut_snmp_get(OID); if (pdu == NULL) @@ -674,8 +737,57 @@ bool_t nut_snmp_get_str(const char *OID, char *buf, size_t buf_len, info_lkp_t * return ret; } + +static bool_t decode_oid(struct snmp_pdu *pdu, char *buf, size_t buf_len) +{ + /* zero out buffer. */ + memset(buf, 0, buf_len); + + switch (pdu->variables->type) { + case ASN_OBJECT_ID: + snprint_objid (buf, buf_len, pdu->variables->val.objid, + pdu->variables->val_len / sizeof(oid)); + upsdebugx(2, "OID value: %s", buf); + break; + default: + return FALSE; + } + + return TRUE; +} + +/* Return the value stored in OID, which is an OID (sysOID for example) + * and don't try to get the value pointed by this OID (no follow). + * To achieve the latter behavior, use standard nut_snmp_get_{str,int}() */ +bool_t nut_snmp_get_oid(const char *OID, char *buf, size_t buf_len) +{ + struct snmp_pdu *pdu; + bool_t ret = FALSE; + + /* zero out buffer. */ + memset(buf, 0, buf_len); + + upsdebugx(3, "Entering %s()", __func__); + + pdu = nut_snmp_get(OID); + if (pdu == NULL) + return FALSE; + + ret = decode_oid(pdu, buf, buf_len); + + if(ret == FALSE) { + upsdebugx(2, "[%s] unhandled ASN 0x%x received from %s", + upsname?upsname:device_name, pdu->variables->type, OID); + } + + snmp_free_pdu(pdu); + + return ret; +} + bool_t nut_snmp_get_int(const char *OID, long *pval) { + char tmp_buf[SU_LARGEBUF]; struct snmp_pdu *pdu; long value; char *buf; @@ -702,11 +814,22 @@ bool_t nut_snmp_get_int(const char *OID, long *pval) /* convert timeticks to seconds */ value = *pdu->variables->val.integer / 100; break; + case ASN_OBJECT_ID: + snprint_objid (tmp_buf, sizeof(tmp_buf), pdu->variables->val.objid, pdu->variables->val_len / sizeof(oid)); + upsdebugx(2, "Received an OID value: %s", tmp_buf); + /* Try to get the value of the pointed OID */ + if (nut_snmp_get_int(tmp_buf, &value) == FALSE) { + upsdebugx(3, "Failed to retrieve OID value, using fallback"); + /* Otherwise return the last part of the returned OID (ex: 1.2.3 => 3) */ + char *oid_leaf = strrchr(tmp_buf, '.'); + value = strtol(oid_leaf+1, NULL, 0); + upsdebugx(3, "Fallback value: %ld", value); + } + break; default: upslogx(LOG_ERR, "[%s] unhandled ASN 0x%x received from %s", upsname?upsname:device_name, pdu->variables->type, OID); return FALSE; - break; } snmp_free_pdu(pdu); @@ -725,11 +848,11 @@ bool_t nut_snmp_set(const char *OID, char type, const char *value) oid name[MAX_OID_LEN]; size_t name_len = MAX_OID_LEN; - upsdebugx(1, "entering nut_snmp_set (%s, %c, %s)", OID, type, value); + upsdebugx(1, "entering %s(%s, %c, %s)", __func__, OID, type, value); if (!snmp_parse_oid(OID, name, &name_len)) { - upslogx(LOG_ERR, "[%s] nut_snmp_set: %s: %s", - upsname?upsname:device_name, OID, snmp_api_errstring(snmp_errno)); + upslogx(LOG_ERR, "[%s] %s: %s: %s", + upsname?upsname:device_name, __func__, OID, snmp_api_errstring(snmp_errno)); return FALSE; } @@ -738,8 +861,8 @@ bool_t nut_snmp_set(const char *OID, char type, const char *value) fatalx(EXIT_FAILURE, "Not enough memory"); if (snmp_add_var(pdu, name, name_len, type, value)) { - upslogx(LOG_ERR, "[%s] nut_snmp_set: %s: %s", - upsname?upsname:device_name, OID, snmp_api_errstring(snmp_errno)); + upslogx(LOG_ERR, "[%s] %s: %s: %s", + upsname?upsname:device_name, __func__, OID, snmp_api_errstring(snmp_errno)); return FALSE; } @@ -750,7 +873,7 @@ bool_t nut_snmp_set(const char *OID, char type, const char *value) ret = TRUE; else nut_snmp_perror(g_snmp_sess_p, status, response, - "nut_snmp_set: can't set %s", OID); + "%s: can't set %s", __func__, OID); snmp_free_pdu(response); return ret; @@ -847,12 +970,17 @@ static void disable_transfer_oids(void) /* universal function to add or update info element. */ void su_setinfo(snmp_info_t *su_info_p, const char *value) { - upsdebugx(1, "entering su_setinfo(%s)", su_info_p->info_type); + info_lkp_t *info_lkp; + + upsdebugx(1, "entering %s(%s)", __func__, su_info_p->info_type); if (SU_TYPE(su_info_p) == SU_TYPE_CMD) return; - if (strcasecmp(su_info_p->info_type, "ups.status")) + /* ups.status and {ups, Lx, outlet, outlet.group}.alarm have special + * handling, not here! */ + if ((strcasecmp(su_info_p->info_type, "ups.status")) + && (strcasecmp(strrchr(su_info_p->info_type, '.'), ".alarm"))) { if (value != NULL) dstate_setinfo(su_info_p->info_type, "%s", value); @@ -862,6 +990,19 @@ void su_setinfo(snmp_info_t *su_info_p, const char *value) dstate_setflags(su_info_p->info_type, su_info_p->info_flags); dstate_setaux(su_info_p->info_type, su_info_p->info_len); + /* Set enumerated values, only if the data has ST_FLAG_RW and there + * are lookup values */ + if ((su_info_p->info_flags & ST_FLAG_RW) && su_info_p->oid2info) { + + upsdebugx(3, "%s: adding enumerated values", __func__); + + /* Loop on all existing values */ + for (info_lkp = su_info_p->oid2info; info_lkp != NULL + && info_lkp->info_value != NULL; info_lkp++) { + dstate_addenum(su_info_p->info_type, "%s", info_lkp->info_value); + } + } + /* Commit the current value, to avoid staleness with huge * data collections on slow devices */ dstate_dataok(); @@ -872,7 +1013,7 @@ void su_status_set(snmp_info_t *su_info_p, long value) { const char *info_value = NULL; - upsdebugx(2, "SNMP UPS driver : entering su_status_set()"); + upsdebugx(2, "SNMP UPS driver: entering %s()", __func__); if ((info_value = su_find_infoval(su_info_p->oid2info, value)) != NULL) { @@ -883,6 +1024,49 @@ void su_status_set(snmp_info_t *su_info_p, long value) /* TODO: else */ } +void su_alarm_set(snmp_info_t *su_info_p, long value) +{ + const char *info_value = NULL; + char alarm_info_value[SU_LARGEBUF]; + /* number of the outlet or phase */ + int item_number = -1; + + upsdebugx(2, "SNMP UPS driver: entering %s(%s)", __func__, su_info_p->info_type); + + if ((info_value = su_find_infoval(su_info_p->oid2info, value)) != NULL + && info_value[0] != 0) + { + /* Special handling for outlet & outlet groups alarms */ + if ((su_info_p->flags & SU_OUTLET) + || (su_info_p->flags & SU_OUTLET_GROUP)) { + /* Extract template number */ + item_number = extract_template_number(su_info_p->flags, su_info_p->info_type); + + /* Inject in the alarm string */ + snprintf(alarm_info_value, sizeof(alarm_info_value), + "outlet%s %i %s", (su_info_p->flags & SU_OUTLET_GROUP) ? " group" : "", + item_number, info_value); + info_value = &alarm_info_value[0]; + } + /* Special handling for phase alarms + * Note that SU_*PHASE flags are cleared, so match the 'Lx' + * start of path */ + if (su_info_p->info_type[0] == 'L') { + /* Extract phase number */ + item_number = atoi(su_info_p->info_type+1); + + /* Inject in the alarm string */ + snprintf(alarm_info_value, sizeof(alarm_info_value), + "phase L%i %s", item_number, info_value); + info_value = &alarm_info_value[0]; + } + + /* Set the alarm value */ + alarm_set(info_value); + } + /* TODO: else */ +} + /* find info element definition in my info array. */ snmp_info_t *su_find_info(const char *type) { @@ -890,11 +1074,11 @@ snmp_info_t *su_find_info(const char *type) for (su_info_p = &snmp_info[0]; su_info_p->info_type != NULL ; su_info_p++) if (!strcasecmp(su_info_p->info_type, type)) { - upsdebugx(3, "su_find_info: \"%s\" found", type); + upsdebugx(3, "%s: \"%s\" found", __func__, type); return su_info_p; } - upsdebugx(3, "su_find_info: unknown info type (%s)", type); + upsdebugx(3, "%s: unknown info type (%s)", __func__, type); return NULL; } @@ -902,7 +1086,9 @@ snmp_info_t *su_find_info(const char *type) * Return a pointer to a mib2nut definition if found, NULL otherwise */ mib2nut_info_t *match_sysoid() { + snmp_info_t *su_info_p; char sysOID_buf[LARGEBUF]; + char testOID_buf[LARGEBUF]; oid device_sysOID[MAX_OID_LEN]; size_t device_sysOID_len = MAX_OID_LEN; oid mib2nut_sysOID[MAX_OID_LEN]; @@ -910,15 +1096,15 @@ mib2nut_info_t *match_sysoid() int i; /* Retrieve sysOID value of this device */ - if (nut_snmp_get_str(SYSOID_OID, sysOID_buf, sizeof(sysOID_buf), NULL)) + if (nut_snmp_get_oid(SYSOID_OID, sysOID_buf, sizeof(sysOID_buf)) == TRUE) { - upsdebugx(1, "match_sysoid: device sysOID value = %s", sysOID_buf); + upsdebugx(1, "%s: device sysOID value = %s", __func__, sysOID_buf); /* Build OIDs for comparison */ if (!read_objid(sysOID_buf, device_sysOID, &device_sysOID_len)) { - upsdebugx(2, "match_sysoid: can't build device_sysOID %s: %s", - sysOID_buf, snmp_api_errstring(snmp_errno)); + upsdebugx(2, "%s: can't build device_sysOID %s: %s", + __func__, sysOID_buf, snmp_api_errstring(snmp_errno)); return FALSE; } @@ -926,7 +1112,7 @@ mib2nut_info_t *match_sysoid() /* Now, iterate on mib2nut definitions */ for (i = 0; mib2nut[i] != NULL; i++) { - upsdebugx(1, "match_sysoid: checking MIB %s", mib2nut[i]->mib_name); + upsdebugx(1, "%s: checking MIB %s", __func__, mib2nut[i]->mib_name); if (mib2nut[i]->sysOID == NULL) continue; @@ -937,17 +1123,34 @@ mib2nut_info_t *match_sysoid() if (!read_objid(mib2nut[i]->sysOID, mib2nut_sysOID, &mib2nut_sysOID_len)) { - upsdebugx(2, "match_sysoid: can't build OID %s: %s", - sysOID_buf, snmp_api_errstring(snmp_errno)); + upsdebugx(2, "%s: can't build OID %s: %s", + __func__, sysOID_buf, snmp_api_errstring(snmp_errno)); /* Try to continue anyway! */ continue; } /* Now compare these */ - upsdebugx(1, "match_sysoid: comparing %s with %s", sysOID_buf, mib2nut[i]->sysOID); + upsdebugx(1, "%s: comparing %s with %s", __func__, sysOID_buf, mib2nut[i]->sysOID); if (!netsnmp_oid_equals(device_sysOID, device_sysOID_len, mib2nut_sysOID, mib2nut_sysOID_len)) { - upsdebugx(2, "match_sysoid: sysOID matches MIB '%s'!", mib2nut[i]->mib_name); + upsdebugx(2, "%s: sysOID matches MIB '%s'!", __func__, mib2nut[i]->mib_name); + /* Counter verify, using {ups,device}.model */ + snmp_info = mib2nut[i]->snmp_info; + su_info_p = su_find_info("ups.model"); + /* Try to get device.model if ups.model is not available */ + if (su_info_p == NULL) + su_info_p = su_find_info("device.model"); + + if (su_info_p != NULL) { + upsdebugx(2, "Testing %s using OID %s", su_info_p->info_type, su_info_p->OID); + if (nut_snmp_get_str(su_info_p->OID, testOID_buf, LARGEBUF, NULL) != TRUE) { + upsdebugx(2, "%s: testOID provided and doesn't match MIB '%s'!", __func__, mib2nut[i]->mib_name); + snmp_info = NULL; + continue; + } + else + upsdebugx(2, "%s: testOID provided and matches MIB '%s'!", __func__, mib2nut[i]->mib_name); + } return mib2nut[i]; } } @@ -968,9 +1171,10 @@ bool_t load_mib2nut(const char *mib) { int i; char buf[LARGEBUF]; + snmp_info_t *su_info_p; mib2nut_info_t *m2n = NULL; - upsdebugx(2, "SNMP UPS driver : entering load_mib2nut(%s)", mib); + upsdebugx(2, "SNMP UPS driver: entering %s(%s)", __func__, mib); /* First, try to match against sysOID, if no MIB was provided. * This should speed up init stage @@ -992,8 +1196,21 @@ bool_t load_mib2nut(const char *mib) upsdebugx(1, "load_mib2nut: trying classic method with '%s' mib", mib2nut[i]->mib_name); /* Classic method: test an OID specific to this MIB */ - if (!nut_snmp_get_str(mib2nut[i]->oid_auto_check, buf, sizeof(buf), NULL)) { - continue; + snmp_info = mib2nut[i]->snmp_info; + su_info_p = su_find_info("ups.model"); + /* Try to get device.model if ups.model is not available */ + if (su_info_p == NULL) + su_info_p = su_find_info("device.model"); + + if (su_info_p != NULL) { + upsdebugx(2, "Testing %s using OID %s", su_info_p->info_type, su_info_p->OID); + if (nut_snmp_get_str(su_info_p->OID, buf, LARGEBUF, NULL) != TRUE) { + upsdebugx(2, "%s: testOID provided and doesn't match MIB '%s'!", __func__, mib2nut[i]->mib_name); + snmp_info = NULL; + continue; + } + else + upsdebugx(2, "%s: testOID provided and matches MIB '%s'!", __func__, mib2nut[i]->mib_name); } /* MIB found */ m2n = mib2nut[i]; @@ -1030,13 +1247,13 @@ long su_find_valinfo(info_lkp_t *oid2info, const char* value) (strcmp(info_lkp->info_value, "NULL")); info_lkp++) { if (!(strcmp(info_lkp->info_value, value))) { - upsdebugx(1, "su_find_valinfo: found %s (value: %s)", - info_lkp->info_value, value); + upsdebugx(1, "%s: found %s (value: %s)", + __func__, info_lkp->info_value, value); return info_lkp->oid_value; } } - upsdebugx(1, "su_find_valinfo: no matching INFO_* value for this OID value (%s)", value); + upsdebugx(1, "%s: no matching INFO_* value for this OID value (%s)", __func__, value); return -1; } @@ -1046,37 +1263,44 @@ const char *su_find_infoval(info_lkp_t *oid2info, long value) info_lkp_t *info_lkp; for (info_lkp = oid2info; (info_lkp != NULL) && - (strcmp(info_lkp->info_value, "NULL")) && (info_lkp->info_value != NULL); info_lkp++) { + (info_lkp->info_value != NULL) && (strcmp(info_lkp->info_value, "NULL")); info_lkp++) { if (info_lkp->oid_value == value) { - upsdebugx(1, "su_find_infoval: found %s (value: %ld)", - info_lkp->info_value, value); + upsdebugx(1, "%s: found %s (value: %ld)", + __func__, info_lkp->info_value, value); return info_lkp->info_value; } } - upsdebugx(1, "su_find_infoval: no matching INFO_* value for this OID value (%ld)", value); + upsdebugx(1, "%s: no matching INFO_* value for this OID value (%ld)", __func__, value); return NULL; } +/* FIXME: doesn't work with templates! */ static void disable_competition(snmp_info_t *entry) { snmp_info_t *p; for(p=snmp_info; p->info_type!=NULL; p++) { if(p!=entry && !strcmp(p->info_type, entry->info_type)) { - upsdebugx(2, "disable_competition: disabling %s %s", - p->info_type, p->OID); + upsdebugx(2, "%s: disabling %s %s", + __func__, p->info_type, p->OID); p->flags &= ~SU_FLAG_OK; } } } -/* instantiate an snmp_info_t from a template. - * mostly (only?) useful for outlet templates. +/*********************************************************************** + * Template handling functions + **********************************************************************/ + +/* Instantiate an snmp_info_t from a template. + * Useful for outlet and outlet.group templates. * Note: remember to adapt info_type, OID and optionaly dfl */ snmp_info_t *instantiate_info(snmp_info_t *info_template, snmp_info_t *new_instance) { + upsdebugx(1, "%s(%s)", __func__, info_template->info_type); + /* sanity check */ if (info_template == NULL) return NULL; @@ -1097,11 +1321,12 @@ snmp_info_t *instantiate_info(snmp_info_t *info_template, snmp_info_t *new_insta new_instance->oid2info = info_template->oid2info; new_instance->setvar = info_template->setvar; + upsdebugx(2, "instantiate_info: template instantiated"); return new_instance; } -/* free a dynamically allocated snmp_info_t. - * mostly (only?) useful for outlet templates */ +/* Free a dynamically allocated snmp_info_t. + * Useful for outlet and outlet.group templates */ void free_info(snmp_info_t *su_info_p) { /* sanity check */ @@ -1117,61 +1342,191 @@ void free_info(snmp_info_t *su_info_p) free (su_info_p); } -/* return the base SNMP index (0 or 1) to start outlet iteration on the MIB, - * based on a test using a template OID */ -int base_snmp_outlet_index(const char *OID_template) +/* return the base SNMP index (0 or 1) to start template iteration on + * the MIB, based on a test using a template OID */ +int base_snmp_template_index(const char *OID_template) { - int base_index = outlet_index_base; + int base_index = template_index_base; char test_OID[SU_INFOSIZE]; - if (outlet_index_base == -1) + if (template_index_base == -1) { /* not initialised yet */ for (base_index = 0 ; base_index < 2 ; base_index++) { - sprintf(test_OID, OID_template, base_index); + snprintf(test_OID, sizeof(test_OID), OID_template, base_index); if (nut_snmp_get(test_OID) != NULL) break; } - outlet_index_base = base_index; + template_index_base = base_index; } - upsdebugx(3, "base_snmp_outlet_index: %i", outlet_index_base); + upsdebugx(3, "%s: %i", __func__, template_index_base); return base_index; } -/* return the NUT offset (increment) based on outlet_index_base - * ie (outlet_index_base == 0) => increment +1 - * (outlet_index_base == 1) => increment +0 */ -int base_nut_outlet_offset(void) +/* return the NUT offset (increment) based on template_index_base + * ie (template_index_base == 0) => increment +1 + * (template_index_base == 1) => increment +0 */ +int base_nut_template_offset(void) { - return (outlet_index_base==0)?1:0; + return (template_index_base==0)?1:0; } -/* try to determine the number of outlets, using a template definition, - * that we walk, until we can't get anymore values */ -static int guestimate_outlet_count(const char *OID_template) +/* Try to determine the number of items (outlets, outlet groups, ...), + * using a template definition. Walk through the template until we can't + * get anymore values. I.e., if we can iterate up to 8 item, return 8 */ +static int guestimate_template_count(const char *OID_template) { int base_index = 0; char test_OID[SU_INFOSIZE]; int base_count; - upsdebugx(1, "guestimate_outlet_count(%s)", OID_template); + upsdebugx(1, "%s(%s)", __func__, OID_template); /* Determine if OID index starts from 0 or 1? */ - sprintf(test_OID, OID_template, base_index); + snprintf(test_OID, sizeof(test_OID), OID_template, base_index); if (nut_snmp_get(test_OID) == NULL) base_index++; /* Now, actually iterate */ for (base_count = 0 ; ; base_count++) { - sprintf(test_OID, OID_template, base_index + base_count); + snprintf(test_OID, sizeof(test_OID), OID_template, base_index + base_count); if (nut_snmp_get(test_OID) == NULL) break; } - upsdebugx(3, "guestimate_outlet_count: %i", base_count); + upsdebugx(3, "%s: %i", __func__, base_count); return base_count; } +/* Process template definition, instantiate and get data or register + * command + * type: outlet, outlet.group */ +bool_t process_template(int mode, const char* type, snmp_info_t *su_info_p) +{ + /* Default to TRUE, and leave to get_and_process_data() to set + * to FALSE when actually getting data from devices, to avoid false + * negative with server side data */ + bool_t status = TRUE; + int cur_template_number = 1; + int cur_nut_index = 0; + int template_count = 0; + snmp_info_t cur_info_p; + char template_count_var[SU_BUFSIZE]; + + upsdebugx(1, "%s template definition found (%s)...", type, su_info_p->info_type); + + snprintf(template_count_var, sizeof(template_count_var), "%s.count", type); + + if(dstate_getinfo(template_count_var) == NULL) { + /* FIXME: should we disable it? + * su_info_p->flags &= ~SU_FLAG_OK; + * or rely on guestimation? */ + template_count = guestimate_template_count(su_info_p->OID); + /* Publish the count estimation */ + dstate_setinfo(template_count_var, "%i", template_count); + } + else { + template_count = atoi(dstate_getinfo(template_count_var)); + } + + /* Only instantiate templates if needed! */ + if (template_count > 0) { + /* general init of data using the template */ + instantiate_info(su_info_p, &cur_info_p); + + for (cur_template_number = base_snmp_template_index(su_info_p->OID) ; + cur_template_number < (template_count + base_snmp_template_index(su_info_p->OID)) ; + cur_template_number++) + { + cur_nut_index = cur_template_number + base_nut_template_offset(); + snprintf((char*)cur_info_p.info_type, SU_INFOSIZE, + su_info_p->info_type, cur_nut_index); + + /* check if default value is also a template */ + if ((cur_info_p.dfl != NULL) && + (strstr(su_info_p->dfl, "%i") != NULL)) { + cur_info_p.dfl = (char *)xmalloc(SU_INFOSIZE); + snprintf((char *)cur_info_p.dfl, SU_INFOSIZE, su_info_p->dfl, cur_nut_index); + } + + if (cur_info_p.OID != NULL) { + snprintf((char *)cur_info_p.OID, SU_INFOSIZE, su_info_p->OID, cur_template_number); + + /* add instant commands to the info database. */ + if (SU_TYPE(su_info_p) == SU_TYPE_CMD) { + upsdebugx(1, "Adding template command %s", cur_info_p.info_type); + /* FIXME: only add if "su_ups_get(cur_info_p) == TRUE" */ + if (mode == SU_WALKMODE_INIT) + dstate_addcmd(cur_info_p.info_type); + } + else /* get and process this data */ + status = get_and_process_data(mode, &cur_info_p); + } else { + /* server side (ABSENT) data */ + su_setinfo(&cur_info_p, NULL); + } + /* set back the flag */ + su_info_p->flags = cur_info_p.flags; + } + free((char*)cur_info_p.info_type); + if (cur_info_p.OID != NULL) + free((char*)cur_info_p.OID); + if ((cur_info_p.dfl != NULL) && + (strstr(su_info_p->dfl, "%i") != NULL)) + free((char*)cur_info_p.dfl); + } + else { + upsdebugx(1, "No %s present, discarding template definition...", type); + } + return status; +} + +/* Return the type of template, according to a variable name. + * Return: SU_OUTLET_GROUP, SU_OUTLET or 0 if not a template */ +int get_template_type(const char* varname) +{ + /* Check if it is outlet / outlet.group */ + if (!strncmp(varname, "outlet.group", 12)) { + return SU_OUTLET_GROUP; + } + else if (!strncmp(varname, "outlet", 6)) { + return SU_OUTLET_GROUP; + } + else { + upsdebugx(2, "Unknown template type: %s", varname); + return 0; + } +} + +/* Extract the id number of an instantiated template. + * Example: return '1' for type = 'outlet.1.desc', -1 if unknown */ +int extract_template_number(int template_type, const char* varname) +{ + const char* item_number_ptr = NULL; + int item_number = -1; + + if (template_type & SU_OUTLET_GROUP) + item_number_ptr = &varname[12]; + else if (template_type & SU_OUTLET) + item_number_ptr = &varname[6]; + else + return -1; + + item_number = atoi(++item_number_ptr); + upsdebugx(3, "%s: item %i", __func__, item_number); + return item_number; +} + +/* Extract the id number of a template from a variable name. + * Example: return '1' for type = 'outlet.1.desc' */ +int extract_template_number_from_snmp_info_t(const char* varname) +{ + return extract_template_number(get_template_type(varname), varname); +} + +/* end of template functions */ + + /* process a single data from a walk */ bool_t get_and_process_data(int mode, snmp_info_t *su_info_p) { @@ -1226,7 +1581,8 @@ bool_t snmp_ups_walk(int mode) /* skip instcmd, not linked to outlets */ if ((SU_TYPE(su_info_p) == SU_TYPE_CMD) - && !(su_info_p->flags & SU_OUTLET)) { + && !(su_info_p->flags & SU_OUTLET) + && !(su_info_p->flags & SU_OUTLET_GROUP)) { upsdebugx(1, "SU_CMD_MASK => %s", su_info_p->OID); continue; } @@ -1239,11 +1595,12 @@ bool_t snmp_ups_walk(int mode) su_info_p->flags & SU_FLAG_STATIC) continue; - /* set default value if we cannot fetch it */ + /* Set default value if we cannot fetch it */ /* and set static flag on this element. - * not applicable to outlets (need SU_FLAG_STATIC tagging) */ + * Not applicable to outlets (need SU_FLAG_STATIC tagging) */ if ((su_info_p->flags & SU_FLAG_ABSENT) - && !(su_info_p->flags & SU_OUTLET)) { + && !(su_info_p->flags & SU_OUTLET) + && !(su_info_p->flags & SU_OUTLET_GROUP)) { if (mode == SU_WALKMODE_INIT) { if (su_info_p->dfl) { /* Set default value if we cannot fetch it from ups. */ @@ -1255,13 +1612,20 @@ bool_t snmp_ups_walk(int mode) } /* check stale elements only on each PN_STALE_RETRY iteration. */ - if ((su_info_p->flags & SU_FLAG_STALE) && +/* if ((su_info_p->flags & SU_FLAG_STALE) && (iterations % SU_STALE_RETRY) != 0) continue; - +*/ + /* Filter 1-phase Vs 3-phase according to {input,output}.phase. + * Non matching items are disabled, and flags are cleared at + * init time */ if (su_info_p->flags & SU_INPHASES) { - upsdebugx(1, "Check input_phases"); + upsdebugx(1, "Check input_phases (%i)", input_phases); if (input_phases == 0) { + /* FIXME: to get from input.phases + * this would avoid the use of the SU_FLAG_SETINT flag + * and potential human-error to not declare the right way. + * It would also free the slot for SU_OUTLET_GROUP */ continue; } if (su_info_p->flags & SU_INPUT_1) { @@ -1290,6 +1654,7 @@ bool_t snmp_ups_walk(int mode) if (su_info_p->flags & SU_OUTPHASES) { upsdebugx(1, "Check output_phases"); if (output_phases == 0) { + /* FIXME: same as for input_phases */ continue; } if (su_info_p->flags & SU_OUTPUT_1) { @@ -1318,6 +1683,7 @@ bool_t snmp_ups_walk(int mode) if (su_info_p->flags & SU_BYPPHASES) { upsdebugx(1, "Check bypass_phases"); if (bypass_phases == 0) { + /* FIXME: same as for input_phases */ continue; } if (su_info_p->flags & SU_BYPASS_1) { @@ -1345,77 +1711,18 @@ bool_t snmp_ups_walk(int mode) /* process outlet template definition */ if (su_info_p->flags & SU_OUTLET) { - upsdebugx(1, "outlet template definition found (%s)...", su_info_p->info_type); - int cur_outlet_number = 1; - int cur_nut_index = 0; - int outlet_count = 0; - snmp_info_t cur_info_p; - - if(dstate_getinfo("outlet.count") == NULL) { - /* FIXME: should we disable it? - * su_info_p->flags &= ~SU_FLAG_OK; - * or rely on guestimation? */ - if ((outlet_count = guestimate_outlet_count(su_info_p->OID)) == -1) { - /* Failed */ - continue; - } - else { - /* Publish the count estimation */ - dstate_setinfo("outlet.count", "%i", outlet_count); - } - } - else { - outlet_count = atoi(dstate_getinfo("outlet.count")); - } - - /* Only instantiate outlets if needed! */ - if (outlet_count > 0) { - /* general init of data using the template */ - instantiate_info(su_info_p, &cur_info_p); - - for (cur_outlet_number = base_snmp_outlet_index(su_info_p->OID) ; - cur_outlet_number < (outlet_count + base_snmp_outlet_index(su_info_p->OID)) ; - cur_outlet_number++) - { - cur_nut_index = cur_outlet_number + base_nut_outlet_offset(); - sprintf((char*)cur_info_p.info_type, su_info_p->info_type, - cur_nut_index); - - /* check if default value is also a template */ - if ((cur_info_p.dfl != NULL) && - (strstr(su_info_p->dfl, "%i") != NULL)) { - cur_info_p.dfl = (char *)xmalloc(SU_INFOSIZE); - sprintf((char *)cur_info_p.dfl, su_info_p->dfl, cur_nut_index); - } - - if (cur_info_p.OID != NULL) { - sprintf((char *)cur_info_p.OID, su_info_p->OID, cur_outlet_number); - - /* add outlet instant commands to the info database. */ - if (SU_TYPE(su_info_p) == SU_TYPE_CMD) { - /* FIXME: only add if "su_ups_get(cur_info_p) == TRUE" */ - if (mode == SU_WALKMODE_INIT) - dstate_addcmd(cur_info_p.info_type); - } - else /* get and process this data */ - status = get_and_process_data(mode, &cur_info_p); - } else { - /* server side (ABSENT) data */ - su_setinfo(&cur_info_p, NULL); - } - /* set back the flag */ - su_info_p->flags = cur_info_p.flags; - } - free((char*)cur_info_p.info_type); - if (cur_info_p.OID != NULL) - free((char*)cur_info_p.OID); - if ((cur_info_p.dfl != NULL) && - (strstr(su_info_p->dfl, "%i") != NULL)) - free((char*)cur_info_p.dfl); - } - else { - upsdebugx(1, "No outlet present, discarding template definition..."); - } + /* Skip commands after init */ + if ((SU_TYPE(su_info_p) == SU_TYPE_CMD) && (mode == SU_WALKMODE_UPDATE)) + continue; + else + status = process_template(mode, "outlet", su_info_p); + } + else if (su_info_p->flags & SU_OUTLET_GROUP) { + /* Skip commands after init */ + if ((SU_TYPE(su_info_p) == SU_TYPE_CMD) && (mode == SU_WALKMODE_UPDATE)) + continue; + else + status = process_template(mode, "outlet.group", su_info_p); } else { /* get and process this data */ @@ -1424,7 +1731,6 @@ bool_t snmp_ups_walk(int mode) } /* for (su_info_p... */ iterations++; - return status; } @@ -1433,12 +1739,13 @@ bool_t su_ups_get(snmp_info_t *su_info_p) static char buf[SU_INFOSIZE]; bool_t status; long value; + const char *strValue = NULL; struct snmp_pdu ** pdu_array; struct snmp_pdu * current_pdu; alarms_info_t * alarms; int index = 0; - upsdebugx(2, "su_ups_get: %s %s", su_info_p->info_type, su_info_p->OID); + upsdebugx(2, "%s: %s %s", __func__, su_info_p->info_type, su_info_p->OID); if (!strcasecmp(su_info_p->info_type, "ups.status")) { @@ -1453,12 +1760,33 @@ bool_t su_ups_get(snmp_info_t *su_info_p) return status; } + /* Handle 'ups.alarm', 'outlet.n.alarm' and 3phase 'Lx.alarm', + * nothing else! */ + if (!strcmp(strrchr(su_info_p->info_type, '.'), ".alarm")) { + + upsdebugx(2, "Processing alarm: %s", su_info_p->info_type); + + status = nut_snmp_get_int(su_info_p->OID, &value); + if (status == TRUE) + { + su_alarm_set(su_info_p, value); + upsdebugx(2, "=> value: %ld", value); + } + else upsdebugx(2, "=> Failed"); + + return status; + } + + /* Walk a subtree (array) of alarms, composed of OID references. + * The object referenced should not be accessible, but rather when + * present, this means that the alarm condition is TRUE. + * Only present in powerware-mib.c for now */ if (!strcasecmp(su_info_p->info_type, "ups.alarms")) { status = nut_snmp_get_int(su_info_p->OID, &value); if (status == TRUE) { - upsdebugx(2, "=> value: %ld", value); + upsdebugx(2, "=> %ld alarms present", value); if( value > 0 ) { - pdu_array = nut_snmp_walk(su_info_p->OID,INT_MAX); + pdu_array = nut_snmp_walk(su_info_p->OID, INT_MAX); if(pdu_array == NULL) { upsdebugx(2, "=> Walk failed"); return FALSE; @@ -1466,15 +1794,26 @@ bool_t su_ups_get(snmp_info_t *su_info_p) current_pdu = pdu_array[index]; while(current_pdu) { - decode_str(current_pdu,buf,sizeof(buf),NULL); - alarms = alarms_info; - while( alarms->OID ) { - if(!strcmp(buf+1,alarms_info->OID)) { - upsdebugx(3, "Alarm OID %s found => %s", alarms->OID, alarms->info_value); - status_set(alarms->info_value); - break; + /* Retrieve the OID name, for comparison */ + if (decode_oid(current_pdu, buf, sizeof(buf)) == TRUE) { + alarms = alarms_info; + while( alarms->OID ) { + if(!strcmp(buf, alarms->OID)) { + upsdebugx(3, "Alarm OID found => %s", alarms->OID); + /* Check for ups.status value */ + if (alarms->status_value) { + upsdebugx(3, "Alarm value (status) found => %s", alarms->status_value); + status_set(alarms->status_value); + } + /* Check for ups.alarm value */ + if (alarms->alarm_value) { + upsdebugx(3, "Alarm value (alarm) found => %s", alarms->alarm_value); + alarm_set(alarms->alarm_value); + } + break; + } + alarms++; } - alarms++; } index++; current_pdu = pdu_array[index]; @@ -1482,7 +1821,6 @@ bool_t su_ups_get(snmp_info_t *su_info_p) nut_snmp_free(pdu_array); } } - else { upsdebugx(2, "=> Failed"); } @@ -1523,7 +1861,9 @@ bool_t su_ups_get(snmp_info_t *su_info_p) return TRUE; } - if (su_info_p->info_flags == 0) { + if (su_info_p->info_flags & ST_FLAG_STRING) { + status = nut_snmp_get_str(su_info_p->OID, buf, sizeof(buf), su_info_p->oid2info); + } else { status = nut_snmp_get_int(su_info_p->OID, &value); if (status == TRUE) { if (su_info_p->flags&SU_FLAG_NEGINVALID && value<0) { @@ -1538,10 +1878,12 @@ bool_t su_ups_get(snmp_info_t *su_info_p) upsdebugx(1, "setvar %s", su_info_p->OID); *su_info_p->setvar = value; } - snprintf(buf, sizeof(buf), "%.2f", value * su_info_p->info_len); + /* Check if there is a value to be looked up */ + if ((strValue = su_find_infoval(su_info_p->oid2info, value)) != NULL) + snprintf(buf, sizeof(buf), "%s", strValue); + else + snprintf(buf, sizeof(buf), "%.2f", value * su_info_p->info_len); } - } else { - status = nut_snmp_get_str(su_info_p->OID, buf, sizeof(buf), su_info_p->oid2info); } if (status == TRUE) { @@ -1560,37 +1902,53 @@ int su_setvar(const char *varname, const char *val) snmp_info_t *su_info_p = NULL; bool_t status; int retval = STAT_SET_FAILED; - int value = -1; + long value = -1; + /* normal (default), outlet, or outlet group variable */ + int vartype = get_template_type(varname); - upsdebugx(2, "entering su_setvar(%s, %s)", varname, val); + upsdebugx(2, "entering %s(%s, %s)", __func__, varname, val); + /* Check if it is outlet / outlet.group */ if (strncmp(varname, "outlet", 6)) su_info_p = su_find_info(varname); else { snmp_info_t *tmp_info_p; - char *outlet_number_ptr = strchr(varname, '.'); - int outlet_number = atoi(++outlet_number_ptr); - if (dstate_getinfo("outlet.count") == NULL) { - upsdebugx(2, "su_setvar: can't get outlet.count..."); - return STAT_SET_INVALID; + /* Point the outlet or outlet group number in the string */ + const char *item_number_ptr = NULL; + /* Store the target outlet or group number */ + int item_number = extract_template_number_from_snmp_info_t(varname); + /* Store the total number of outlets or outlet groups */ + int total_items = -1; + + /* Check if it is outlet / outlet.group */ + if (vartype == SU_OUTLET_GROUP) { + total_items = atoi(dstate_getinfo("outlet.group.count")); + item_number_ptr = &varname[12]; + } + else { + total_items = atoi(dstate_getinfo("outlet.count")); + item_number_ptr = &varname[6]; } - upsdebugx(3, "su_setvar: outlet %i / %i", outlet_number, - atoi(dstate_getinfo("outlet.count"))); + item_number = atoi(++item_number_ptr); + upsdebugx(3, "%s: item %i / %i", __func__, item_number, total_items); - /* ensure the outlet number is supported (filtered upstream though)! */ - if (outlet_number > atoi(dstate_getinfo("outlet.count"))) { - /* out of bound outlet number */ - upsdebugx(2, "su_setvar: outlet is out of bound (%i / %s)", - outlet_number, dstate_getinfo("outlet.count")); + /* ensure the item number is supported (filtered upstream though)! */ + if (item_number > total_items) { + /* out of bound item number */ + upsdebugx(2, "%s: item is out of bound (%i / %i)", + __func__, item_number, total_items); return STAT_SET_INVALID; } - /* find back the outlet template */ - char *outlet_varname = (char *)xmalloc(SU_INFOSIZE); - sprintf(outlet_varname, "outlet.%s%s", "%i", strchr(outlet_number_ptr++, '.')); - upsdebugx(3, "su_setvar: searching for template\"%s\"", outlet_varname); - tmp_info_p = su_find_info(outlet_varname); - free(outlet_varname); + /* find back the item template */ + char *item_varname = (char *)xmalloc(SU_INFOSIZE); + snprintf(item_varname, SU_INFOSIZE, "%s.%s%s", + (vartype == SU_OUTLET)?"outlet":"outlet.group", + "%i", strchr(item_number_ptr++, '.')); + + upsdebugx(3, "%s: searching for template\"%s\"", __func__, item_varname); + tmp_info_p = su_find_info(item_varname); + free(item_varname); /* for an snmp_info_t instance */ su_info_p = instantiate_info(tmp_info_p, su_info_p); @@ -1599,35 +1957,37 @@ int su_setvar(const char *varname, const char *val) if ((su_info_p->dfl != NULL) && (strstr(tmp_info_p->dfl, "%i") != NULL)) { su_info_p->dfl = (char *)xmalloc(SU_INFOSIZE); - sprintf((char *)su_info_p->dfl, tmp_info_p->dfl, - outlet_number - base_nut_outlet_offset()); + snprintf((char *)su_info_p->dfl, sizeof(su_info_p->dfl), tmp_info_p->dfl, + item_number - base_nut_template_offset()); } /* adapt the OID */ if (su_info_p->OID != NULL) { - sprintf((char *)su_info_p->OID, tmp_info_p->OID, - outlet_number - base_nut_outlet_offset()); + snprintf((char *)su_info_p->OID, sizeof(su_info_p->OID), tmp_info_p->OID, + item_number - base_nut_template_offset()); } /* else, don't return STAT_SET_INVALID since we can be setting * a server side variable! */ /* adapt info_type */ if (su_info_p->info_type != NULL) - sprintf((char *)su_info_p->info_type, "%s", varname); + snprintf((char *)su_info_p->info_type, sizeof(su_info_p->info_type), "%s", varname); } if (!su_info_p || !su_info_p->info_type || !(su_info_p->flags & SU_FLAG_OK)) { - upsdebugx(2, "su_setvar: info element unavailable %s", varname); + upsdebugx(2, "%s: info element unavailable %s", __func__, varname); - if (!strncmp(varname, "outlet", 6)) + /* Free template (outlet and outlet.group) */ + if (vartype != 0) free_info(su_info_p); return STAT_SET_UNKNOWN; } if (!(su_info_p->info_flags & ST_FLAG_RW) || su_info_p->OID == NULL) { - upsdebugx(2, "su_setvar: not writable %s", varname); + upsdebugx(2, "%s: not writable %s", __func__, varname); - if (!strncmp(varname, "outlet", 6)) + /* Free template (outlet and outlet.group) */ + if (vartype != 0) free_info(su_info_p); return STAT_SET_INVALID; @@ -1642,22 +2002,25 @@ int su_setvar(const char *varname, const char *val) value = su_find_valinfo(su_info_p->oid2info, val); } else { - value = strtol(val, NULL, 0); + /* Convert value and apply multiplier */ + value = atof(val) / su_info_p->info_len; } /* Actually apply the new value */ status = nut_snmp_set_int(su_info_p->OID, value); } if (status == FALSE) - upsdebugx(1, "su_setvar: cannot set value %s for %s", val, su_info_p->OID); + upsdebugx(1, "%s: cannot set value %s for %s", __func__, val, su_info_p->OID); else { retval = STAT_SET_HANDLED; - upsdebugx(1, "su_setvar: successfully set %s to \"%s\"", varname, val); + upsdebugx(1, "%s: successfully set %s to \"%s\"", __func__, varname, val); - /* update info array */ + /* update info array + * FIXME: we'd better call su_ups_get() to refresh! */ su_setinfo(su_info_p, val); } - if (!strncmp(varname, "outlet", 6)) + /* Free template (outlet and outlet.group) */ + if (vartype != 0) free_info(su_info_p); return retval; @@ -1670,39 +2033,54 @@ int su_instcmd(const char *cmdname, const char *extradata) int status; int retval = STAT_INSTCMD_FAILED; int cmd_offset = 0; + /* normal (default), outlet, or outlet group variable */ + int vartype = get_template_type(cmdname); - upsdebugx(2, "entering su_instcmd(%s, %s)", cmdname, extradata); + upsdebugx(2, "entering %s(%s, %s)", __func__, cmdname, extradata); /* FIXME: this should only apply if strchr(%)! */ if (strncmp(cmdname, "outlet", 6)) { su_info_p = su_find_info(cmdname); } else { +/* FIXME: common with su_setvar(), apart from upsdebugx */ snmp_info_t *tmp_info_p; - char *outlet_number_ptr = strchr(cmdname, '.'); - int outlet_number = atoi(++outlet_number_ptr); - if (dstate_getinfo("outlet.count") == NULL) { - upsdebugx(2, "su_instcmd: can't get outlet.count..."); - return STAT_INSTCMD_UNKNOWN; + /* Point the outlet or outlet group number in the string */ + const char *item_number_ptr = NULL; + /* Store the target outlet or group number */ + int item_number = extract_template_number_from_snmp_info_t(cmdname); + /* Store the total number of outlets or outlet groups */ + int total_items = -1; + + /* Check if it is outlet / outlet.group */ + if (vartype == SU_OUTLET_GROUP) { + total_items = atoi(dstate_getinfo("outlet.group.count")); + item_number_ptr = &cmdname[12]; + } + else { + total_items = atoi(dstate_getinfo("outlet.count")); + item_number_ptr = &cmdname[6]; } - upsdebugx(3, "su_instcmd: outlet %i / %i", outlet_number, - atoi(dstate_getinfo("outlet.count"))); + item_number = atoi(++item_number_ptr); + upsdebugx(3, "%s: item %i / %i", __func__, item_number, total_items); - /* ensure the outlet number is supported! */ - if (outlet_number > atoi(dstate_getinfo("outlet.count"))) { - /* out of bound outlet number */ - upsdebugx(2, "su_instcmd: outlet is out of bound (%i / %s)", - outlet_number, dstate_getinfo("outlet.count")); - return STAT_INSTCMD_INVALID; + /* ensure the item number is supported (filtered upstream though)! */ + if (item_number > total_items) { + /* out of bound item number */ + upsdebugx(2, "%s: item is out of bound (%i / %i)", + __func__, item_number, total_items); + return STAT_SET_INVALID; } + /* find back the item template */ + char *item_varname = (char *)xmalloc(SU_INFOSIZE); + snprintf(item_varname, SU_INFOSIZE, "%s.%s%s", + (vartype == SU_OUTLET)?"outlet":"outlet.group", + "%i", strchr(item_number_ptr++, '.')); - /* find back the outlet template */ - char *outlet_cmdname = (char *)xmalloc(SU_INFOSIZE); - sprintf(outlet_cmdname, "outlet.%s%s", "%i", strchr(outlet_number_ptr++, '.')); - upsdebugx(3, "su_instcmd: searching for template\"%s\"", outlet_cmdname); - tmp_info_p = su_find_info(outlet_cmdname); - free(outlet_cmdname); + upsdebugx(3, "%s: searching for template\"%s\"", __func__, item_varname); + tmp_info_p = su_find_info(item_varname); + free(item_varname); /* for an snmp_info_t instance */ su_info_p = instantiate_info(tmp_info_p, su_info_p); @@ -1711,9 +2089,11 @@ int su_instcmd(const char *cmdname, const char *extradata) if ((su_info_p->dfl != NULL) && (strstr(tmp_info_p->dfl, "%i") != NULL)) { su_info_p->dfl = (char *)xmalloc(SU_INFOSIZE); - sprintf((char *)su_info_p->dfl, tmp_info_p->dfl, - outlet_number - base_nut_outlet_offset()); + snprintf((char *)su_info_p->dfl, sizeof(su_info_p->dfl), tmp_info_p->dfl, + item_number - base_nut_template_offset()); } +/* FIXME: common with su_setvar(), apart from upsdebugx */ + /* adapt the OID */ if (su_info_p->OID != NULL) { /* Workaround buggy Eaton Pulizzi implementation @@ -1723,8 +2103,8 @@ int su_instcmd(const char *cmdname, const char *extradata) cmd_offset++; } - sprintf((char *)su_info_p->OID, tmp_info_p->OID, - outlet_number - base_nut_outlet_offset() + cmd_offset); + snprintf((char *)su_info_p->OID, sizeof(su_info_p->OID), tmp_info_p->OID, + item_number - base_nut_template_offset() + cmd_offset); } else { free_info(su_info_p); return STAT_INSTCMD_UNKNOWN; @@ -1775,7 +2155,7 @@ int su_instcmd(const char *cmdname, const char *extradata) return su_instcmd("load.off.delay", dstate_getinfo("ups.delay.shutdown")); } - upsdebugx(2, "su_instcmd: %s unavailable", cmdname); + upsdebugx(2, "%s: %s unavailable", __func__, cmdname); if (!strncmp(cmdname, "outlet", 6)) free_info(su_info_p); @@ -1791,10 +2171,10 @@ int su_instcmd(const char *cmdname, const char *extradata) } if (status == FALSE) - upsdebugx(1, "su_instcmd: cannot set value for %s", cmdname); + upsdebugx(1, "%s: cannot set value for %s", __func__, cmdname); else { retval = STAT_INSTCMD_HANDLED; - upsdebugx(1, "su_instcmd: successfully sent command %s", cmdname); + upsdebugx(1, "%s: successfully sent command %s", __func__, cmdname); } if (!strncmp(cmdname, "outlet", 6)) @@ -1826,9 +2206,9 @@ static int parse_mibconf_args(int numargs, char **arg) } if (ret == FALSE) - upslogx(LOG_ERR, "su_setvar: cannot set value %s for %s", arg[4], arg[3]); + upslogx(LOG_ERR, "%s: cannot set value %s for %s", __func__, arg[4], arg[3]); else - upsdebugx(1, "su_setvar: successfully set %s to \"%s\"", arg[0], arg[4]); + upsdebugx(1, "%s: successfully set %s to \"%s\"", __func__, arg[0], arg[4]); return 1; } @@ -1849,7 +2229,7 @@ void read_mibconf(char *mib) char fn[SMALLBUF]; PCONF_CTX_t ctx; - upsdebugx(2, "SNMP UPS driver : entering read_mibconf(%s)", mib); + upsdebugx(2, "SNMP UPS driver: entering %s(%s)", __func__, mib); snprintf(fn, sizeof(fn), "%s/snmp/%s.conf", CONFPATH, mib); diff --git a/drivers/snmp-ups.h b/drivers/snmp-ups.h index 8b281df..05e0d3f 100644 --- a/drivers/snmp-ups.h +++ b/drivers/snmp-ups.h @@ -30,9 +30,12 @@ - add syscontact/location (to all mib.h or centralized?) - complete shutdown - add enum values to OIDs. -- optimize network flow by constructing one big packet (calling snmp_add_null_var -for each OID request we made), instead of sending many small packets -- add support for registration and traps (manager mode), +- optimize network flow by: + 1) caching OID values (as in usbhid-ups) with timestamping and lifetime + 2) constructing one big packet (calling snmp_add_null_var + for each OID request we made), instead of sending many small packets +- add support for registration and traps (manager mode) + => Issue: 1 trap listener for N snmp-ups drivers! - complete mib2nut data (add all OID translation to NUT) - externalize mib2nut data in .m2n files and load at driver startup using parseconf()... - adjust information logging. @@ -79,7 +82,9 @@ for each OID request we made), instead of sending many small packets #define DISABLE_MIB_LOADING 1 /* Parameters default values */ -#define DEFAULT_POLLFREQ 30 /* in seconds */ +#define DEFAULT_POLLFREQ 30 /* in seconds */ +#define DEFAULT_NETSNMP_RETRIES 5 +#define DEFAULT_NETSNMP_TIMEOUT 1 /* in seconds */ /* use explicit booleans */ #ifndef FALSE @@ -112,7 +117,7 @@ typedef struct { typedef struct { const char *info_type; /* INFO_ or CMD_ element */ int info_flags; /* flags to set in addinfo */ - float info_len; /* length of strings if STR, + double info_len; /* length of strings if STR, * cmd value if CMD, multiplier otherwise. */ const char *OID; /* SNMP OID or NULL */ const char *dfl; /* default value */ @@ -151,6 +156,8 @@ typedef struct { #define SU_STATUS_NUM_ELEM 4 #define SU_STATUS_INDEX(t) (((t) >> 8) & 7) +#define SU_OUTLET_GROUP (1 << 10) /* outlet group template definition */ + /* Phase specific data */ #define SU_PHASES (0x3F << 12) #define SU_INPHASES (0x3 << 12) @@ -174,6 +181,8 @@ typedef struct { #define SU_VAR_COMMUNITY "community" #define SU_VAR_VERSION "snmp_version" +#define SU_VAR_RETRIES "snmp_retries" +#define SU_VAR_TIMEOUT "snmp_timeout" #define SU_VAR_MIBS "mibs" #define SU_VAR_POLLFREQ "pollfreq" /* SNMP v3 related parameters */ @@ -202,7 +211,8 @@ typedef struct { typedef struct { const char * OID; - const char *info_value; + const char *status_value; /* when not NULL, set ups.status to this */ + const char *alarm_value; /* when not NULL, set ups.alarm to this */ } alarms_info_t; typedef struct { diff --git a/drivers/solis.c b/drivers/solis.c index 380ecc3..23218a5 100644 --- a/drivers/solis.c +++ b/drivers/solis.c @@ -24,6 +24,8 @@ 2005/07/01 - Version 0.50 - add internal e external shutdown programming 2005/08/18 - Version 0.60 - save external shutdown programming to ups, and support new cables for solis 3 + 2015/09/19 - Version 0.65 - patch for correct reading for Microsol Back-Ups BZ1200-BR + (see the version control logs for more recent updates) Microsol contributed with UPS Solis 1.5 HS 1.5 KVA for my tests. @@ -33,14 +35,14 @@ #include #include - +#include #include "main.h" #include "serial.h" #include "solis.h" #include "timehead.h" #define DRIVER_NAME "Microsol Solis UPS driver" -#define DRIVER_VERSION "0.62" +#define DRIVER_VERSION "0.65" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -53,6 +55,7 @@ upsdrv_info_t upsdrv_info = { #define false 0 #define true 1 +#define RESP_END 0xFE #define ENDCHAR 13 /* replies end with CR */ /* solis commands */ #define CMD_UPSCONT 0xCC @@ -90,11 +93,11 @@ upsdrv_info_t upsdrv_info = { #define NO_EVENT "No events\n" #define UPS_TIME "UPS internal Time %0d:%02d:%02d\n" #define PRG_DAYS "Programming Shutdown Sun Mon Tue Wed Thu Fri Sat\n" -#define PRG_ONON "External shutdown programming ative\n" -#define PRG_ONOU "Internal shutdown programming ative\n" +#define PRG_ONON "External shutdown programming active\n" +#define PRG_ONOU "Internal shutdown programming atcive\n" #define TIME_OFF "UPS Time power off %02d:%02d\n" #define TIME_ON "UPS Time power on %02d:%02d\n" -#define PRG_ONOF "Shutdown programming not atived\n" +#define PRG_ONOF "Shutdown programming not activated\n" #define TODAY_DD "Shutdown today at %02d:%02d\n" #define SHUT_NOW "Shutdown now!\n" #endif @@ -129,7 +132,7 @@ static char* convdays( char *cop ) } alt[7] = 0; /* string terminator */ - + stra = strdup( alt ); return stra; } @@ -149,7 +152,7 @@ static int Binary( char *nome ) char ch, cc; int cont=0, nint = 1, tobin=0; int ex, nbin; - + while( *nome && ( cont < 7 ) ) { ch = *nome; if( !(IsBinary( ch ) ) ) @@ -166,7 +169,7 @@ static int Binary( char *nome ) nome++; cont++; } - + if( nint == 0 ) return nint; else @@ -345,7 +348,7 @@ static void confups( void ) for(i=0; i < 12; i++) ser_send_char(upsfd, ConfigPack[i] ); - + } /* print UPS internal variables */ @@ -363,7 +366,7 @@ static void prnInfo( void ) dweek = DaysStd; if( prgups > 0 ) { - + /* this is the string to binary standard */ sunday = ( ( dweek & 0x40 ) == 0x40 ); monday = ( ( dweek & 0x20 ) == 0x20 ); @@ -408,9 +411,9 @@ static int IsToday( unsigned char dweek, int nweek) case 6: /* saturday */ return ( ( ( dweek & 0x01 ) == 0x01 ) ); } - + return 0; - + } static void AutonomyCalc( int iauto ) /* all models */ @@ -451,7 +454,7 @@ static void AutonomyCalc( int iauto ) /* all models */ if( indice < min ) Autonomy = 0; } } - + if( BattExtension > 0 && iauto < 4 ) Autonomy = ( Autonomy * ( BattExtension + bx ) * 1.0 / bx ); @@ -459,7 +462,6 @@ static void AutonomyCalc( int iauto ) /* all models */ static void ScanReceivePack( void ) { - int aux, im, ov = 0; /* model independent data */ @@ -472,7 +474,7 @@ static void ScanReceivePack( void ) /* Days of week if in UPS shutdown programming mode */ if( prgups == 3 ) { DaysStd = revertdays( DaysOnWeek ); - + /* time for programming UPS off */ dhour = RecPack[15]; dmin = RecPack[16]; @@ -480,12 +482,12 @@ static void ScanReceivePack( void ) lhour = RecPack[13]; lmin = RecPack[14]; } - + /* UPS internal time */ ihour = RecPack[11]; imin = RecPack[10]; isec = RecPack[9]; - + if( ( ( 0x01 & RecPack[ 20 ] ) == 0x01 ) ) Out220 = 1; CriticBatt = ( ( 0x04 & RecPack[ 20 ] ) == 0x04 ); @@ -507,14 +509,28 @@ static void ScanReceivePack( void ) im = inds[imodel]; ov = Out220; - if( RecPack[ 6 ] >= 194 ) - InVoltage = RecPack[ 6 ] * ctab[imodel].m_involt194[0] + ctab[imodel].m_involt194[1]; - else - InVoltage = RecPack[ 6 ] * ctab[imodel].m_involt193[0] + ctab[imodel].m_involt193[1]; - + if (SolisModel != 16) { + + if( RecPack[ 6 ] >= 194 ) + InVoltage = RecPack[ 6 ] * ctab[imodel].m_involt194[0] + ctab[imodel].m_involt194[1]; + else + InVoltage = RecPack[ 6 ] * ctab[imodel].m_involt193[0] + ctab[imodel].m_involt193[1]; + } else { + /* Code InVoltage for STAY1200_USB */ + + if ((RecPack[20] & 0x1) == 0) { //IsOutVoltage 220 + + InVoltage = RecPack[2] * ctab[imodel].m_involt193[0] + ctab[imodel].m_involt193[1]; + } else { + + InVoltage = RecPack[2] * ctab[imodel].m_involt193[0] + ctab[imodel].m_involt193[1] - 3.0; + } + } + BattVoltage = RecPack[ 3 ] * ctab[imodel].m_battvolt[0] + ctab[imodel].m_battvolt[1]; - + NominalPower = nompow[im]; + if( SourceFail ) { OutVoltage = RecPack[ 1 ] * ctab[imodel].m_outvolt_i[ov][0] + ctab[imodel].m_outvolt_i[ov][1]; OutCurrent = RecPack[ 5 ] * ctab[imodel].m_outcurr_i[ov][0] + ctab[imodel].m_outcurr_i[ov][1]; @@ -531,13 +547,75 @@ static void ScanReceivePack( void ) InCurrent = ( ctab[imodel].m_incurr[0] * 1.0 / BattVoltage ) - ( AppPower * 1.0 / ctab[imodel].m_incurr[1] ) + OutCurrent *( OutVoltage * 1.0 / InVoltage ); } + if (SolisModel == 16) { + + int configRelay = (RecPack[6] & 0x38) >> 3; + double TENSAO_SAIDA_F1_MR[8] = { 1.1549, 1.0925, 0.0, 0.0, 1.0929, 1.0885, 0.0, 0.8654262224145391 }; + double TENSAO_SAIDA_F2_MR[8] = { -6.9157, 11.026, 10.43, 0.0, -0.6109, 12.18, 0.0, 13.677}; + + const double TENSAO_SAIDA_F2_MI[8] ={ 5.59, 9.47, 13.7, 0.0, 0.0, 0.0, 0.0, 0.0 }; + const double TENSAO_SAIDA_F1_MI[8] = { 7.9, 9.1, 17.6, 0.0, 0.0, 0.0, 0.0, 0.0 }; + + const double corrente_saida_F1_MR = 0.12970000389100012; + const double corrente_saida_F2_MR = 0.5387060281204546; + /* double corrente_saida_F1_MI = 0.1372; + double corrente_saida_F2_MI = 0.3456; */ + + if (SourceFail) { + if (RecPack[20] == 0) { + double a = RecPack[1] * 2; + a /= 128.0; + // a = double sqrt(a); + OutVoltage = RecPack[1] * a * TENSAO_SAIDA_F1_MI[configRelay] + TENSAO_SAIDA_F2_MI[configRelay]; + + } + + } else { + + + OutCurrent = (float)(corrente_saida_F1_MR * RecPack[5] + corrente_saida_F2_MR); + OutVoltage = RecPack[1] * TENSAO_SAIDA_F1_MR[configRelay] + TENSAO_SAIDA_F2_MR[configRelay]; + AppPower = OutCurrent * OutVoltage; + + + + double RealPower = (RecPack[7] + RecPack[8] * 256); + + double potVA1 = 5.968 * AppPower - 284.36; + double potVA2 = 7.149 * AppPower - 567.18; + double potLin = 0.1664 * RealPower + 49.182; + double potRe = 0.1519 * RealPower + 32.644; + if (fabs(potVA1 - RealPower) < fabs(potVA2 - RealPower)) { + RealPower = potLin; + } else { + RealPower = potRe; + + } + if (OutCurrent < 0.7) { + RealPower = AppPower; + } + if (AppPower < RealPower) { + double f = AppPower; + AppPower = RealPower; + RealPower = f; + } + + + + } + } aux = ( RecPack[ 21 ] + RecPack[ 22 ] * 256 ); if( aux > 0 ) InFreq = ctab[imodel].m_infreq * 1.0 / aux; + + /* Specific for STAY1200_USB */ + if (SolisModel == 16) { + InFreq = ((float)(0.37 * (257 - (aux >> 8)))); + } else InFreq = 0; - + /* input voltage offset */ if( InVoltage < InVolt_offset ) { /* all is equal 30 */ InFreq = 0; @@ -552,7 +630,7 @@ static void ScanReceivePack( void ) ChargePowerFactor = 0; OutCurrent = 0; } - + if( im < 3 ) AutonomyCalc( im ); else @@ -600,7 +678,7 @@ static void ScanReceivePack( void ) SourceReturn = true; ser_flush_in(upsfd,"",0); /* clean port */ } - + if( !( SourceFail ) == SourceLast ) { SourceReturn = false; FailureFlag = false; @@ -702,101 +780,107 @@ CommReceive(const char *bufptr, int size) int i, CheckSum, i_end; - if( size==25 ) - Waiting = 0; - - switch( Waiting ) - { - /* normal package */ - case 0: - { - if( size == 25 ) { - i_end = 25; - for( i = 0 ; i < i_end ; ++i ) { - RecPack[i] = *bufptr; - bufptr++; + if( size == 25 ) { + i_end = 25; + for( i = 0 ; i < i_end ; ++i ) { + RecPack[i] = *bufptr; + bufptr++; } - + if(nut_debug_level >= 3) { + upsdebug_hex(3, "CommReceive: RecPack", RecPack, size); + } + /* CheckSum verify */ CheckSum = 0; i_end = 23; for( i = 0 ; i < i_end ; ++i ) CheckSum = RecPack[ i ] + CheckSum; CheckSum = CheckSum % 256; - + upsdebugx(4, "%s: calculated checksum = 0x%02x, RecPack[23] = 0x%02x", __func__, CheckSum, RecPack[23]); + ser_flush_in(upsfd,"",0); /* clean port */ - - /* correct package */ - /* 0xA0 is original solis.c; 0xB0 is for APC-branded Microsol units */ + + /* RecPack[0] identify the model number below. + * SOLIS = 1; + RHINO = 2; + STAY = 3; + SOLIS_LI_700 = 169; + SOLIS_M11 = 171; + SOLIS_M15 = 175; + SOLIS_M14 = 174; + SOLIS_M13 = 173; + SOLISDC_M14 = 201; + SOLISDC_M13 = 206; + SOLISDC_M15 = 207; + CABECALHO_RHINO = 194; + PS800 = 185; + STAY1200_USB = 186; + PS350_CII = 184; + PS2200 = 187; + PS2200_22 = 188; + STAY700_USB = 189; + BZ1500 = 190; + */ if( ( ( (RecPack[0] & 0xF0) == 0xA0 ) || (RecPack[0] & 0xF0) == 0xB0) - && ( RecPack[ 24 ] == 254 ) - && ( RecPack[ 23 ] == CheckSum ) ) { + && ( RecPack[ 24 ] == 254 ) + && ( RecPack[ 23 ] == CheckSum ) ) { if(!(detected)) { - SolisModel = (int) (RecPack[0] & 0x0F); + + if (RecPack[0] == 186) { + SolisModel = 16; + } else { + SolisModel = (int) (RecPack[0] & 0x0F); + } if( SolisModel < 13 ) imodel = SolisModel - 10; /* 10 = 0, 11 = 1 */ else imodel = SolisModel - 11; /* 13 = 2, 14 = 3, 15 = 4 */ + detected = true; + } switch( SolisModel ) { - case 10: /* Added for APC-Branded Microsol units */ - { - ScanReceivePack(); - break; - } - case 11: - case 12: - case 13: - case 14: - case 15: - { - ScanReceivePack(); - break; - } - default: - { - printf( M_UNKN ); - ScanReceivePack(); // Scan anyway. - break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + { + ScanReceivePack(); + break; + } + case 16: // STAY1200_USB model + { + ScanReceivePack(); + break; + } + default: + { + printf( M_UNKN ); + ScanReceivePack(); // Scan anyway. + break; + } } } - } - } - - break; - } - - case 1: - { - /* dumping package nothing to do yet */ - Waiting = 0; - break; - } - - } - - Waiting =0; - } static void getbaseinfo(void) { - - unsigned char temp[256]; + unsigned char tmp; #ifdef PORTUGUESE - char diassemana[7][4]={"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"}; + const char diassemana[7][4]={"Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sab"}; #else - char DaysOfWeek[7][4]={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + const char DaysOfWeek[7][4]={"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; #endif - char mycmd[8]; char *str1, *str2, *str3, *str4, *strx; unsigned char Pacote[25]; - int i, i1=0, i2=0, j=0, tam, tpac=25; + int i, i1=0, i2=0, tam; + const int tpac=25; time_t tmt; struct tm *now; @@ -812,7 +896,7 @@ static void getbaseinfo(void) #ifdef PORTUGUESE strcpy( seman, diassemana[weekn] ); -#else +#else strcpy( seman, DaysOfWeek[weekn] ); #endif @@ -860,29 +944,31 @@ static void getbaseinfo(void) DaysOnWeek = DaysOffWeek; } } - + } /* end prgups 1 - 2 */ /* dummy read attempt to sync - throw it out */ - snprintf(mycmd, sizeof(mycmd), "%c%c",CMD_UPSCONT, ENDCHAR); - ser_send(upsfd, "%s", mycmd); + upsdebugx(3, "%s: sending CMD_UPSCONT and ENDCHAR to sync", __func__); + ser_send(upsfd, "%c%c", CMD_UPSCONT, ENDCHAR); - /* trying detect solis model */ - while ( ( !detected ) && ( j < 20 ) ) { - temp[0] = 0; /* flush temp buffer */ - tam = ser_get_buf_len(upsfd, temp, tpac, 3, 0); - if( tam == 25 ) { - for( i = 0 ; i < tam ; i++ ) { - Pacote[i] = temp[i]; - } + /* Read until end-of-response character (0xFE): */ + for(i=0; i 0 && nut_debug_level >= 4) { + upsdebug_hex(4, "received from ser_get_buf_len()", Pacote, tam); } - - j++; - if( tam == 25) - CommReceive((char *)Pacote, tam); - else - CommReceive((char *)temp, tam); - } /* while end */ + CommReceive((char *)Pacote, tam); + } if( (!detected) ) { fatalx(EXIT_FAILURE, NO_SOLIS ); @@ -890,11 +976,8 @@ static void getbaseinfo(void) switch( SolisModel ) { - case 10: /* Added for APC-Microsol units */ - { - Model = "Back-UPS 1200 BR"; - break; - } + case 10: + case 11: case 12: { @@ -916,6 +999,9 @@ static void getbaseinfo(void) Model = "Solis 3.0"; break; } + case 16: + Model = "Microsol Back-Ups BZ1200-BR"; + break; } /* if( isprogram ) */ @@ -955,8 +1041,6 @@ static void getbaseinfo(void) printf("Detected %s on %s\n", dstate_getinfo("ups.model"), device_path); prnInfo(); - - } static void getupdateinfo(void) @@ -978,7 +1062,7 @@ static void getupdateinfo(void) isday = IsToday( DaysStd, weekn ); else isday = IsToday( DaysStd, weekn ); - + if( isday ) printf( TODAY_DD, hourshut, minshut ); @@ -986,7 +1070,7 @@ static void getupdateinfo(void) printf( SHUT_NOW ); progshut = 1; } - } + } /* programable shutdown end block */ @@ -994,8 +1078,15 @@ static void getupdateinfo(void) /* get update package */ temp[0] = 0; /* flush temp buffer */ + + upsdebugx(3, "%s: requesting %d bytes from ser_get_buf_len()", __func__, pacsize); tam = ser_get_buf_len(upsfd, temp, pacsize, 3, 0); + upsdebugx(2, "%s: received %d bytes from ser_get_buf_len()", __func__, tam); + if(tam > 0 && nut_debug_level >= 4) { + upsdebug_hex(4, "received from ser_get_buf_len()", temp, tam); + } + CommReceive((char *)temp, tam); } @@ -1039,7 +1130,7 @@ void upsdrv_updateinfo(void) dstate_setinfo("input.voltage", "%03.1f", InVoltage); dstate_setinfo("battery.voltage", "%02.1f", BattVoltage); dstate_setinfo("battery.charge", "%03.1f", batcharge); - + dstate_setinfo("output.current", "%03.1f", OutCurrent); status_init(); if (!SourceFail ) @@ -1067,25 +1158,26 @@ void upsdrv_updateinfo(void) } -/* power down the attached load immediately */ +/*! @brief Power down the attached load immediately. + * Basic idea: find out line status and send appropriate command. + * - on battery: send normal shutdown, UPS will return by itself on utility + * - on line: send shutdown+return, UPS will cycle and return soon. + */ void upsdrv_shutdown(void) { - /* basic idea: find out line status and send appropriate command */ - /* on battery: send normal shutdown, ups will return by itself on utility */ - /* on line: send shutdown+return, ups will cycle and return soon */ if (!SourceFail) { /* on line */ - - printf("On line, sending shutdown+return command...\n"); + + upslogx(LOG_NOTICE, "On line, sending shutdown+return command...\n"); ser_send_char(upsfd, CMD_SHUTRET ); } else { - printf("On battery, sending normal shutdown command...\n"); + upslogx(LOG_NOTICE, "On battery, sending normal shutdown command...\n"); ser_send_char(upsfd, CMD_SHUT); } - + } void upsdrv_help(void) @@ -1120,7 +1212,7 @@ void upsdrv_makevartable(void) addvar(VAR_VALUE, "daysoff", "Days of week Driver shutdown"); addvar(VAR_VALUE, "houron", "Power on hour (hh:mm)"); addvar(VAR_VALUE, "houroff", "Power off hour (hh:mm)"); - + } void upsdrv_initups(void) diff --git a/drivers/solis.h b/drivers/solis.h index 980f8d5..528a8bb 100644 --- a/drivers/solis.h +++ b/drivers/solis.h @@ -22,7 +22,8 @@ 2004/10/30 - Version 0.40 - add model data structs 2004/11/22 - Version 0.50 - add internal e external shutdown programming 2005/06/16 - Version 0.60 - save external shutdown programming to ups, - support new cables and Solaris compilation + support new cables and Solaris compilation + 2015/09/19 - Version 0.63 - patch for correct reading for Microsol Back-Ups BZ1200-BR */ @@ -33,12 +34,12 @@ typedef int bool_t; /* autonomy constants */ -int bext[5] = {14,18,28,18,1}; -int nompow[4] = { 1000,1500,2000,3000 }; -int inds[5] = { 0,0,1,2,3 }; -double InVolt_offset = 30.; +const static int bext[5] = {14,18,28,18,1}; +const static int nompow[5] = { 1000,1500,2000,3000,1200 }; +const static int inds[6] = { 0,0,1,2,3,4 }; +const static double InVolt_offset = 30.; -struct { +const static struct { int maxi; /* power internals */ int minc[21]; /* power minimal index */ int maxc[21]; /* power maximus index */ @@ -201,7 +202,7 @@ struct { * Solis constants for data ajustment * ----------------------------------------------------------- */ -struct { +const static struct { double m_infreq; double m_appp_offset; double m_involt193[2]; @@ -216,7 +217,7 @@ struct { double m_utilp_i[2][2]; double m_appp_s[2][2]; double m_appp_i[2][2]; -} ctab[5] = +} ctab[6] = { { 101620.0, 25.0, { 1.141, 13.0 }, @@ -287,21 +288,56 @@ struct { { { 1.0/4.78, 52.0 }, { 1.0/4.55, 55.0 } }, { { 1.0/5.15, 29.0 }, { 1.0/4.8, 26.0 } }, { { 1.0/4.78, 52.0 }, { 1.0/4.55, 55.0 } } + }, + + /*STAY1200_USB + + double m_infreq; + double m_appp_offset; + double m_involt193[2]; + double m_involt194[2]; + double m_incurr[2]; + double m_battvolt[2]; + double m_outvolt_s[2][2]; + double m_outvolt_i[2][2]; + double m_outcurr_s[2][2]; + double m_outcurr_i[2][2]; + double m_utilp_s[2][2]; + double m_utilp_i[2][2]; + double m_appp_s[2][2]; + double m_appp_i[2][2]; + + + */ + { 101800.0, //m_infreq + 56.0, //m_appp_offset + { 1.64, 9.34 },// m_involt193 - ok + { 2.5, -250.0 }, //m_involt194 + { 35.0, 1000.0 }, //m_incurr + { 0.1551, 0.2525 }, //m_battvolt + { { 1.41, 13.0 }, { 1.4, 17.0 } }, //m_outvolt_s + { { 2.73, 25.0 }, { 2.73, 30.0 } }, //m_outvolt_i + { { 1.0/8.15, 0.25 }, { 1.0/8.15, 0.25 } }, //m_outcurr_s + { { 1.0/16.0, 0.4 }, { 1.0/15.0, 0.4 } }, //m_outcurr_i + { { 1.0/4.87, 19.0 }, { 1.0/4.55, 17.0 } }, //m_utilp_s + { { 1.0/4.78, 52.0 }, { 1.0/4.55, 55.0 } }, //m_utilp_i + { { 1.0/5.15, 29.0 }, { 1.0/4.8, 26.0 } }, //m__app_s + { { 1.0/4.78, 52.0 }, { 1.0/4.55, 55.0 } } //m_app_i } }; /* Date, time and programming group */ static int const BASE_YEAR = 1998; -int Day, Month, Year; -int isprogram = 0, progshut = 0, prgups = 0; -int dian=0, mesn=0, anon=0, weekn=0; -int dhour, dmin, lhour, lmin, ihour,imin, isec, hourshut, minshut; -unsigned char DaysOnWeek=0, DaysOffWeek=0, DaysStd = 0; -char seman[4]; +static int Day, Month, Year; +static int isprogram = 0, progshut = 0, prgups = 0; +static int dian=0, mesn=0, anon=0, weekn=0; +static int dhour, dmin, lhour, lmin, ihour,imin, isec, hourshut, minshut; +static unsigned char DaysOnWeek=0, DaysOffWeek=0, DaysStd = 0; +static char seman[4]; /* buffers */ -unsigned char RecPack[25]; -unsigned char ConfigPack[12]; +static unsigned char RecPack[25]; +static unsigned char ConfigPack[12]; /* unsigned char MibData[161]; @@ -309,37 +345,35 @@ unsigned char DumpPack[242]; */ /* Identification */ -const char *Model; -int SolisModel, imodel; -int InputValue, Out220; +static const char *Model; +static int SolisModel, imodel; +static int InputValue, Out220; /* protocol */ -int Waiting, NumByteRec = 0; -int pacsize; +static int pacsize; /* Status group */ -unsigned char InputStatus,OutputStatus, BattStatus, StatusGeral; +static unsigned char InputStatus,OutputStatus, BattStatus; /* Events group */ -unsigned char SourceEvents, OutputEvents, BattEvents, GeneralEvents; +static unsigned char SourceEvents, OutputEvents, BattEvents; /* logical */ -bool_t detected = 0; -bool_t SourceFail, SourceLast, FailureFlag, SourceReturn, SuperHeat; -bool_t SuperHeatLast, OverCharge, OverChargeLast, LowBatt; -bool_t CriticBatt, CriticBattLast, Flag_inversor, InversorOn, InversorOnLast; +static bool_t detected = 0; +static bool_t SourceFail, SourceLast, FailureFlag, SourceReturn, SuperHeat; +static bool_t SuperHeatLast, OverCharge, OverChargeLast, LowBatt; +static bool_t CriticBatt, CriticBattLast, Flag_inversor, InversorOn, InversorOnLast; /* Input group */ -double InVoltage, InCurrent, InFreq; -double InDownLim, InUpLim, NomInVolt; +static double InVoltage, InCurrent, InFreq; +static double InDownLim, InUpLim, NomInVolt; /* Output group */ -double OutVoltage, OutCurrent, OutFreq, OutDownLim, OutUpLim, NomOutVolt; +static double OutVoltage, OutCurrent, OutFreq, OutDownLim, OutUpLim, NomOutVolt; /* Battery group */ -int Autonomy, BattExtension, maxauto; -double BattVoltage, BattCurrent, Temperature, batcharge; -double Bat_LimInfRede, Bat_LimSupRede, Bat_LimInfInv, Bat_LimSupInv, Bat_VoltNom; +static int Autonomy, BattExtension, maxauto; +static double BattVoltage, Temperature, batcharge; /* Power group */ -double AppPower, UtilPower, upscharge; -int ChargePowerFactor, NominalPower, UpsPowerFactor; +static double AppPower, UtilPower, upscharge; +static int ChargePowerFactor, NominalPower, UpsPowerFactor; static void prnInfo(void); static int IsToday( unsigned char, int ); @@ -350,7 +384,3 @@ static void getbaseinfo(void); static void getupdateinfo(void); #endif /* INCLUDED_SOLIS_H */ - - - - diff --git a/drivers/tripplite-hid.c b/drivers/tripplite-hid.c index 5409dda..13bd288 100644 --- a/drivers/tripplite-hid.c +++ b/drivers/tripplite-hid.c @@ -29,7 +29,7 @@ #include "tripplite-hid.h" #include "usb-common.h" -#define TRIPPLITE_HID_VERSION "TrippLite HID 0.81" +#define TRIPPLITE_HID_VERSION "TrippLite HID 0.82" /* FIXME: experimental flag to be put in upsdrv_info */ @@ -40,6 +40,10 @@ */ static double battery_scale = 1.0; +static double io_voltage_scale = 1.0; +static double io_frequency_scale = 1.0; +static double io_current_scale = 1.0; + /* Specific handlers for USB device matching */ static void *battery_scale_1dot0(USBDevice_t *device) { @@ -52,6 +56,14 @@ static void *battery_scale_0dot1(USBDevice_t *device) battery_scale = 0.1; return NULL; } +static void *smart1500lcdt_scale(USBDevice_t *device) +{ + battery_scale = 100000.0; + io_voltage_scale = 100000.0; + io_frequency_scale = 0.01; + io_current_scale = 0.01; + return NULL; +} /* TrippLite */ #define TRIPPLITE_VENDORID 0x09ae @@ -96,7 +108,7 @@ static usb_device_id_t tripplite_usb_device_table[] = { /* e.g. ? */ { USB_DEVICE(TRIPPLITE_VENDORID, 0x3015), battery_scale_1dot0 }, /* e.g. TrippLite Smart1500LCD (newer unit) */ - { USB_DEVICE(TRIPPLITE_VENDORID, 0x3016), battery_scale_1dot0 }, + { USB_DEVICE(TRIPPLITE_VENDORID, 0x3016), smart1500lcdt_scale }, /* e.g. TrippLite SmartOnline SU1500RTXL2UA (older unit?) */ { USB_DEVICE(TRIPPLITE_VENDORID, 0x4001), battery_scale_1dot0 }, /* e.g. TrippLite SmartOnline SU6000RT4U? */ @@ -175,6 +187,45 @@ static info_lkp_t tripplite_battvolt[] = { { 0, NULL, tripplite_battvolt_fun } }; +static const char *tripplite_iovolt_fun(double value) +{ + static char buf[8]; + + snprintf(buf, sizeof(buf), "%.1f", io_voltage_scale * value); + + return buf; +} + +static info_lkp_t tripplite_iovolt[] = { + { 0, NULL, tripplite_iovolt_fun } +}; + +static const char *tripplite_iofreq_fun(double value) +{ + static char buf[8]; + + snprintf(buf, sizeof(buf), "%.1f", io_frequency_scale * value); + + return buf; +} + +static info_lkp_t tripplite_iofreq[] = { + { 0, NULL, tripplite_iofreq_fun } +}; + +static const char *tripplite_ioamp_fun(double value) +{ + static char buf[8]; + + snprintf(buf, sizeof(buf), "%.1f", io_current_scale * value); + + return buf; +} + +static info_lkp_t tripplite_ioamp[] = { + { 0, NULL, tripplite_ioamp_fun } +}; + /* --------------------------------------------------------------- */ /* Vendor-specific usage table */ /* --------------------------------------------------------------- */ @@ -279,7 +330,7 @@ static hid_info_t tripplite_hid2nut[] = { #endif /* USBHID_UPS_TRIPPLITE_DEBUG */ /* Device page */ - { "device.part", 0, 0, "UPS.TLCustom.[1].iUPSPartNumber", NULL, "%.0f", 0, stringid_conversion }, + { "device.part", 0, 0, "UPS.TLCustom.[1].iUPSPartNumber", NULL, "%s", HU_FLAG_STATIC, stringid_conversion }, /* Battery page */ { "battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", NULL, "%.0f", 0, NULL }, @@ -363,9 +414,9 @@ static hid_info_t tripplite_hid2nut[] = { /* Input page */ { "input.voltage.nominal", 0, 0, "UPS.PowerSummary.Input.ConfigVoltage", NULL, "%.0f", HU_FLAG_STATIC, NULL }, - { "input.voltage", 0, 0, "UPS.PowerSummary.Input.Voltage", NULL, "%.1f", 0, NULL }, - { "input.voltage", 0, 0, "UPS.PowerConverter.Input.Voltage", NULL, "%.1f", 0, NULL }, - { "input.frequency", 0, 0, "UPS.PowerConverter.Input.Frequency", NULL, "%.1f", 0, NULL }, + { "input.voltage", 0, 0, "UPS.PowerSummary.Input.Voltage", NULL, "%s", 0, tripplite_iovolt }, + { "input.voltage", 0, 0, "UPS.PowerConverter.Input.Voltage", NULL, "%s", 0, tripplite_iovolt }, + { "input.frequency", 0, 0, "UPS.PowerConverter.Input.Frequency", NULL, "%s", 0, tripplite_iofreq }, { "input.transfer.low", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.PowerConverter.Output.LowVoltageTransfer", NULL, "%.1f", HU_FLAG_SEMI_STATIC, NULL }, { "input.transfer.low.max", 0, 0, "UPS.PowerConverter.Output.TLLowVoltageTransferMax", NULL, "%.0f", HU_FLAG_STATIC, NULL }, { "input.transfer.low.min", 0, 0, "UPS.PowerConverter.Output.TLLowVoltageTransferMin", NULL, "%.0f", HU_FLAG_STATIC, NULL }, @@ -375,11 +426,11 @@ static hid_info_t tripplite_hid2nut[] = { /* Output page */ { "output.voltage.nominal", 0, 0, "UPS.Flow.ConfigVoltage", NULL, "%.0f", HU_FLAG_STATIC, NULL }, - { "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", NULL, "%.1f", 0, NULL }, - { "output.voltage", 0, 0, "UPS.PowerSummary.Voltage", NULL, "%.1f", 0, NULL }, - { "output.current", 0, 0, "UPS.PowerConverter.Output.Current", NULL, "%.2f", 0, NULL }, + { "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", NULL, "%s", 0, tripplite_iovolt }, + { "output.voltage", 0, 0, "UPS.PowerSummary.Voltage", NULL, "%s", 0, tripplite_iovolt }, + { "output.current", 0, 0, "UPS.PowerConverter.Output.Current", NULL, "%s", 0, tripplite_ioamp }, { "output.frequency.nominal", 0, 0, "UPS.Flow.ConfigFrequency", NULL, "%.0f", HU_FLAG_STATIC, NULL }, - { "output.frequency", 0, 0, "UPS.PowerConverter.Output.Frequency", NULL, "%.1f", 0, NULL }, + { "output.frequency", 0, 0, "UPS.PowerConverter.Output.Frequency", NULL, "%s", 0, tripplite_iofreq }, /* instant commands. */ { "test.battery.start.quick", 0, 0, "UPS.BatterySystem.Test", NULL, "1", HU_TYPE_CMD, NULL }, /* reported to work on OMNI1000 */ diff --git a/drivers/tripplitesu.c b/drivers/tripplitesu.c index d0d0563..2f6dd2b 100644 --- a/drivers/tripplitesu.c +++ b/drivers/tripplitesu.c @@ -125,7 +125,7 @@ #include "serial.h" #define DRIVER_NAME "Tripp Lite SmartOnline driver" -#define DRIVER_VERSION "0.03" +#define DRIVER_VERSION "0.05" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -296,7 +296,7 @@ static int do_command(char type, const char *command, const char *parameters, ch I don't like that, so I remove them. This is safe to do with all responses for this protocol, so I just do that here. */ - rtrim(response, ' '); + str_rtrim(response, ' '); return ret; } @@ -552,6 +552,11 @@ static int init_comm(void) char response[MAX_RESPONSE_LENGTH]; ups.commands_available = 0; + /* Repeat enumerate command 2x, firmware bug on some units garbles 1st response */ + if (do_command(POLL, AVAILABLE, "", response) <= 0){ + upslogx(LOG_NOTICE, "init_comm: Initial response malformed, retrying in 300ms"); + usleep(3E5); + } if (do_command(POLL, AVAILABLE, "", response) <= 0) return 0; i = strlen(response); diff --git a/drivers/upscode2.c b/drivers/upscode2.c index 1a5a6a2..3de16d9 100644 --- a/drivers/upscode2.c +++ b/drivers/upscode2.c @@ -44,7 +44,7 @@ #include #define DRIVER_NAME "UPScode II UPS driver" -#define DRIVER_VERSION "0.88" +#define DRIVER_VERSION "0.89" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -1046,7 +1046,7 @@ static int upscrecv(char *buf) } else if (res == 0) { upsdebugx(3, "upscrecv: Timeout"); } else { - upsdebugx(3, "upscrecv: %u bytes:\t'%s'", res-1, rtrim(buf, ENDCHAR)); + upsdebugx(3, "upscrecv: %u bytes:\t'%s'", res-1, str_rtrim(buf, ENDCHAR)); } return res; diff --git a/drivers/usb-common.h b/drivers/usb-common.h index d7a3ff4..c9d8a85 100644 --- a/drivers/usb-common.h +++ b/drivers/usb-common.h @@ -38,12 +38,13 @@ * corresponding string did not exist or could not be retrieved. */ typedef struct USBDevice_s { - uint16_t VendorID; /*!< Device's Vendor ID */ - uint16_t ProductID; /*!< Device's Product ID */ - char *Vendor; /*!< Device's Vendor Name */ - char *Product; /*!< Device's Product Name */ - char *Serial; /* Product serial number */ - char *Bus; /* Bus name, e.g. "003" */ + uint16_t VendorID; /*!< Device's Vendor ID */ + uint16_t ProductID; /*!< Device's Product ID */ + char *Vendor; /*!< Device's Vendor Name */ + char *Product; /*!< Device's Product Name */ + char *Serial; /*!< Product serial number */ + char *Bus; /*!< Bus name, e.g. "003" */ + uint16_t bcdDevice; /*!< Device release number */ } USBDevice_t; /*! diff --git a/drivers/usbhid-ups.c b/drivers/usbhid-ups.c index c3e480c..1e87de4 100644 --- a/drivers/usbhid-ups.c +++ b/drivers/usbhid-ups.c @@ -27,7 +27,7 @@ */ #define DRIVER_NAME "Generic HID driver" -#define DRIVER_VERSION "0.39" +#define DRIVER_VERSION "0.41" #include "main.h" #include "libhid.h" @@ -753,7 +753,7 @@ void upsdrv_makevartable(void) void upsdrv_updateinfo(void) { hid_info_t *item; - HIDData_t *event[MAX_EVENT_NUM]; + HIDData_t *event[MAX_EVENT_NUM], *found_data; int i, evtCount; double value; time_t now; @@ -826,7 +826,15 @@ void upsdrv_updateinfo(void) } /* Skip Input reports, if we don't use the Feature report */ - item = find_hid_info(FindObject_with_Path(pDesc, &(event[i]->Path), interrupt_only ? ITEM_INPUT:ITEM_FEATURE)); + found_data = FindObject_with_Path(pDesc, &(event[i]->Path), interrupt_only ? ITEM_INPUT:ITEM_FEATURE); + if(!found_data && !interrupt_only) { + found_data = FindObject_with_Path(pDesc, &(event[i]->Path), ITEM_INPUT); + } + if(!found_data) { + upsdebugx(2, "Could not find event as either ITEM_INPUT or ITEM_FEATURE?"); + continue; + } + item = find_hid_info(found_data); if (!item) { upsdebugx(3, "NUT doesn't use this HID object"); continue; @@ -1481,6 +1489,11 @@ static hid_info_t *find_hid_info(const HIDData_t *hiddata) { hid_info_t *hidups_item; + if(!hiddata) { + upsdebugx(2, "%s: hiddata == NULL", __func__); + return NULL; + } + for (hidups_item = subdriver->hid2nut; hidups_item->info_type != NULL ; hidups_item++) { /* Skip server side vars */ diff --git a/drivers/xppc-mib.c b/drivers/xppc-mib.c index 4562cd4..c00655c 100644 --- a/drivers/xppc-mib.c +++ b/drivers/xppc-mib.c @@ -33,7 +33,7 @@ * static info_lkp_t onbatt_info[] = { * { 1, "OB" }, * { 2, "OL" }, - * { 0, "NULL" } + * { 0, NULL } * }; */ @@ -94,7 +94,7 @@ static snmp_info_t xppc_mib[] = { * static info_lkp_t onbatt_info[] = { * { 1, "OB" }, * { 2, "OL" }, - * { 0, "NULL" } + * { 0, NULL } * }; */ { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "Tripp Lite / Phoenixtec", diff --git a/include/Makefile.am b/include/Makefile.am index 6e4b966..41f47ba 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,5 +1,5 @@ dist_noinst_HEADERS = attribute.h common.h extstate.h parseconf.h proto.h \ - state.h timehead.h upsconf.h nut_stdint.h nut_platform.h + state.h str.h timehead.h upsconf.h nut_stdint.h nut_platform.h # http://www.gnu.org/software/automake/manual/automake.html#Clean BUILT_SOURCES = nut_version.h diff --git a/include/Makefile.in b/include/Makefile.in index d1e2f36..05faa88 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -203,6 +203,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ @@ -337,7 +338,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ udevdir = @udevdir@ dist_noinst_HEADERS = attribute.h common.h extstate.h parseconf.h proto.h \ - state.h timehead.h upsconf.h nut_stdint.h nut_platform.h + state.h str.h timehead.h upsconf.h nut_stdint.h nut_platform.h # http://www.gnu.org/software/automake/manual/automake.html#Clean diff --git a/include/common.h b/include/common.h index 477774e..f893657 100644 --- a/include/common.h +++ b/include/common.h @@ -43,6 +43,7 @@ #include "timehead.h" #include "attribute.h" #include "proto.h" +#include "str.h" #ifdef __cplusplus /* *INDENT-OFF* */ @@ -118,11 +119,6 @@ void *xcalloc(size_t number, size_t size); void *xrealloc(void *ptr, size_t size); char *xstrdup(const char *string); -char *rtrim(char *in, const char sep); -char* ltrim(char *in, const char sep); -char *rtrim_m(char *in, const char *seps); -char* ltrim_m(char *in, const char *seps); - int select_read(const int fd, void *buf, const size_t buflen, const long d_sec, const long d_usec); int select_write(const int fd, const void *buf, const size_t buflen, const long d_sec, const long d_usec); diff --git a/include/config.h.in b/include/config.h.in index dd42362..faa62ff 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -206,6 +206,9 @@ /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF +/* Define to 1 if you have the header file. */ +#undef HAVE_SSL_H + /* Define to 1 if you have the `SSL_library_init' function. */ #undef HAVE_SSL_LIBRARY_INIT @@ -281,6 +284,9 @@ /* Default path for HTML files */ #undef HTMLPATH +/* Default path for system libraries */ +#undef LIBDIR + /* Desired syslog facility - see syslog(3) */ #undef LOG_FACILITY diff --git a/include/str.h b/include/str.h new file mode 100644 index 0000000..57955fd --- /dev/null +++ b/include/str.h @@ -0,0 +1,129 @@ +/* str.h - Common string-related functions + * + * Copyright (C) + * 2000 Russell Kroll + * 2015 Daniele Pezzini + * + * 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 STR_H +#define STR_H + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/* Remove all + * - leading and trailing (str_trim[_m]()) + * - leading (str_ltrim[_m]()) + * - trailing (str_rtrim[_m])) + * instances of + * - *character* (plain versions) + * - each character in *characters* ('_m' versions) + * from a string. + * - *string*: null-terminated byte string from which characters are to be removed; + * - *character*: character that has to be removed from *string*; + * - *characters*: null-terminated byte string of characters to be removed from string. + * Return: + * - NULL, if *string* is NULL, otherwise + * - *string* without the specified characters (upto an empty string). */ +char *str_trim(char *string, const char character); +char *str_trim_m(char *string, const char *characters); +char *str_ltrim(char *string, const char character); +char *str_ltrim_m(char *string, const char *characters); +char *str_rtrim(char *string, const char character); +char *str_rtrim_m(char *string, const char *characters); + +/* Remove all + * - leading and trailing (str_trim_space()) + * - leading (str_ltrim_space()) + * - trailing (str_rtrim_space()) + * spaces (as identified by isspace()) from a string. + * - *string*: null-terminated byte string from which spaces are to be removed. + * Return: + * - NULL, if *string* is NULL, otherwise + * - *string* without the specified spaces (upto an empty string). */ +char *str_trim_space(char *string); +char *str_ltrim_space(char *string); +char *str_rtrim_space(char *string); + +/* Tell whether a string can be converted to a number of type str_is_[_strict](). + * - *string*: the null-terminated byte string to check; + * - *base*: the base the string must conform to. + * The same restrictions of the corresponding str_to_[_strict]() functions apply. + * If *string* can be converted to a valid number of type , return 1. + * Otherwise, return 0 with errno set to: + * - ENOMEM, if available memory is insufficient; + * - EINVAL, if the value of *base* is not supported or no conversion could be performed; + * - ERANGE, if the converted value would be out of the acceptable range of . */ +int str_is_short(const char *string, const int base); +int str_is_short_strict(const char *string, const int base); +int str_is_ushort(const char *string, const int base); +int str_is_ushort_strict(const char *string, const int base); +int str_is_int(const char *string, const int base); +int str_is_int_strict(const char *string, const int base); +int str_is_uint(const char *string, const int base); +int str_is_uint_strict(const char *string, const int base); +int str_is_long(const char *string, const int base); +int str_is_long_strict(const char *string, const int base); +int str_is_ulong(const char *string, const int base); +int str_is_ulong_strict(const char *string, const int base); +int str_is_double(const char *string, const int base); +int str_is_double_strict(const char *string, const int base); + +/* Convert a string to a number of type str_to_[_strict](). + * - *string*: the null-terminated byte string to convert, + * 'strict' versions' strings shall not contain spaces (as identified by isspace()), + * - short, int, long: strtol()'s restrictions apply, + * - ushort, uint, ulong: strtoul()'s restrictions apply, plus: + * - plus ('+') and minus ('-') signs (and hence negative values) are not supported, + * - double: strtod()'s restrictions apply, plus: + * - infinity and nan are not supported, + * - radix character (decimal point character) must be a period ('.'); + * - *number*: a pointer to a that will be filled upon execution; + * - *base*: the base the string must conform to, + * - short, ushort, int, uint, long, ulong: acceptable values as in strtol()/strtoul(), + * - double: 0 for auto-select, 10 or 16. + * On success, return 1 with *number* being the result of the conversion of *string*. + * On failure, return 0 with *number* being 0 and errno set to: + * - ENOMEM, if available memory is insufficient; + * - EINVAL, if the value of *base* is not supported or no conversion can be performed; + * - ERANGE, if the converted value is out of the acceptable range of . */ +int str_to_short(const char *string, short *number, const int base); +int str_to_short_strict(const char *string, short *number, const int base); +int str_to_ushort(const char *string, unsigned short *number, const int base); +int str_to_ushort_strict(const char *string, unsigned short *number, const int base); +int str_to_int(const char *string, int *number, const int base); +int str_to_int_strict(const char *string, int *number, const int base); +int str_to_uint(const char *string, unsigned int *number, const int base); +int str_to_uint_strict(const char *string, unsigned int *number, const int base); +int str_to_long(const char *string, long *number, const int base); +int str_to_long_strict(const char *string, long *number, const int base); +int str_to_ulong(const char *string, unsigned long *number, const int base); +int str_to_ulong_strict(const char *string, unsigned long *number, const int base); +int str_to_double(const char *string, double *number, const int base); +int str_to_double_strict(const char *string, double *number, const int base); + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif + +#endif /* STR_H */ diff --git a/lib/Makefile.in b/lib/Makefile.in index a0d827c..da3c235 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -218,6 +218,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/lib/README b/lib/README index aecb7c2..600a4cb 100644 --- a/lib/README +++ b/lib/README @@ -116,7 +116,7 @@ Simply replace 'libupsclient' occurences in the above example, by the name of the desired library (for example, 'libnutscan'). NOTE: this is an alternate method. Use of PKG_CHECK_MODULES macro should be -prefered. +preferred. Future consideration diff --git a/m4/nut_check_libnss.m4 b/m4/nut_check_libnss.m4 index 4adc913..7c23531 100644 --- a/m4/nut_check_libnss.m4 +++ b/m4/nut_check_libnss.m4 @@ -55,9 +55,10 @@ if test -z "${nut_have_libnss_seen}"; then ], []) AC_MSG_RESULT([${LIBS}]) - dnl check if NSS is usable - AC_CHECK_HEADERS(nss.h, [nut_have_libnss=yes], [nut_have_libnss=no], [AC_INCLUDES_DEFAULT]) - AC_CHECK_FUNCS(NSS_Init, [], [nut_have_libnss=no]) + dnl check if NSS is usable: we need both the runtime and headers + AC_CHECK_FUNCS(NSS_Init, [nut_have_libnss=yes], [nut_have_libnss=no]) + dnl libc6 also provides an nss.h file, so also check for ssl.h + AC_CHECK_HEADERS([nss.h ssl.h], [], [nut_have_libnss=no], [AC_INCLUDES_DEFAULT]) if test "${nut_have_libnss}" = "yes"; then nut_with_ssl="yes" diff --git a/scripts/Makefile.in b/scripts/Makefile.in index fc45fe7..65ff56c 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -241,6 +241,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/Solaris/Makefile.in b/scripts/Solaris/Makefile.in index c49592e..9a1f124 100644 --- a/scripts/Solaris/Makefile.in +++ b/scripts/Solaris/Makefile.in @@ -183,6 +183,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/augeas/Makefile.in b/scripts/augeas/Makefile.in index e3271d4..d8fa703 100644 --- a/scripts/augeas/Makefile.in +++ b/scripts/augeas/Makefile.in @@ -188,6 +188,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/augeas/README b/scripts/augeas/README index 3be147e..a4ac27c 100644 --- a/scripts/augeas/README +++ b/scripts/augeas/README @@ -41,7 +41,7 @@ As an example, on Debian and derivatives, do the following: $ apt-get install augeas-lenses augeas-tools -And optionaly: +And optionally: $ apt-get install libaugeas0 libaugeas-dev python-augeas diff --git a/scripts/augeas/nutupsconf.aug.in b/scripts/augeas/nutupsconf.aug.in index 70d5f67..441b0a0 100644 --- a/scripts/augeas/nutupsconf.aug.in +++ b/scripts/augeas/nutupsconf.aug.in @@ -33,7 +33,10 @@ let ups_sep = IniFile.sep IniFile.sep_re IniFile.sep_default let ups_global = "chroot" | "driverpath" | "maxstartdelay" + | "maxretry" + | "retrydelay" | "pollinterval" + | "synchronous" | "user" let ups_fields = "driver" @@ -41,7 +44,9 @@ let ups_fields = "driver" | "sdorder" | "desc" | "nolock" + | "ignorelb" | "maxstartdelay" + | "synchronous" | "CP" | "CS" | "ID" @@ -160,6 +165,8 @@ let ups_fields = "driver" | "shutdown_timer" | "silent" | "site_fault_detection" + | "snmp_retries" + | "snmp_timeout" | "snmp_version" | "startdelay" | "status_only" diff --git a/scripts/augeas/nutupsconf.aug.tpl b/scripts/augeas/nutupsconf.aug.tpl index 24f6bcc..0f7c66c 100644 --- a/scripts/augeas/nutupsconf.aug.tpl +++ b/scripts/augeas/nutupsconf.aug.tpl @@ -33,7 +33,10 @@ let ups_sep = IniFile.sep IniFile.sep_re IniFile.sep_default let ups_global = "chroot" | "driverpath" | "maxstartdelay" + | "maxretry" + | "retrydelay" | "pollinterval" + | "synchronous" | "user" let ups_fields = "driver" @@ -41,7 +44,9 @@ let ups_fields = "driver" | "sdorder" | "desc" | "nolock" + | "ignorelb" | "maxstartdelay" + | "synchronous" @SPECIFIC_DRV_VARS@ let ups_entry = IniFile.indented_entry (ups_global|ups_fields) ups_sep ups_comment diff --git a/scripts/devd/Makefile.in b/scripts/devd/Makefile.in index cad7c1f..094af7d 100644 --- a/scripts/devd/Makefile.in +++ b/scripts/devd/Makefile.in @@ -213,6 +213,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/devd/nut-usb.conf.in b/scripts/devd/nut-usb.conf.in index 09418de..b491415 100644 --- a/scripts/devd/nut-usb.conf.in +++ b/scripts/devd/nut-usb.conf.in @@ -178,6 +178,15 @@ notify 100 { match "product" "0xffff"; action "chgrp @RUN_AS_GROUP@ /dev/$cdev; chmod g+rw /dev/$cdev"; }; +# TS Shara UPSes - nutdrv_qx +notify 100 { + match "system" "USB"; + match "subsystem" "DEVICE"; + match "type" "ATTACH"; + match "vendor" "0x0483"; + match "product" "0x0035"; + action "chgrp @RUN_AS_GROUP@ /dev/$cdev; chmod g+rw /dev/$cdev"; +}; # Riello (Cypress Semiconductor Corp.) # various models - riello_usb @@ -884,6 +893,17 @@ notify 100 { match "product" "0x00c9"; action "chgrp @RUN_AS_GROUP@ /dev/$cdev; chmod g+rw /dev/$cdev"; }; + +# AEG +# PROTECT B / NAS - usbhid-ups +notify 100 { + match "system" "USB"; + match "subsystem" "DEVICE"; + match "type" "ATTACH"; + match "vendor" "0x2b2d"; + match "product" "0xffff"; + action "chgrp @RUN_AS_GROUP@ /dev/$cdev; chmod g+rw /dev/$cdev"; +}; # Ablerex 625L USB - blazer_usb notify 100 { match "system" "USB"; diff --git a/scripts/hotplug/Makefile.in b/scripts/hotplug/Makefile.in index 4e9b5e5..390e97e 100644 --- a/scripts/hotplug/Makefile.in +++ b/scripts/hotplug/Makefile.in @@ -216,6 +216,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/hotplug/libhid.usermap b/scripts/hotplug/libhid.usermap index d1be810..7cee0ae 100644 --- a/scripts/hotplug/libhid.usermap +++ b/scripts/hotplug/libhid.usermap @@ -48,6 +48,8 @@ libhidups 0x0003 0x0463 0xffff 0x0000 0x0000 0x00 # Dell # various models libhidups 0x0003 0x047c 0xffff 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# TS Shara UPSes +libhidups 0x0003 0x0483 0x0035 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # Riello (Cypress Semiconductor Corp.) # various models @@ -222,5 +224,9 @@ libhidups 0x0003 0x10af 0x0004 0x0000 0x0000 0x00 libhidups 0x0003 0x10af 0x0008 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # GE EP series libhidups 0x0003 0x14f0 0x00c9 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 + +# AEG +# PROTECT B / NAS +libhidups 0x0003 0x2b2d 0xffff 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # Ablerex 625L USB libhidups 0x0003 0xffff 0x0000 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 diff --git a/scripts/python/Makefile.in b/scripts/python/Makefile.in index 79c48e5..baf6384 100644 --- a/scripts/python/Makefile.in +++ b/scripts/python/Makefile.in @@ -183,6 +183,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/subdriver/gen-snmp-subdriver.sh b/scripts/subdriver/gen-snmp-subdriver.sh index 92d18d5..0ff16d6 100755 --- a/scripts/subdriver/gen-snmp-subdriver.sh +++ b/scripts/subdriver/gen-snmp-subdriver.sh @@ -3,12 +3,13 @@ # an auxiliary script to produce a "stub" snmp-ups subdriver from # SNMP data from a real agent or from dump files # -# Version: 0.4 +# Version: 0.6 # # See also: docs/snmp-subdrivers.txt # # Copyright (C) -# 2011 - 2012 Arnaud Quette +# 2011 - 2012 Arnaud Quette +# 2015 Arnaud Quette # # 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 @@ -38,13 +39,24 @@ usage() { echo "mode 1: get SNMP data from a real agent" echo " -H host_address -- SNMP host IP address or name" echo " -c community -- SNMP v1 community name (default: public)" + echo " -s XXXX -- override SNMP OID entry point (sysOID). Ex: '.1.3.6.1.4.1.534.10'" echo "" echo "mode 2: get data from files (snmpwalk dumps of 'sysOID' subtree)" - echo " -s XXXX -- SNMP OID entry point (sysOID). Ex: '.1.3.6.1.4.1.705.1'" + echo " -s XXXX -- SNMP OID entry point (sysOID). Ex: '.1.3.6.1.4.1.534.6.6.7'" echo " file1 file2 -- read from files instead of an host (using Net SNMP)" echo " file1: numeric SNMP walk (snmpwalk -On ... )" echo " file2: string SNMP walk (snmpwalk -Os ... )" - # FIXME: EXAMPLES + echo "" + echo "Notes:" + echo " For both modes, prefer to copy the specific MIB file(s) for your device in the $0 script directory" + echo " In such case, for mode 2, also add \"-M.\" to allow the name resolution of OIDs" + echo "" + echo "Example:" + echo "mode 1: $0 -H 192.168.0.1 -n mibname -c mycommunity" + echo "mode 2: (using sysOID .1.3.6.1.4.1.534.6.6.7)" + echo " snmpwalk -On -v1 -c mycommunity 192.168.0.1 .1.3.6.1.4.1.534.6.6.7 2>/dev/null 1> numeric-walk-file" + echo " snmpwalk -Os -v1 -m ALL -M+. -c mycommunity 192.168.0.1 .1.3.6.1.4.1.534.6.6.7 2>/dev/null 1> string-walk-file" + echo " $0 -s .1.3.6.1.4.1.534.6.6.7 numeric-walk-file string-walk-file" } # variables @@ -66,10 +78,14 @@ TMP_NUMWALKFILE=`mktemp "$TMPDIR/$NAME-TMP-NUMWALK.XXXXXX"` TMP_STRWALKFILE=`mktemp "$TMPDIR/$NAME-TMP-STRWALK.XXXXXX"` get_snmp_data() { - # 1) get the sysOID (points the mfr specif MIB) - SYSOID=`snmpget -v1 -c $COMMUNITY -Ov $HOSTNAME .1.3.6.1.2.1.1.2.0 | cut -d' ' -f2` - - echo "sysOID retrieved: ${SYSOID}" + # 1) get the sysOID (points the mfr specif MIB), apart if there's an override + if [ -z "$SYSOID" ] + then + SYSOID=`snmpget -On -v1 -c $COMMUNITY -Ov $HOSTNAME .1.3.6.1.2.1.1.2.0 | cut -d' ' -f2` + echo "sysOID retrieved: ${SYSOID}" + else + echo "Using the provided sysOID override ($SYSOID)" + fi # 2) get the content of the mfr specif MIB echo "Retrieving SNMP information. This may take some time" @@ -83,7 +99,7 @@ while [ $# -gt 0 ]; do DRIVER="$2" shift 2 elif [ $# -gt 1 -a "$1" = "-M" ]; then - MIBS_DIRLIST="+$2" + MIBS_DIRLIST="$MIBS_DIRLIST:$2" shift 2 elif [ "$1" = "-k" ]; then KEEP=yes @@ -166,7 +182,7 @@ fi cleanup () { rm -f "$DEBUG $DFL_NUMWALKFILE $TMP_NUMWALKFILE $DFL_STRWALKFILE $TMP_STRWALKFILE" } -if [ -z "$KEEP" ]; then +if [ -n "$KEEP" ]; then trap cleanup EXIT fi @@ -272,7 +288,7 @@ cat > "$CFILE" <> ${CFILE} # append footer diff --git a/scripts/systemd/Makefile.in b/scripts/systemd/Makefile.in index 252ff39..9f91eab 100644 --- a/scripts/systemd/Makefile.in +++ b/scripts/systemd/Makefile.in @@ -222,6 +222,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/systemd/nut-server.service.in b/scripts/systemd/nut-server.service.in index dada977..fe20145 100644 --- a/scripts/systemd/nut-server.service.in +++ b/scripts/systemd/nut-server.service.in @@ -4,7 +4,7 @@ After=local-fs.target network.target nut-driver.service # We don't Require drivers to be successfully started! This would be # a change of behavior compared to init SysV, and could prevent from # accessing successfully started, at least to audit a system. -#Requires=nut-driver.service +Wants=nut-driver.service Before=nut-monitor.service [Service] diff --git a/scripts/udev/Makefile.in b/scripts/udev/Makefile.in index 33dd60d..7b7485f 100644 --- a/scripts/udev/Makefile.in +++ b/scripts/udev/Makefile.in @@ -215,6 +215,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/scripts/udev/nut-usbups.rules.in b/scripts/udev/nut-usbups.rules.in index 1ac601d..966674f 100644 --- a/scripts/udev/nut-usbups.rules.in +++ b/scripts/udev/nut-usbups.rules.in @@ -50,6 +50,8 @@ ATTR{idVendor}=="0463", ATTR{idProduct}=="ffff", MODE="664", GROUP="@RUN_AS_GROU # Dell # various models - usbhid-ups ATTR{idVendor}=="047c", ATTR{idProduct}=="ffff", MODE="664", GROUP="@RUN_AS_GROUP@" +# TS Shara UPSes - nutdrv_qx +ATTR{idVendor}=="0483", ATTR{idProduct}=="0035", MODE="664", GROUP="@RUN_AS_GROUP@" # Riello (Cypress Semiconductor Corp.) # various models - riello_usb @@ -224,6 +226,10 @@ ATTR{idVendor}=="10af", ATTR{idProduct}=="0004", MODE="664", GROUP="@RUN_AS_GROU ATTR{idVendor}=="10af", ATTR{idProduct}=="0008", MODE="664", GROUP="@RUN_AS_GROUP@" # GE EP series - blazer_usb ATTR{idVendor}=="14f0", ATTR{idProduct}=="00c9", MODE="664", GROUP="@RUN_AS_GROUP@" + +# AEG +# PROTECT B / NAS - usbhid-ups +ATTR{idVendor}=="2b2d", ATTR{idProduct}=="ffff", MODE="664", GROUP="@RUN_AS_GROUP@" # Ablerex 625L USB - blazer_usb ATTR{idVendor}=="ffff", ATTR{idProduct}=="0000", MODE="664", GROUP="@RUN_AS_GROUP@" diff --git a/scripts/upower/95-upower-hid.rules b/scripts/upower/95-upower-hid.rules index a407b53..4c5f2ca 100644 --- a/scripts/upower/95-upower-hid.rules +++ b/scripts/upower/95-upower-hid.rules @@ -1,12 +1,20 @@ ############################################################################################################## # Uninterruptible Power Supplies with USB HID interfaces # -# to keep up to date, monitor https://github.com/networkupstools/nut/commits/master/scripts/upower/95-upower-hid.rules +# This file was automatically generated by NUT: +# https://github.com/networkupstools/nut/ +# +# To keep up to date, monitor upstream NUT +# https://github.com/networkupstools/nut/commits/master/scripts/upower/95-upower-hid.rules +# or checkout the NUT repository and call 'tools/nut-usbinfo.pl' +# newer hiddev are part of the usbmisc class +SUBSYSTEM=="usbmisc", GOTO="up_hid_chkdev" # only support USB, else ignore SUBSYSTEM!="usb", GOTO="up_hid_end" # if usbraw device, ignore +LABEL="up_hid_chkdev" KERNEL!="hiddev*", GOTO="up_hid_end" # if an interface, ignore @@ -25,6 +33,7 @@ ATTRS{idVendor}=="0764", ENV{UPOWER_VENDOR}="Cyber Power Systems" ATTRS{idVendor}=="09ae", ENV{UPOWER_VENDOR}="TrippLite" ATTRS{idVendor}=="0d9f", ENV{UPOWER_VENDOR}="PowerCOM" ATTRS{idVendor}=="10af", ENV{UPOWER_VENDOR}="Liebert" +ATTRS{idVendor}=="2b2d", ENV{UPOWER_VENDOR}="AEG" # Hewlett Packard ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="0001", ENV{UPOWER_BATTERY_TYPE}="ups" @@ -130,4 +139,7 @@ ATTRS{idVendor}=="10af", ATTRS{idProduct}=="0001", ENV{UPOWER_BATTERY_TYPE}="ups ATTRS{idVendor}=="10af", ATTRS{idProduct}=="0004", ENV{UPOWER_BATTERY_TYPE}="ups" ATTRS{idVendor}=="10af", ATTRS{idProduct}=="0008", ENV{UPOWER_BATTERY_TYPE}="ups" +# AEG +ATTRS{idVendor}=="2b2d", ATTRS{idProduct}=="ffff", ENV{UPOWER_BATTERY_TYPE}="ups" + LABEL="up_hid_end" diff --git a/server/Makefile.in b/server/Makefile.in index 398db3f..e81745a 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -255,6 +255,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/server/netget.c b/server/netget.c index 9d6cf08..d876891 100644 --- a/server/netget.c +++ b/server/netget.c @@ -156,9 +156,10 @@ static void get_type(nut_ctype_t *client, const char *upsname, const char *var) return; } - /* hmm... */ + /* Any variable that is not string | range | enum is just a simple + * numeric value */ - sendback(client, "TYPE %s %s UNKNOWN\n", upsname, var); + sendback(client, "TYPE %s %s NUMBER\n", upsname, var); } static void get_var_server(nut_ctype_t *client, const char *upsname, const char *var) diff --git a/server/upsd.c b/server/upsd.c index 7dcda1d..c6efb21 100644 --- a/server/upsd.c +++ b/server/upsd.c @@ -334,7 +334,7 @@ int sendback(nut_ctype_t *client, const char *fmt, ...) res = write(client->sock_fd, ans, len); } - upsdebugx(2, "write: [destfd=%d] [len=%d] [%s]", client->sock_fd, len, rtrim(ans, '\n')); + upsdebugx(2, "write: [destfd=%d] [len=%d] [%s]", client->sock_fd, len, str_rtrim(ans, '\n')); if (len != res) { upslog_with_errno(LOG_NOTICE, "write() failed for %s", client->addr); diff --git a/tests/Makefile.in b/tests/Makefile.in index ac73f55..5991274 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -444,6 +444,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/tools/Makefile.am b/tools/Makefile.am index f8add46..1ba2820 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -17,7 +17,7 @@ SUBDIRS = . nut-scanner EXTRA_DIST = nut-usbinfo.pl nut-recorder.sh nut-ddl-dump.sh \ - gitlog2changelog.py nut-snmpinfo.py + gitlog2changelog.py nut-snmpinfo.py driver-list-format.sh all: nut-scanner-deps @@ -49,6 +49,7 @@ nut-scanner-deps: # call the USB info script upon "make dist", and if Perl is present # call the SNMP info script upon "make dist", and if Python is present # and call both for building nut-scanner +# Also ensure that data/driver.list is well formatted dist-hook: @if python -c 1; then \ echo "Regenerating the SNMP helper files."; \ @@ -70,4 +71,6 @@ dist-hook: echo "----------------------------------------------------------------------"; \ fi + @$(distdir)/driver-list-format.sh; + .PHONY: nut-scanner-deps nut-scanner-snmp-deps nut-scanner-usb-deps diff --git a/tools/Makefile.in b/tools/Makefile.in index d132e0d..c492ea0 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -243,6 +243,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ @@ -393,7 +394,7 @@ udevdir = @udevdir@ # sub-directory SUBDIRS = . nut-scanner EXTRA_DIST = nut-usbinfo.pl nut-recorder.sh nut-ddl-dump.sh \ - gitlog2changelog.py nut-snmpinfo.py + gitlog2changelog.py nut-snmpinfo.py driver-list-format.sh all: all-recursive @@ -740,6 +741,7 @@ nut-scanner-deps: # call the USB info script upon "make dist", and if Perl is present # call the SNMP info script upon "make dist", and if Python is present # and call both for building nut-scanner +# Also ensure that data/driver.list is well formatted dist-hook: @if python -c 1; then \ echo "Regenerating the SNMP helper files."; \ @@ -761,6 +763,8 @@ dist-hook: echo "----------------------------------------------------------------------"; \ fi + @$(distdir)/driver-list-format.sh; + .PHONY: nut-scanner-deps nut-scanner-snmp-deps nut-scanner-usb-deps # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/tools/driver-list-format.sh b/tools/driver-list-format.sh new file mode 100755 index 0000000..cf9f291 --- /dev/null +++ b/tools/driver-list-format.sh @@ -0,0 +1,32 @@ +#!/bin/sh +################################################################################ +# +# Ensure that driver.list and driver.list.in are properly formatted (with tabs) +# +################################################################################ + +# Adapt path for either dist target or manual call +CURRENT_PATH="`dirname $0`" +DRVLIST_PATH="" + +if [ -f "${CURRENT_PATH}/data/driver.list.in" ]; then + DRVLIST_PATH="${CURRENT_PATH}" +elif [ -f "${CURRENT_PATH}/../data/driver.list.in" ]; then + DRVLIST_PATH="${CURRENT_PATH}/.." +else + echo "Can't find driver.list in . or .." + exit 1 +fi + +echo "Checking whether driver.list[.in] are well formatted" +for drvfile in driver.list.in driver.list +do + if [ -f "${DRVLIST_PATH}/data/${drvfile}" ]; then + sed -e '/^#/!s/\" \+\"/\"\t\"/g' -e "/^#/!s/[[:blank:]]*$//" < "${DRVLIST_PATH}/data/${drvfile}" > "${DRVLIST_PATH}/data/${drvfile}.tabbed" + mv -f "${DRVLIST_PATH}/data/${drvfile}.tabbed" "${DRVLIST_PATH}/data/${drvfile}" + echo "Processed ${DRVLIST_PATH}/data/${drvfile}" + else + echo "Skipping ${drvfile} as it is missing..." + fi +done +echo "done" diff --git a/tools/nut-scanner/Makefile.in b/tools/nut-scanner/Makefile.in index 3ff07cd..4de16e0 100644 --- a/tools/nut-scanner/Makefile.in +++ b/tools/nut-scanner/Makefile.in @@ -301,6 +301,7 @@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBDIR = @LIBDIR@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ diff --git a/tools/nut-scanner/README b/tools/nut-scanner/README index d6e9d59..c5a8077 100644 --- a/tools/nut-scanner/README +++ b/tools/nut-scanner/README @@ -75,7 +75,7 @@ iteration function to display results: This library file and the associated header files are not installed by -default. You must `./configure --with-lib` to enable building and +default. You must `./configure --with-dev` to enable building and installing these files. The libraries can then be built and installed with `make` and `make install` as usual. This must be done before building other (non-NUT) programs which depend on them. diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h index 37298fa..ce19726 100644 --- a/tools/nut-scanner/nut-scan.h +++ b/tools/nut-scanner/nut-scan.h @@ -1,7 +1,6 @@ -/* nut-scan.h: detect NUT services - * +/* * Copyright (C) - * 2011 - Frederic Bohe + * 2011 - EATON * 2012 - Arnaud Quette * * This program is free software; you can redistribute it and/or modify @@ -19,6 +18,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file nut-scan.h + \brief general header for nut-scanner + \author Frederic Bohe + \author Arnaud Quette +*/ + #ifndef NUT_SCAN_H #define NUT_SCAN_H diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c index 4451158..e0a6e33 100644 --- a/tools/nut-scanner/nut-scanner.c +++ b/tools/nut-scanner/nut-scanner.c @@ -1,7 +1,5 @@ -/* nut-scanner.c: a tool to detect NUT supported devices - * - * Copyright (C) - * 2011 - 2012 Arnaud Quette +/* + * Copyright (C) 2011 - 2012 Arnaud Quette * * 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 @@ -18,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file nut-scanner.c + \brief a tool to detect NUT supported devices + \author Arnaud Quette +*/ + #include #include #include @@ -532,26 +535,26 @@ display_help: } #ifdef HAVE_PTHREAD - if( allow_usb && nutscan_avail_usb ) { - pthread_join(thread[TYPE_USB],NULL); + if( allow_usb && nutscan_avail_usb && thread[TYPE_USB]) { + pthread_join(thread[TYPE_USB], NULL); } - if( allow_snmp && nutscan_avail_snmp ) { - pthread_join(thread[TYPE_SNMP],NULL); + if( allow_snmp && nutscan_avail_snmp && thread[TYPE_SNMP]) { + pthread_join(thread[TYPE_SNMP], NULL); } - if( allow_xml && nutscan_avail_xml_http ) { - pthread_join(thread[TYPE_XML],NULL); + if( allow_xml && nutscan_avail_xml_http && thread[TYPE_XML]) { + pthread_join(thread[TYPE_XML], NULL); } - if( allow_oldnut && nutscan_avail_nut ) { - pthread_join(thread[TYPE_NUT],NULL); + if( allow_oldnut && nutscan_avail_nut && thread[TYPE_NUT]) { + pthread_join(thread[TYPE_NUT], NULL); } - if( allow_avahi && nutscan_avail_avahi ) { - pthread_join(thread[TYPE_AVAHI],NULL); + if( allow_avahi && nutscan_avail_avahi && thread[TYPE_AVAHI]) { + pthread_join(thread[TYPE_AVAHI], NULL); } - if( allow_ipmi && nutscan_avail_ipmi ) { - pthread_join(thread[TYPE_IPMI],NULL); + if( allow_ipmi && nutscan_avail_ipmi && thread[TYPE_IPMI]) { + pthread_join(thread[TYPE_IPMI], NULL); } - if (allow_eaton_serial) { - pthread_join(thread[TYPE_EATON_SERIAL],NULL); + if (allow_eaton_serial && thread[TYPE_EATON_SERIAL]) { + pthread_join(thread[TYPE_EATON_SERIAL], NULL); } #endif /* HAVE_PTHREAD */ diff --git a/tools/nut-scanner/nutscan-device.c b/tools/nut-scanner/nutscan-device.c index c1b3268..58c8874 100644 --- a/tools/nut-scanner/nutscan-device.c +++ b/tools/nut-scanner/nutscan-device.c @@ -1,6 +1,5 @@ -/* device.c: manipulation of a container describing a NUT device - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -16,6 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file nutscan-device.c + \brief manipulation of a container describing a NUT device + \author Frederic Bohe +*/ + #include "nutscan-device.h" #include #include diff --git a/tools/nut-scanner/nutscan-device.h b/tools/nut-scanner/nutscan-device.h index 8960410..5001a6a 100644 --- a/tools/nut-scanner/nutscan-device.h +++ b/tools/nut-scanner/nutscan-device.h @@ -1,6 +1,5 @@ -/* device.h: definition of a container describing a NUT device - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -16,6 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file nutscan-device.h + \brief definition of a container describing a NUT discovered device + \author Frederic Bohe +*/ + #ifndef SCAN_DEVICE #define SCAN_DEVICE diff --git a/tools/nut-scanner/nutscan-display.c b/tools/nut-scanner/nutscan-display.c index 411ed25..6a2987d 100644 --- a/tools/nut-scanner/nutscan-display.c +++ b/tools/nut-scanner/nutscan-display.c @@ -1,6 +1,5 @@ -/* display.c: format and display scanned devices - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file nutscan-display.c + \brief format and display scanned devices + \author Frederic Bohe +*/ + #include "common.h" #include #include "nutscan-device.h" diff --git a/tools/nut-scanner/nutscan-init.c b/tools/nut-scanner/nutscan-init.c index 16ea760..5f08ea2 100644 --- a/tools/nut-scanner/nutscan-init.c +++ b/tools/nut-scanner/nutscan-init.c @@ -1,6 +1,5 @@ -/* nutscan-init.c: init functions for nut scanner library - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,8 +16,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file nutscan-init.c + \brief init functions for nut scanner library + \author Frederic Bohe +*/ + #include "common.h" #include +#include +#include +#include +#include int nutscan_avail_avahi = 0; int nutscan_avail_ipmi = 0; @@ -27,31 +35,72 @@ int nutscan_avail_snmp = 0; int nutscan_avail_usb = 0; int nutscan_avail_xml_http = 0; -int nutscan_load_usb_library(void); -int nutscan_load_snmp_library(void); -int nutscan_load_neon_library(void); -int nutscan_load_avahi_library(void); -int nutscan_load_ipmi_library(void); -int nutscan_load_upsclient_library(void); +int nutscan_load_usb_library(const char *libname_path); +int nutscan_load_snmp_library(const char *libname_path); +int nutscan_load_neon_library(const char *libname_path); +int nutscan_load_avahi_library(const char *libname_path); +int nutscan_load_ipmi_library(const char *libname_path); +int nutscan_load_upsclient_library(const char *libname_path); + +/* FIXME: would be good to get more from /etc/ld.so.conf[.d] */ +char * search_paths[] = { + LIBDIR, + "/usr/lib64", + "/lib64", + "/usr/lib", + "/lib", + "/usr/local/lib", + NULL +}; + +const char * get_libname(const char* base_libname) +{ + DIR *dp; + struct dirent *dirp; + int index = 0; + char *libname_path = NULL; + char current_test_path[LARGEBUF]; + + for(index = 0 ; (search_paths[index] != NULL) && (libname_path == NULL) ; index++) + { + memset(current_test_path, 0, LARGEBUF); + + if ((dp = opendir(search_paths[index])) == NULL) + continue; + + while ((dirp = readdir(dp)) != NULL) + { + if(!strncmp(dirp->d_name, base_libname, strlen(base_libname))) { + snprintf(current_test_path, LARGEBUF, "%s/%s", search_paths[index], dirp->d_name); + libname_path = realpath(current_test_path, NULL); + if (libname_path != NULL) + break; + } + } + closedir(dp); + } + /* fprintf(stderr,"Looking for lib %s, found %s\n", base_libname, (libname_path!=NULL)?libname_path:"NULL");*/ + return libname_path; +} void nutscan_init(void) { #ifdef WITH_USB - nutscan_avail_usb = nutscan_load_usb_library(); + nutscan_avail_usb = nutscan_load_usb_library(get_libname("libusb-0.1.so")); #endif #ifdef WITH_SNMP - nutscan_avail_snmp = nutscan_load_snmp_library(); + nutscan_avail_snmp = nutscan_load_snmp_library(get_libname("libnetsnmp.so")); #endif #ifdef WITH_NEON - nutscan_avail_xml_http = nutscan_load_neon_library(); + nutscan_avail_xml_http = nutscan_load_neon_library(get_libname("libneon.so")); #endif #ifdef WITH_AVAHI - nutscan_avail_avahi = nutscan_load_avahi_library(); + nutscan_avail_avahi = nutscan_load_avahi_library(get_libname("libavahi-client.so")); #endif #ifdef WITH_FREEIPMI - nutscan_avail_ipmi = nutscan_load_ipmi_library(); + nutscan_avail_ipmi = nutscan_load_ipmi_library(get_libname("libfreeipmi.so")); #endif - nutscan_avail_nut = nutscan_load_upsclient_library(); + nutscan_avail_nut = nutscan_load_upsclient_library(get_libname("libupsclient.so")); } void nutscan_free(void) diff --git a/tools/nut-scanner/nutscan-init.h b/tools/nut-scanner/nutscan-init.h index daf1358..e242693 100644 --- a/tools/nut-scanner/nutscan-init.h +++ b/tools/nut-scanner/nutscan-init.h @@ -1,6 +1,5 @@ -/* nutscan-init.h: initialisation data - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -16,6 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file nutscan-init.h + \brief initialisation data + \author Frederic Bohe +*/ + #ifndef SCAN_INIT #define SCAN_INIT diff --git a/tools/nut-scanner/nutscan-ip.c b/tools/nut-scanner/nutscan-ip.c index 8788018..5622242 100644 --- a/tools/nut-scanner/nutscan-ip.c +++ b/tools/nut-scanner/nutscan-ip.c @@ -1,6 +1,5 @@ -/* ip.c: iterator for IPv4 or IPv6 addresses - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file nutscan-ip.c + \brief iterator for IPv4 or IPv6 addresses + \author Frederic Bohe +*/ + #include "nutscan-ip.h" #include #include "common.h" diff --git a/tools/nut-scanner/nutscan-ip.h b/tools/nut-scanner/nutscan-ip.h index b28ff00..d0cc78e 100644 --- a/tools/nut-scanner/nutscan-ip.h +++ b/tools/nut-scanner/nutscan-ip.h @@ -1,6 +1,5 @@ -/* ip.h: iterator for IPv4 or IPv6 addresses - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -16,6 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file nutscan-ip.h + \brief iterator for IPv4 or IPv6 addresses + \author Frederic Bohe +*/ + #ifndef SCAN_IP #define SCAN_IP diff --git a/tools/nut-scanner/nutscan-serial.c b/tools/nut-scanner/nutscan-serial.c index 65e0c03..42d9fca 100644 --- a/tools/nut-scanner/nutscan-serial.c +++ b/tools/nut-scanner/nutscan-serial.c @@ -1,6 +1,5 @@ -/* nutscan-serial.c: helper functions to get serial devices name - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file nutscan-serial.c + \brief helper functions to get serial devices name + \author Frederic Bohe + \author Arnaud Quette +*/ + #include "nutscan-serial.h" #include #include diff --git a/tools/nut-scanner/nutscan-serial.h b/tools/nut-scanner/nutscan-serial.h index 175b1d7..2471247 100644 --- a/tools/nut-scanner/nutscan-serial.h +++ b/tools/nut-scanner/nutscan-serial.h @@ -1,6 +1,5 @@ -/* nutscan-serial.h: helper functions to get serial devices name - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -16,6 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file nutscan-serial.h + \brief helper functions to get serial devices name + \author Frederic Bohe +*/ + #ifndef SCAN_SERIAL #define SCAN_SERIAL diff --git a/tools/nut-scanner/nutscan-snmp.h b/tools/nut-scanner/nutscan-snmp.h index 38202a0..f6aa512 100644 --- a/tools/nut-scanner/nutscan-snmp.h +++ b/tools/nut-scanner/nutscan-snmp.h @@ -1,5 +1,6 @@ /* nutscan-snmp - * Copyright (C) 2011 - Frederic Bohe + * Copyright (C) 2011 - Frederic Bohe + * Copyright (C) 2016 - Arnaud Quette * * 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 @@ -27,24 +28,28 @@ typedef struct { /* SNMP IDs device table */ static snmp_device_id_t snmp_device_table[] = { - { ".1.3.6.1.4.1.13742.1.1.12.0" , "raritan", ".1.3.6.1.4.1.13742"}, - { "" , "xppc", ".1.3.6.1.4.1.935"}, - { "1.3.6.1.4.1.534.1.1.2.0" , "pw", ".1.3.6.1.4.1.534.1"}, - { "1.3.6.1.2.1.33.1.1.1.0" , "ietf", ".1.3.6.1.2.1.33"}, - { ".1.3.6.1.4.1.232.165.3.1.1.0" , "cpqpower", ".1.3.6.1.4.1.232.165.3"}, - { ".1.3.6.1.4.1.17373.3.1.1.0" , "aphel_genesisII", ".1.3.6.1.4.1.17373"}, - { ".1.3.6.1.4.1.534.6.6.6.1.1.12.0" , "aphel_revelation", ".1.3.6.1.4.1.534.6.6.6"}, - { ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0" , "eaton_epdu", ".1.3.6.1.4.1.534.6.6.7"}, - { "" , "pulizzi_monitored", NULL}, - { ".1.3.6.1.4.1.20677.1" , "pulizzi_switched1", ".1.3.6.1.4.1.20677.1"}, - { ".1.3.6.1.4.1.20677.1" , "pulizzi_switched2", ".1.3.6.1.4.1.20677.2"}, - { ".1.3.6.1.4.1.3808.1.1.1.1.1.1.0" , "cyberpower", ".1.3.6.1.4.1.3808"}, - { ".1.3.6.1.4.1.705.1.1.1.0" , "mge", ".1.3.6.1.4.1.705.1"}, - { "" , "delta_ups", ".1.3.6.1.4.1.2254.2.4"}, - { ".1.3.6.1.4.1.4555.1.1.1.1.1.1.0" , "netvision", ".1.3.6.1.4.1.4555.1.1.1"}, - { ".1.3.6.1.4.1.318.1.1.1.1.1.1.0" , "apcc", NULL}, - { ".1.3.6.1.4.1.4779.1.3.5.2.1.24.1" , "baytech", NULL}, - { ".1.3.6.1.4.1.2947.1.1.2.0" , "bestpower", NULL}, + { "", "apc_ats", ".1.3.6.1.4.1.318.1.3.11"}, + { ".1.3.6.1.4.1.534.10.2.1.2.0", "eaton_ats", ".1.3.6.1.4.1.705.1"}, + { ".1.3.6.1.4.1.13742.1.1.12.0", "raritan", ".1.3.6.1.4.1.13742"}, + { "", "xppc", ".1.3.6.1.4.1.935"}, + { "1.3.6.1.4.1.534.1.1.2.0", "pw", ".1.3.6.1.4.1.534.1"}, + { "1.3.6.1.4.1.534.1.1.2.0", "pxgx_ups", ".1.3.6.1.4.1.534.2.12"}, + { "1.3.6.1.2.1.33.1.1.1.0", "ietf", ".1.3.6.1.2.1.33"}, + { "", "ietf", ".1.3.6.1.4.1.850.1"}, + { ".1.3.6.1.4.1.232.165.3.1.1.0", "cpqpower", ".1.3.6.1.4.1.232.165.3"}, + { ".1.3.6.1.4.1.17373.3.1.1.0", "aphel_genesisII", ".1.3.6.1.4.1.17373"}, + { ".1.3.6.1.4.1.534.6.6.6.1.1.12.0", "aphel_revelation", ".1.3.6.1.4.1.534.6.6.6"}, + { ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0", "eaton_epdu", ".1.3.6.1.4.1.534.6.6.7"}, + { ".1.3.6.1.4.1.20677.1", "pulizzi_switched1", ".1.3.6.1.4.1.20677.1"}, + { ".1.3.6.1.4.1.20677.1", "pulizzi_switched2", ".1.3.6.1.4.1.20677.2"}, + { ".1.3.6.1.4.1.3808.1.1.1.1.1.1.0", "cyberpower", ".1.3.6.1.4.1.3808"}, + { ".1.3.6.1.4.1.705.1.1.1.0", "mge", ".1.3.6.1.4.1.705.1"}, + { "", "delta_ups", ".1.3.6.1.4.1.2254.2.4"}, + { "", "huawei", ".1.3.6.1.4.1.8072.3.2.10"}, + { ".1.3.6.1.4.1.4555.1.1.1.1.1.1.0", "netvision", ".1.3.6.1.4.1.4555.1.1.1"}, + { ".1.3.6.1.4.1.318.1.1.1.1.1.1.0", "apcc", NULL}, + { ".1.3.6.1.4.1.4779.1.3.5.2.1.24.1", "baytech", NULL}, + { ".1.3.6.1.4.1.2947.1.1.2.0", "bestpower", NULL}, /* Terminating entry */ { NULL, NULL, NULL} }; diff --git a/tools/nut-scanner/nutscan-usb.h b/tools/nut-scanner/nutscan-usb.h index a35513a..c0c1200 100644 --- a/tools/nut-scanner/nutscan-usb.h +++ b/tools/nut-scanner/nutscan-usb.h @@ -50,6 +50,7 @@ static usb_device_id_t usb_device_table[] = { { 0x0463, 0x0001, "usbhid-ups" }, { 0x0463, 0xffff, "usbhid-ups" }, { 0x047c, 0xffff, "usbhid-ups" }, + { 0x0483, 0x0035, "nutdrv_qx" }, { 0x04b4, 0x5500, "riello_usb" }, { 0x04d8, 0xd004, "usbhid-ups" }, { 0x04d8, 0xd005, "usbhid-ups" }, @@ -126,6 +127,7 @@ static usb_device_id_t usb_device_table[] = { { 0x10af, 0x0004, "usbhid-ups" }, { 0x10af, 0x0008, "usbhid-ups" }, { 0x14f0, 0x00c9, "blazer_usb" }, + { 0x2b2d, 0xffff, "usbhid-ups" }, { 0xffff, 0x0000, "blazer_usb" }, /* Terminating entry */ { -1, -1, NULL } diff --git a/tools/nut-scanner/scan_avahi.c b/tools/nut-scanner/scan_avahi.c index 198e1f2..ec3beb8 100644 --- a/tools/nut-scanner/scan_avahi.c +++ b/tools/nut-scanner/scan_avahi.c @@ -1,6 +1,5 @@ -/* scan_avahi.c: detect NUT avahi services - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -16,6 +15,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file scan_avahi.c + \brief detect NUT through Avahi mDNS / DNS-SD services + \author Frederic Bohe +*/ + #include "common.h" #include "nut-scan.h" @@ -36,7 +41,6 @@ #include /* dynamic link library stuff */ -static char * libname = "libavahi-client"; static lt_dlhandle dl_handle = NULL; static const char *dl_error = NULL; @@ -83,125 +87,129 @@ static char * (*nut_avahi_address_snprint)(char *ret_s, size_t length, const Ava static const AvahiPoll* (*nut_avahi_simple_poll_get)(AvahiSimplePoll *s); /* return 0 on error */ -int nutscan_load_avahi_library() +int nutscan_load_avahi_library(const char *libname_path) { - if( dl_handle != NULL ) { - /* if previous init failed */ - if( dl_handle == (void *)1 ) { - return 0; - } - /* init has already been done */ - return 1; - } + if( dl_handle != NULL ) { + /* if previous init failed */ + if( dl_handle == (void *)1 ) { + return 0; + } + /* init has already been done */ + return 1; + } - if( lt_dlinit() != 0 ) { - fprintf(stderr, "Error initializing lt_init\n"); - return 0; - } + if (libname_path == NULL) { + fprintf(stderr, "AVAHI client library not found. AVAHI search disabled.\n"); + return 0; + } - dl_handle = lt_dlopenext(libname); - if (!dl_handle) { - dl_error = lt_dlerror(); - goto err; - } - lt_dlerror(); /* Clear any existing error */ - *(void **) (&nut_avahi_service_browser_get_client) = lt_dlsym(dl_handle, "avahi_service_browser_get_client"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + if( lt_dlinit() != 0 ) { + fprintf(stderr, "Error initializing lt_init\n"); + return 0; + } - *(void **) (&nut_avahi_simple_poll_loop) = lt_dlsym(dl_handle, "avahi_simple_poll_loop"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + dl_handle = lt_dlopen(libname_path); + if (!dl_handle) { + dl_error = lt_dlerror(); + goto err; + } + lt_dlerror(); /* Clear any existing error */ + *(void **) (&nut_avahi_service_browser_get_client) = lt_dlsym(dl_handle, "avahi_service_browser_get_client"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_client_free) = lt_dlsym(dl_handle, "avahi_client_free"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_simple_poll_loop) = lt_dlsym(dl_handle, "avahi_simple_poll_loop"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_client_errno) = lt_dlsym(dl_handle, "avahi_client_errno"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_client_free) = lt_dlsym(dl_handle, "avahi_client_free"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_free) = lt_dlsym(dl_handle, "avahi_free"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_client_errno) = lt_dlsym(dl_handle, "avahi_client_errno"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_simple_poll_quit) = lt_dlsym(dl_handle, "avahi_simple_poll_quit"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_free) = lt_dlsym(dl_handle, "avahi_free"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_client_new) = lt_dlsym(dl_handle, "avahi_client_new"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_simple_poll_quit) = lt_dlsym(dl_handle, "avahi_simple_poll_quit"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_simple_poll_free) = lt_dlsym(dl_handle, "avahi_simple_poll_free"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_client_new) = lt_dlsym(dl_handle, "avahi_client_new"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_service_resolver_new) = lt_dlsym(dl_handle, "avahi_service_resolver_new"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_simple_poll_free) = lt_dlsym(dl_handle, "avahi_simple_poll_free"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_strerror) = lt_dlsym(dl_handle, "avahi_strerror"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_service_resolver_new) = lt_dlsym(dl_handle, "avahi_service_resolver_new"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_service_resolver_get_client) = lt_dlsym(dl_handle, "avahi_service_resolver_get_client"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_strerror) = lt_dlsym(dl_handle, "avahi_strerror"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_service_browser_new) = lt_dlsym(dl_handle, "avahi_service_browser_new"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_service_resolver_get_client) = lt_dlsym(dl_handle, "avahi_service_resolver_get_client"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_service_resolver_free) = lt_dlsym(dl_handle, "avahi_service_resolver_free"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_service_browser_new) = lt_dlsym(dl_handle, "avahi_service_browser_new"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_simple_poll_new) = lt_dlsym(dl_handle, "avahi_simple_poll_new"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_service_resolver_free) = lt_dlsym(dl_handle, "avahi_service_resolver_free"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_string_list_to_string) = lt_dlsym(dl_handle, "avahi_string_list_to_string"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_simple_poll_new) = lt_dlsym(dl_handle, "avahi_simple_poll_new"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_service_browser_free) = lt_dlsym(dl_handle, "avahi_service_browser_free"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_string_list_to_string) = lt_dlsym(dl_handle, "avahi_string_list_to_string"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_address_snprint) = lt_dlsym(dl_handle, "avahi_address_snprint"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_service_browser_free) = lt_dlsym(dl_handle, "avahi_service_browser_free"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_avahi_simple_poll_get) = lt_dlsym(dl_handle, "avahi_simple_poll_get"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_avahi_address_snprint) = lt_dlsym(dl_handle, "avahi_address_snprint"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - return 1; + *(void **) (&nut_avahi_simple_poll_get) = lt_dlsym(dl_handle, "avahi_simple_poll_get"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } + + return 1; err: - fprintf(stderr, "Cannot load AVAHI library (%s) : %s. AVAHI search disabled.\n", libname, dl_error); - - dl_handle = (void *)1; + fprintf(stderr, "Cannot load AVAHI library (%s) : %s. AVAHI search disabled.\n", libname_path, dl_error); + dl_handle = (void *)1; lt_dlexit(); - return 0; + return 0; } /* end of dynamic link library stuff */ diff --git a/tools/nut-scanner/scan_eaton_serial.c b/tools/nut-scanner/scan_eaton_serial.c index ecfbe14..84baeeb 100644 --- a/tools/nut-scanner/scan_eaton_serial.c +++ b/tools/nut-scanner/scan_eaton_serial.c @@ -1,6 +1,5 @@ -/* scan_eaton_serial.c: detect Eaton serial XCP, SHUT and Q1 devices - * - * Copyright (C) 2012 Arnaud Quette +/* + * Copyright (C) 2012 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file scan_eaton_serial.c + \brief detect Eaton serial XCP, SHUT and Q1 devices + \author Arnaud Quette +*/ + #include "common.h" /* Need this on AIX when using xlc to get alloca */ diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c index 4da3dcd..5cb651c 100644 --- a/tools/nut-scanner/scan_ipmi.c +++ b/tools/nut-scanner/scan_ipmi.c @@ -1,5 +1,4 @@ -/* scan_ipmi.c: detect NUT supported Power Supply Units - * +/* * Copyright (C) * 2011 - 2012 Arnaud Quette * @@ -17,6 +16,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/*! \file scan_ipmi.c + \brief detect NUT supported Power Supply Units + \author Arnaud Quette +*/ + #include "common.h" #include "nut-scan.h" @@ -35,7 +40,6 @@ #define IPMI_RETRANSMISSION_TIMEOUT_LENGTH_DEFAULT 250 /* dynamic link library stuff */ -static char * libname = "libfreeipmi"; static lt_dlhandle dl_handle = NULL; static const char *dl_error = NULL; @@ -112,7 +116,7 @@ static void (*nut_ipmi_ctx_destroy) (ipmi_ctx_t ctx); static nutscan_device_t * nutscan_scan_ipmi_device(const char * IPaddr, nutscan_ipmi_t * sec); /* Return 0 on error */ -int nutscan_load_ipmi_library() +int nutscan_load_ipmi_library(const char *libname_path) { if( dl_handle != NULL ) { /* if previous init failed */ @@ -123,12 +127,17 @@ int nutscan_load_ipmi_library() return 1; } + if (libname_path == NULL) { + fprintf(stderr, "IPMI library not found. IPMI search disabled.\n"); + return 0; + } + if( lt_dlinit() != 0 ) { fprintf(stderr, "Error initializing lt_init\n"); return 0; } - dl_handle = lt_dlopenext(libname); + dl_handle = lt_dlopen(libname_path); if (!dl_handle) { dl_error = lt_dlerror(); goto err; @@ -234,7 +243,7 @@ int nutscan_load_ipmi_library() return 1; err: - fprintf(stderr, "Cannot load IPMI library (%s) : %s. IPMI search disabled.\n", libname, dl_error); + fprintf(stderr, "Cannot load IPMI library (%s) : %s. IPMI search disabled.\n", libname_path, dl_error); dl_handle = (void *)1; lt_dlexit(); return 0; diff --git a/tools/nut-scanner/scan_nut.c b/tools/nut-scanner/scan_nut.c index 005cfe6..f53c66b 100644 --- a/tools/nut-scanner/scan_nut.c +++ b/tools/nut-scanner/scan_nut.c @@ -1,6 +1,5 @@ -/* scan_nut.c: detect remote NUT services - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file scan_nut.c + \brief detect remote NUT services + \author Frederic Bohe +*/ + #include "common.h" #include "upsclient.h" #include "nut-scan.h" @@ -26,7 +30,6 @@ #include /* dynamic link library stuff */ -static char * libname = "libupsclient"; static lt_dlhandle dl_handle = NULL; static const char *dl_error = NULL; @@ -50,67 +53,71 @@ struct scan_nut_arg { }; /* return 0 on error */ -int nutscan_load_upsclient_library() +int nutscan_load_upsclient_library(const char *libname_path) { + if( dl_handle != NULL ) { + /* if previous init failed */ + if( dl_handle == (void *)1 ) { + return 0; + } + /* init has already been done */ + return 1; + } - if( dl_handle != NULL ) { - /* if previous init failed */ - if( dl_handle == (void *)1 ) { - return 0; - } - /* init has already been done */ - return 1; - } + if (libname_path == NULL) { + fprintf(stderr, "NUT client library not found. NUT search disabled.\n"); + return 0; + } - if( lt_dlinit() != 0 ) { - fprintf(stderr, "Error initializing lt_init\n"); - return 0; - } + if( lt_dlinit() != 0 ) { + fprintf(stderr, "Error initializing lt_init\n"); + return 0; + } - dl_handle = lt_dlopenext(libname); - if (!dl_handle) { - dl_error = lt_dlerror(); - goto err; - } + dl_handle = lt_dlopen(libname_path); + if (!dl_handle) { + dl_error = lt_dlerror(); + goto err; + } - lt_dlerror(); /* Clear any existing error */ + lt_dlerror(); /* Clear any existing error */ - *(void **) (&nut_upscli_splitaddr) = lt_dlsym(dl_handle, - "upscli_splitaddr"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_upscli_splitaddr) = lt_dlsym(dl_handle, + "upscli_splitaddr"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_upscli_tryconnect) = lt_dlsym(dl_handle, - "upscli_tryconnect"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_upscli_tryconnect) = lt_dlsym(dl_handle, + "upscli_tryconnect"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_upscli_list_start) = lt_dlsym(dl_handle, - "upscli_list_start"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_upscli_list_start) = lt_dlsym(dl_handle, + "upscli_list_start"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_upscli_list_next) = lt_dlsym(dl_handle, - "upscli_list_next"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_upscli_list_next) = lt_dlsym(dl_handle, + "upscli_list_next"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_upscli_disconnect) = lt_dlsym(dl_handle, - "upscli_disconnect"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_upscli_disconnect) = lt_dlsym(dl_handle, + "upscli_disconnect"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - return 1; + return 1; err: - fprintf(stderr, "Cannot load NUT library (%s) : %s. NUT search disabled.\n", libname, dl_error); - dl_handle = (void *)1; + fprintf(stderr, "Cannot load NUT library (%s) : %s. NUT search disabled.\n", libname_path, dl_error); + dl_handle = (void *)1; lt_dlexit(); - return 0; + return 0; } /* FIXME: SSL support */ diff --git a/tools/nut-scanner/scan_snmp.c b/tools/nut-scanner/scan_snmp.c index 0fcb9a6..994d695 100644 --- a/tools/nut-scanner/scan_snmp.c +++ b/tools/nut-scanner/scan_snmp.c @@ -1,6 +1,5 @@ -/* scan_snmp.c: detect NUT supported SNMP devices - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file scan_snmp.c + \brief detect NUT supported SNMP devices + \author Frederic Bohe +*/ + #include "common.h" #include "nut-scan.h" @@ -68,13 +72,10 @@ static nutscan_device_t * dev_ret = NULL; #ifdef HAVE_PTHREAD static pthread_mutex_t dev_mutex; -static pthread_t * thread_array = NULL; -static int thread_count = 0; #endif long g_usec_timeout ; /* dynamic link library stuff */ -static char * libname = "libnetsnmp"; static lt_dlhandle dl_handle = NULL; static const char *dl_error = NULL; @@ -103,7 +104,7 @@ static oid * (*nut_usmHMACSHA1AuthProtocol); static oid * (*nut_usmDESPrivProtocol); /* return 0 on error */ -int nutscan_load_snmp_library() +int nutscan_load_snmp_library(const char *libname_path) { if( dl_handle != NULL ) { /* if previous init failed */ @@ -114,12 +115,17 @@ int nutscan_load_snmp_library() return 1; } - if( lt_dlinit() != 0 ) { - fprintf(stderr, "Error initializing lt_init\n"); - return 0; - } + if (libname_path == NULL) { + fprintf(stderr, "SNMP library not found. SNMP search disabled.\n"); + return 0; + } - dl_handle = lt_dlopenext(libname); + if( lt_dlinit() != 0 ) { + fprintf(stderr, "Error initializing lt_init\n"); + return 0; + } + + dl_handle = lt_dlopen(libname_path); if (!dl_handle) { dl_error = lt_dlerror(); goto err; @@ -232,7 +238,7 @@ int nutscan_load_snmp_library() return 1; err: - fprintf(stderr, "Cannot load SNMP library (%s) : %s. SNMP search disabled.\n", libname, dl_error); + fprintf(stderr, "Cannot load SNMP library (%s) : %s. SNMP search disabled.\n", libname_path, dl_error); dl_handle = (void *)1; lt_dlexit(); return 0; @@ -655,6 +661,8 @@ nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip char * ip_str = NULL; #ifdef HAVE_PTHREAD pthread_t thread; + pthread_t * thread_array = NULL; + int thread_count = 0; pthread_mutex_init(&dev_mutex,NULL); #endif @@ -696,8 +704,9 @@ nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip pthread_mutex_destroy(&dev_mutex); free(thread_array); #endif - - return nutscan_rewind_device(dev_ret); + nutscan_device_t * result = nutscan_rewind_device(dev_ret); + dev_ret = NULL; + return result; } #else /* WITH_SNMP */ nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip,long usec_timeout, nutscan_snmp_t * sec) diff --git a/tools/nut-scanner/scan_usb.c b/tools/nut-scanner/scan_usb.c index c82dad5..1027e93 100644 --- a/tools/nut-scanner/scan_usb.c +++ b/tools/nut-scanner/scan_usb.c @@ -1,6 +1,5 @@ -/* scan_usb.c: detect NUT supported USB devices - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file scan_usb.c + \brief detect NUT supported USB devices + \author Frederic Bohe +*/ + #include "common.h" #include "nut-scan.h" @@ -28,7 +32,6 @@ #include /* dynamic link library stuff */ -static char * libname = "libusb"; static lt_dlhandle dl_handle = NULL; static const char *dl_error = NULL; static int (*nut_usb_close)(usb_dev_handle *dev); @@ -42,75 +45,80 @@ static usb_dev_handle * (*nut_usb_open)(struct usb_device *dev); static int (*nut_usb_find_devices)(void); /* return 0 on error */ -int nutscan_load_usb_library() +int nutscan_load_usb_library(const char *libname_path) { - if( dl_handle != NULL ) { - /* if previous init failed */ - if( dl_handle == (void *)1 ) { - return 0; - } - /* init has already been done */ - return 1; - } + if( dl_handle != NULL ) { + /* if previous init failed */ + if( dl_handle == (void *)1 ) { + return 0; + } + /* init has already been done */ + return 1; + } + + if (libname_path == NULL) { + fprintf(stderr, "USB library not found. USB search disabled.\n"); + return 0; + } if( lt_dlinit() != 0 ) { fprintf(stderr, "Error initializing lt_init\n"); return 0; } - dl_handle = lt_dlopenext(libname); - if (!dl_handle) { - dl_error = lt_dlerror(); - goto err; - } - lt_dlerror(); /* Clear any existing error */ - *(void **) (&nut_usb_close) = lt_dlsym(dl_handle, "usb_close"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + dl_handle = lt_dlopen(libname_path); + if (!dl_handle) { + dl_error = lt_dlerror(); + goto err; + } + lt_dlerror(); /* Clear any existing error */ + *(void **) (&nut_usb_close) = lt_dlsym(dl_handle, "usb_close"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_usb_find_busses) = lt_dlsym(dl_handle, "usb_find_busses"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_usb_find_busses) = lt_dlsym(dl_handle, "usb_find_busses"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_usb_strerror) = lt_dlsym(dl_handle, "usb_strerror"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_usb_strerror) = lt_dlsym(dl_handle, "usb_strerror"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_usb_init) = lt_dlsym(dl_handle, "usb_init"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_usb_init) = lt_dlsym(dl_handle, "usb_init"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_usb_get_string_simple) = lt_dlsym(dl_handle, - "usb_get_string_simple"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_usb_get_string_simple) = lt_dlsym(dl_handle, + "usb_get_string_simple"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_usb_busses) = lt_dlsym(dl_handle, "usb_busses"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_usb_busses) = lt_dlsym(dl_handle, "usb_busses"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_usb_open) = lt_dlsym(dl_handle, "usb_open"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_usb_open) = lt_dlsym(dl_handle, "usb_open"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **)(&nut_usb_find_devices) = lt_dlsym(dl_handle,"usb_find_devices"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **)(&nut_usb_find_devices) = lt_dlsym(dl_handle,"usb_find_devices"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - return 1; + return 1; err: - fprintf(stderr, "Cannot load USB library (%s) : %s. USB search disabled.\n", libname, dl_error); - dl_handle = (void *)1; + fprintf(stderr, "Cannot load USB library (%s) : %s. USB search disabled.\n", libname_path, dl_error); + dl_handle = (void *)1; lt_dlexit(); - return 0; + return 0; } /* end of dynamic link library stuff */ @@ -177,7 +185,7 @@ nutscan_device_t * nutscan_scan_usb() dev->descriptor.iSerialNumber, string, sizeof(string)); if (ret > 0) { - serialnumber = strdup(rtrim(string, ' ')); + serialnumber = strdup(str_rtrim(string, ' ')); } } /* get product name */ @@ -186,7 +194,7 @@ nutscan_device_t * nutscan_scan_usb() dev->descriptor.iProduct, string, sizeof(string)); if (ret > 0) { - device_name = strdup(rtrim(string, ' ')); + device_name = strdup(str_rtrim(string, ' ')); } } @@ -196,7 +204,7 @@ nutscan_device_t * nutscan_scan_usb() dev->descriptor.iManufacturer, string, sizeof(string)); if (ret > 0) { - vendor_name = strdup(rtrim(string, ' ')); + vendor_name = strdup(str_rtrim(string, ' ')); } } diff --git a/tools/nut-scanner/scan_xml_http.c b/tools/nut-scanner/scan_xml_http.c index ee713e4..6320980 100644 --- a/tools/nut-scanner/scan_xml_http.c +++ b/tools/nut-scanner/scan_xml_http.c @@ -1,6 +1,5 @@ -/* scan_xml_http.c: detect NUT supported XML HTTP devices - * - * Copyright (C) 2011 - Frederic Bohe +/* + * Copyright (C) 2011 - EATON * * 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 @@ -17,6 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/*! \file scan_xml_http.c + \brief detect NUT supported XML HTTP devices + \author Frederic Bohe +*/ + #include "common.h" #include "nut-scan.h" #ifdef WITH_NEON @@ -47,57 +51,61 @@ static ne_xml_parser * (*nut_ne_xml_create)(void); static int (*nut_ne_xml_parse)(ne_xml_parser *p, const char *block, size_t len); /* return 0 on error */ -int nutscan_load_neon_library() +int nutscan_load_neon_library(const char *libname_path) { + if( dl_handle != NULL ) { + /* if previous init failed */ + if( dl_handle == (void *)1 ) { + return 0; + } + /* init has already been done */ + return 1; + } - if( dl_handle != NULL ) { - /* if previous init failed */ - if( dl_handle == (void *)1 ) { - return 0; - } - /* init has already been done */ - return 1; - } + if (libname_path == NULL) { + fprintf(stderr, "Neon library not found. XML search disabled.\n"); + return 0; + } - if( lt_dlinit() != 0 ) { - fprintf(stderr, "Error initializing lt_init\n"); - return 0; - } + if( lt_dlinit() != 0 ) { + fprintf(stderr, "Error initializing lt_init\n"); + return 0; + } - dl_handle = lt_dlopenext(libname); - if (!dl_handle) { - dl_error = lt_dlerror(); - goto err; - } + dl_handle = lt_dlopen(libname_path); + if (!dl_handle) { + dl_error = lt_dlerror(); + goto err; + } - lt_dlerror(); /* Clear any existing error */ - *(void **) (&nut_ne_xml_push_handler) = lt_dlsym(dl_handle, - "ne_xml_push_handler"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + lt_dlerror(); /* Clear any existing error */ + *(void **) (&nut_ne_xml_push_handler) = lt_dlsym(dl_handle, + "ne_xml_push_handler"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_ne_xml_destroy) = lt_dlsym(dl_handle,"ne_xml_destroy"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_ne_xml_destroy) = lt_dlsym(dl_handle,"ne_xml_destroy"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_ne_xml_create) = lt_dlsym(dl_handle,"ne_xml_create"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_ne_xml_create) = lt_dlsym(dl_handle,"ne_xml_create"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - *(void **) (&nut_ne_xml_parse) = lt_dlsym(dl_handle,"ne_xml_parse"); - if ((dl_error = lt_dlerror()) != NULL) { - goto err; - } + *(void **) (&nut_ne_xml_parse) = lt_dlsym(dl_handle,"ne_xml_parse"); + if ((dl_error = lt_dlerror()) != NULL) { + goto err; + } - return 1; + return 1; err: - fprintf(stderr, "Cannot load XML library (%s) : %s. XML search disabled.\n", libname, dl_error); - dl_handle = (void *)1; + fprintf(stderr, "Cannot load XML library (%s) : %s. XML search disabled.\n", libname, dl_error); + dl_handle = (void *)1; lt_dlexit(); - return 0; + return 0; } static int startelm_cb(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { diff --git a/tools/nut-snmpinfo.py b/tools/nut-snmpinfo.py index 89cc359..32d1778 100755 --- a/tools/nut-snmpinfo.py +++ b/tools/nut-snmpinfo.py @@ -1,5 +1,6 @@ #!/usr/bin/env python -# Copyright (C) 2011 - Frederic Bohe +# Copyright (C) 2011 - Frederic Bohe +# Copyright (C) 2016 - Arnaud Quette # # 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 @@ -15,11 +16,11 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# This program extracts all SNMP information related to NUT snmp-ups -# drivers. +# This program extracts all SNMP information related to NUT snmp-ups drivers. import glob import re +import sys output_file_name="./nut-scanner/nutscan-snmp.h" output_file = open(output_file_name,'w') @@ -49,7 +50,8 @@ def expand_define(filename,constant): output_file.write( "/* nutscan-snmp\n" ) -output_file.write( " * Copyright (C) 2011 - Frederic Bohe \n" ) +output_file.write( " * Copyright (C) 2011 - Frederic Bohe \n" ) +output_file.write( " * Copyright (C) 2016 - Arnaud Quette \n" ) output_file.write( " *\n" ) output_file.write( " * This program is free software; you can redistribute it and/or modify\n" ) output_file.write( " * it under the terms of the GNU General Public License as published by\n" ) @@ -82,6 +84,13 @@ for filename in glob.glob('../drivers/*-mib.c'): list_of_line = open(filename,'r').read().split(';') for line in list_of_line: if "mib2nut_info_t" in line: + # Discard commented lines + # Note that we only search for the beginning of the comment, the + # end can be in the following line, due to the .split(';') + m = re.search(r'/\*.*', line) + if m: + #sys.stderr.write('discarding line'+line+'\n') + continue #clean up line line2 = re.sub("[\n\t\r}]", "", line) # split line @@ -129,7 +138,7 @@ for filename in glob.glob('../drivers/*-mib.c'): else: sysoid = "\"" + sysoid + "\"" - output_file.write( "\t{ \"" + oid + "\" , " + mib + ", " + sysoid + "},\n" ) + output_file.write( "\t{ \"" + oid + "\", " + mib + ", " + sysoid + "},\n" ) output_file.write( " /* Terminating entry */\n" ) output_file.write( " { NULL, NULL, NULL}\n" ) diff --git a/tools/nut-usbinfo.pl b/tools/nut-usbinfo.pl index 51a60e1..2c0dd05 100755 --- a/tools/nut-usbinfo.pl +++ b/tools/nut-usbinfo.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Current Version : 1.3 # Copyright (C) 2008 - 2012 dloic (loic.dardant AT gmail DOT com) -# Copyright (C) 2008 - 2014 Arnaud Quette +# Copyright (C) 2008 - 2015 Arnaud Quette # Copyright (C) 2013 - 2014 Charles Lepple # # Based on the usbdevice.pl script, made for the Ubuntu Media Center @@ -111,9 +111,12 @@ sub gen_usb_files open my $outputUPower, ">$outputUPower" || die "error $outputUPower : $!"; print $outputUPower '##############################################################################################################'."\n"; print $outputUPower '# Uninterruptible Power Supplies with USB HID interfaces'."\n#\n"; - print $outputUPower '# to keep up to date, monitor https://github.com/networkupstools/nut/commits/master/scripts/upower/95-upower-hid.rules'."\n\n"; + print $outputUPower '# This file was automatically generated by NUT:'."\n#".' https://github.com/networkupstools/nut/'."\n#\n"; + print $outputUPower '# To keep up to date, monitor upstream NUT'."\n#".' https://github.com/networkupstools/nut/commits/master/scripts/upower/95-upower-hid.rules'."\n"; + print $outputUPower "# or checkout the NUT repository and call 'tools/nut-usbinfo.pl'\n\n"; + print $outputUPower '# newer hiddev are part of the usbmisc class'."\n".'SUBSYSTEM=="usbmisc", GOTO="up_hid_chkdev"'."\n"; print $outputUPower '# only support USB, else ignore'."\n".'SUBSYSTEM!="usb", GOTO="up_hid_end"'."\n\n"; - print $outputUPower '# if usbraw device, ignore'."\n".'KERNEL!="hiddev*", GOTO="up_hid_end"'."\n\n"; + print $outputUPower '# if usbraw device, ignore'."\n".'LABEL="up_hid_chkdev"'."\n".'KERNEL!="hiddev*", GOTO="up_hid_end"'."\n\n"; print $outputUPower '# if an interface, ignore'."\n".'ENV{DEVTYPE}=="usb_interface", GOTO="up_hid_end"'."\n\n"; # Device scanner header