~ubuntu-branches/ubuntu/saucy/nut/saucy

« back to all changes in this revision

Viewing changes to drivers/bcmxcp.c

  • Committer: Chuck Short
  • Date: 2013-05-13 12:57:25 UTC
  • Revision ID: zulcss@ubuntu.com-20130513125725-llq8wsohyhq9idsy
* Merge from Debian.  Remaining changes:
  - debian/control:
    + remove Build-Depends on libpowerman0-dev
    + remove nut-powerman-pdu
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut
    groups unconditonally to handle the upgrade from hardy release.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install,
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled
* Non-maintainer upload with fixes for wheezy.
* debian/nut-client.preinst: also revert /etc/nut/nut.conf mangling done
  by postinst during upgrade from lenny to squeeze (Really closes: #677054)
  Thanks to Andreas Beckmann for the review.
* Merge from Debian.  Remaining changes:
  - debian/control:
    + remove Build-Depends on libpowerman0-dev
    + remove nut-powerman-pdu
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut
    groups unconditonally to handle the upgrade from hardy release.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install,
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled
* Dropped the following patches, no longer required:
  - debian/patches/CVE-2012-2944.patch (included upstream)
* Non-maintainer upload with fixes for wheezy.
* Only remove /etc/init.d/nut from previous versions of nut in nut-server
  postinst if there are no local changes.
* Also remove /etc/init.d/nut in nut-client postinst. Thanks to 
  Laurent Bigonville for the hint.
* Only fix permissions of configfiles on first install.
* debian/control: Fix typo in package description. Thanks to Julien Cristau
  for spotting this.
* Non-maintainer upload.
* debian/nut-client.preinst: revert /etc/nut/nut.conf mangling done by older
  versions of the postinst (Closes: #677054)
* debian/rules: Stop the nut-client before nut-server on systems using
  static
  boot ordering (Closes: #679451)
* debian/nut-server.postinst: Remove /etc/init.d/nut on upgrade
  (Closes: #677822)
* Rename nut-server.lintian-overrides to nut-client.lintian-overrides and
  adjust overrides now that ups-monitor is shipped in nut-client package
  (Closes: #677947)
* Add debian/patches/0001-fix-upsmon-regression.patch: Fix upsmon/upssched
  regression (Taken from upstream) (Closes: #679513)
* Move nut metapackage to Section: metapackages
* Also create nut user when installing nut-client package and do not delete
  it on purge anymore (Closes: #682000)
* Drop /etc/default/nut → /etc/nut/nut.conf migration code, migration
  happends before squeeze release and this was against policy to have a
  maintainer script modifying a conffile in the first place (Closes: #684392)
* Add dependency against adduser and lsb-base on nut-client package
* Be sure that client is stopped before the server also when using
  dependencies based boot
* Fix package descriptions (Closes: #678068)
* Also install /bin/upssched-cmd in nut-client package as this script is
  referenced in default upssched.conf config file
* debian/watch: Update watch file
* Be sure that all maintainer scripts are returning 0 at their end
* New upstream release (Closes: #671444)
* acknowledges NMU (Closes: #613643)
* debian/nut-client.init: fix action "start" and use of log_*_*msg
  LSB log functions (Closes: #675619)
* debian/nut-server.preinst: remove obsolete file(s) left in
  /etc/udev/rules.d and related processing: udev files are now located
  in /lib/udev/rules, and there is no reason to modify the dedicated
  USB UPS rules (52-nut-usbups.rules) (Closes: #660072)
* debian/nut-server.init: rewrite to match upsd / drivers startup scope
* debian/nut-client.init: created to match upsmon startup scope
  (Closes: #634858)
* debian/nut.TODO.Debian, debian/Makefile.am: updated to reflect the above
* debian/rules: install nut-client.init, and update to reflect the above
* debian/control, debian/Makefile.am: updated to reflect the above
* debian/control:
  - add Breaks on nut-server (<< 2.6.3-1~)
  - bump Standards-Version to 3.9.3
* debian/nut-client.links: renamed from debian/nut-server.links, since
  ups-monitor is now provided by nut-client initscript
* debian/nut.README.Debian: renamed from nut-server.README.Debian,
  to provide it with both client and server packages
* debian/nut-server.install: add missing drivers (clone-outlet,
  liebert-esp2 and microdowell)
* debian/nut-server.manpages: add missing manual pages (apcsmart-old,
  ivtscd, liebert-esp2 and microdowell)
* SECURITY UPDATE: remote denial of service
 - debian/CVE-2012-2944.patch: limit the set of parsed characters to ' '
   through '~'
 - CVE-2012-2944
* Merge from Debian testing.  Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* New upstream release (Closes: #635186, #598741, #633756, #638221)
* debian/nut-server.{install,manpages}: add richcomm_usb
* debian/nut-server.install, debian/rules: install Avahi service file
* debian/rules, nut-client.install: install Augeas lenses
* debian/nut-server.README.Debian: clarify udev explanation (Closes: #529664)
* debian/patches/0001-fix_spelling_and_typo.patch,
  debian/patches/0003-libupsclient-version.patch: removed since these are now
  fixed upstream
* debian/patches/series: updated
* Merge from debian unstable.  Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* New upstream release (Closes: #594989)
* debian/control:
  - remove legacy Build-Depends for nut-hal-drivers on libdbus and libglib
  - Build-Depends-Indep on docbook-xsl for offline document
    generation (Closes: #635347)
* debian/nut-server.install: add apcsmart-old
* debian/nut-server.init:
  - add udev as Required-Start/Stop (Closes: #642412)
  - remove legacy support for /etc/default/nut (Closes: #638021)
* debian/patches/0003-libupsclient-version.patch: added to fix the missing
  libupsclient version info bump
* debian/libupsclient1-dev.links: update link name
* debian/libupsclient1.symbols: add with upscli_tryconnect
* debian/nut.TODO.Debian: update and complete the TODO list
* Fix FTBFS for Ubuntu (LP: #815760):
  - debian/control: Build-Depends-Indep on docbook-xsl for offline 
    document generation.
* Merge from Debian unstable (LP: #811976). Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* debian/nut.README.Debian: Adjust udev rules naming for permissions override
  (Closes: #529664)
* Re-add and refresh debian/patches/0001-fix_spelling_and_typo.patch:
  Some typos and spelling errors remain.
* Split nut package into nut-client and nut-server, keep nut package as
  metapackage
* Generate PDF and html doc and install it in nut-doc package
* debian/rules:
  - List non-installed files
  - Includes python-module.mk
  - Add flags to build documentation and install it
* debian/control:
  - Add python-nut package and add python build-dependency
  - Set nut-powerman-pdu priority to extras
  - Add nut-monitor package
  - Add nut-doc package and add required C/R/P
  - Add libups-nut-perl package
* debian/nut-server.prerm: Remove /var/run/nut during removal
* Merge from debian unstable.  Remaining changes:
  - debian/control:
    + Drop Build-Depends on libpowerman0-dev (currently in universe)
  - debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  - debian/rules: Use udev version for Ubuntu.
* debian/patches/backport-fix-lp753661.patch: Refreshed.
* Drop changes due to .pc being not clean.
* New upstream release (Closes: #595953, #614842, #595773)
* debian/patches/*.patch: removed since these are now fixed upstream
* Drop HAL package and build-dependencies (Closes: #613197)
* debian/control:
  - Bump Standards-Version to 3.9.2 (no further changes)
  - Drop autotools build-dependencies (not needed anymore)
  - Drop non-existing build-dependencies
* debian/rules:
  - Correctly pass flags to configure
* Merge from debian unstable (LP: #789323).  Remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to handle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nul-hal-drivers.{docs,install,postinst,preinst}: Dropped since hal is in universe now
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + debian/patches/backport-fix-lp753661.patch
  + Dropped:
    - debian/patches/fix_pc_file.patch: replaced by debian's 0002-fix_libupsclient_pc.patch
* debian/patches/fix_pc_file.patch: add DEP3 patch header
* debian/patches/debian-changes-2.6.0-1: remove that accidental file
* debian/nut-snmp.docs: Distribute snmp.txt doc file (Closes: #548295)
* d/p/0001-fix_spelling_and_typo.patch: Update and refresh
* debian/nut.lintian-overrides: Fix typo
* debian/patch/0002-fix_libupsclient_pc.patch: Fix libupsclient.pc (Closes:
  #624255)
* debian/rules:
  - Switch to cdbs
  - Remove not existing configure options (Closes: #611813)
  - Drop Phony rules (Closes: #613699)
* debian/control:
  - Add cdbs build-dependency
* debian/patches/backport-fix-lp753661.patch: Backport fix 
  to trim extraneous end-of-line, in buggy HID string tables, 
  which results in upsc breaking the communication pipe.
  (LP: #753661)
* fix_pc_file.patch: fix .pc source files by using LIBSSL_LIBS instead of
  LIBSSL_LDFLAGS to avoid a FTBFS in packages that uses libupsclient.pc
  (LP: #743484)
* Merge from Debian unstable, remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nul-hal-drivers.{docs,install,postinst,preinst}: Dropped since hal is in universe now
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + Dropped:
    - debian/patches/0002-fix_udev_action.patch: Accepted upstream.
    - debian/patches/0004-netvision-improvements-lp-600950: no longer needed.
    - debian/patches/0005-fix-nut-m4.patch: no longer needed.
    - debian/patches/9999-autoconf.patch: no longer needed.
* New upstream release (Closes: #575176, #588648, #609597, #687985)
* debian/patches/*.patch: removed since these are now fixed upstream
* debian/patches/0001-fix_spelling_and_typo.patch,
  debian/patches/series: reworked to match the new upstream release
* debian/nut.install, debian/nut.manpages: remove obsolete reference to
  megatec and megatec_usb, now respectively replaced by blazer_ser and
  blazer_usb
* debian/nut.docs: limit distributed documentation
* debian/control:
  - Wrap build-dependencies
  - Change nut-cgi Recommends to apache2 | httpd-cgi
* debian/nut.postinst: Only trigger USB subsystem, should Closes: #574769
* debian/patches/0002-fix_udev_action.patch: Use SUBSYSTEM instead of BUS
* debian/control, debian/rules, 
  debian/nut-hal-drivers.{docs,install,postinst,preinst}: Drop
  nut-hal-drivers since Nut doesnt go into universe.
* Split patches/debian-changes-2.4.3-2ubuntu1 into
  patches/0005-fix-nut-m4.patch and patches/9999-autoconf.patch
* Readd lost debian/patches0004-netvision-improvements-lp-600950.patch patch
  (LP: #707050)
* debian/patches/0002-fix_udev_action.patch:
  Change BUS to SUBSYSTEMS, since the former is deprecated. (LP: #692171)
* debian/nut.postinst: Uncomment missing call to adduser
* debian/control: Drop hal build dependency, we don't need the daemon to
  build the package. Add a hal dependency to nut-hal-drivers, which is the
  only thing that actually needs it.
* Merge from debian unstable.  Remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/nut.postinst: Update udevadm trigger.
    "libusb_get_report: error sending control message: 
     Operation not permitted" error on some UPS devices. (LP: #572262)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + debian/patches/netvision-improvements-lp-600950.patch: Add improvements
    for netvision UPSes
  + Fix FTBFS with ld --as-needed.
  + Dropped:
    - debian/patches/03_udev_rules_change.dpatch: Use debian's instead.
    - debian/patches/04_nut_small-buffers.dpatch: Use debian's instead.
* debian/control:
  - Bump Standards-Version to 3.9.1
  - Update Vcs-* fields to new GIT repository
  - Add myself as Uploaders
* Switch to dpkg-source 3.0 (quilt) format (Closes: #573601)
* debian/patches/0001-low_speed_usb_ups.patch: Use patch system for changes
  that were applied directly in the source
* Add debian/gbp.conf file
* debian/watch: Bump version to 3
* Add debian/patches/0002-fix_udev_action.patch: Also set permission for
  "change" udev ACTION (Closes: #557178)
* debian/nut.postrm: Do not try to remove nut user is deluser is not
  installed anymore
* debian/nut.manpages: Install manpage nut.conf.5 (Closes: #528222)
* debian/copyright: Fix copyright-with-old-dh-make-debian-copyright
* Remove nut-snmp.lintian-overrides, not needed anymore
* debian/patches/0003-fix_spelling_and_typo.patch: Fix some spelling errors
* Add debian/libupsclient1.symbols file
* Add debian/nut.links: Re-add /etc/init.d/ups-monitor that was lost for
  some reasons (Closes: #592351)
* debian/nut.lintian-overrides: Add override for
  init.d-script-does-not-provide-itself /etc/init.d/ups-monitor
* Drop libupsclient1.post{inst,rm}: ldconfig call is added automatically by
  debhelper
* debian/libupsclient1-dev.install: Do not ship /lib/libupsclient.la anymore
* debian/rules: Remove dpatch logic as we are using package source version
  '3.0 (quilt)'
* debian/compat: Bump debhelper compatibility to 8
* Non-maintainer upload.
* drivers/libhid.c: Apply r2407 from upstream to fix bug with some
  low speed UPS devices. (Closes: #583371)
* Fix FTBFS with ld --as-needed.
* debian/patches/netvision-improvements-lp-600950.patch: Add improvements for netvision UPSes 
  (LP: #600950) 
* debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook. 
* debian/patches/04_nut-small-buffers.dpatch: Fix "libusb_get_report: error sending control message: 
  Operation not permitted" error on some UPS devices. (LP: #572262)
* debian/nut.postinst: Revert dropping of --action=change. "add" events must
  not ever be triggered automatically.
* Add 03_udev_rules_change.dpatch: Run udev rules on change events, too.
* debian/control: grr...fix ftbfs. 
* Merge from debian testing.  Remaining changes (LP: #535152):
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/nut.postinst: Update udevadm trigger.
  + Dropped:
    - debian/patches/02-fix-trust-pw4130m.dpatch: No longer needed.
* New upstream release (Closes: #544390, #528222, #539747, #526811,
  #562064)
* debian/nut.install, debian/nut.manpages:
  - remove cyberpower driver and manpage
  - add bestfortress, clone and ivtscd drivers and manpages
* debian/rules:
  - change udev dir to /lib/udev (Closes: #522327)
  - replace deprecated calls to 'dh_clean -k' by dh_prep (Closes: #536599)
* debian/rules, debian/nut.install, debian/nut.install,
  debian/nut.README.Debian: install configuration files, without the
  sample suffix (Closes: #528641)
* debian/nut.links: restored (Closes: #522506)
* debian/nut.init:
  - source nut.conf instead of default/nut for POWEROFF_WAIT(Closes:
    #538173)
  - fix status checking (Closes: #538785)
  - improve detection of non configured system and beautify related
    output (Closes: #563112)
  - use 'invoke-rc.d' instead of calling the reboot script directly
  - add $remote_fs to Required-Start and Required-Stop
* debian/nut.postrm: remove udev files and simplify cleanup (Closes:
  #541629)
* debian/control:
  - remove Luca Filipozzi from the Uploaders list (Closes: #568987)
  - update Standards-Version to 3.8.4
  - remove the debconf dependency
  - bump debhelper version to (>= 7) in Build-Depends, for dh_prep
  - add Breaks on nut-hal-drivers to ensure we have correct udev version
* Remove debconf support since it was related to really old nut
  version (Closes: #518056):
  - remove nut-cgi.config, nut.config, nut-cgi.templates, nut.templates,
    and po/ directory
  - update nut-cgi.postinst
* debian/nut.dirs: remove /var/run/nut to conform to Debian Policy
* debian/nut.postint:
  - create /var/run/nut if needed
  - improve security checks
* debian/nut.README.Debian: add a security note for ups.conf
* debian/watch: URL update
* debian/patches/02-fix-trust-pw4130m.dpatch: Fix issues with Trust
  PW-4130M UPS. (LP: #447586) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 * emes -at- geomer.de *
7
7
 * All rights reserved.*
8
8
 
9
 
 Copyright (C) 2004 Kjell Claesson <kjell.claesson-at-epost.tidanet.se>
10
 
 and Tore Ørpetveit <tore-at-orpetveit.net>
 
9
 Copyright (C)
 
10
   2004 Kjell Claesson <kjell.claesson-at-epost.tidanet.se>
 
11
   2004 Tore Ørpetveit <tore-at-orpetveit.net>
 
12
   2011 - 2012 Arnaud Quette <ArnaudQuette@Eaton.com>
11
13
 
12
14
 Thanks to Tore Ørpetveit <tore-at-orpetveit.net> that sent me the
13
15
 manuals for bcm/xcp.
16
18
 It influenced the layout of this driver.
17
19
 
18
20
 Modified for USB by Wolfgang Ocker <weo@weo1.de>
19
 
 
 
21
 
20
22
 ojw0000 2007Apr5 Oliver Wilcock - modified to control individual load segments (outlet.2.shutdown.return) on Powerware PW5125.
21
 
 
 
23
 
 
24
 Modified to support setvar for outlet.n.delay.start by Rich Wrenn (RFW) 9-3-11.
 
25
 Modified to support setvar for outlet.n.delay.shutdown by Arnaud Quette, 9-12-11 
 
26
 
22
27
This program is free software; you can redistribute it and/or modify
23
28
 it under the terms of the GNU General Public License as published by
24
29
 the Free Software Foundation; either version 2 of the License, or
41
46
                Give information if config block is
42
47
                present, and how long it is, if it exist.
43
48
                If config block exist, read the config block and setup
44
 
                the possible config commands, and parse the 
 
49
                the possible config commands, and parse the
45
50
                'Length of the Extended Limits Configuration Block' for
46
 
                extended configuration commands 
 
51
                extended configuration commands
47
52
 
48
53
                Statistic map Size: (Low priority)
49
54
                May be used to se if there is a Statistic Map.
93
98
                        2 = Waiting to communicate with a UPS
94
99
                        3 = Communication established with a UPS
95
100
                        4 = Waiting to communicate with software or adapter
96
 
                        5 = Communication established software (e.g., LanSafe) 
 
101
                        5 = Communication established software (e.g., LanSafe)
97
102
                                or adapter (e.g., ConnectUPS)
98
103
                        6 = Communicating with a Display Device
99
104
                        7 = Multi-drop Serial channel
105
110
                settings or turn the outlet on or off with a delay (0 - 32767 seconds)
106
111
 
107
112
 
108
 
        Rewrite some parts of the driver, to minimise code duplication. (Like the inst commands) 
109
 
 
 
113
        Rewrite some parts of the driver, to minimise code duplication. (Like the instant commands)
 
114
 
 
115
        Implement support for Password Authorization (XCP spec, §4.3.2)
 
116
 
 
117
        Complete support for settable variables (upsh.setvar)
110
118
*/
111
119
 
112
120
 
113
121
#include "main.h"
114
 
 
115
122
#include <math.h>               /* For ldexp() */
116
123
#include <float.h>              /*for FLT_MAX */
 
124
#include "nut_stdint.h" /* for uint8_t, uint16_t, uint32_t, ... */
117
125
#include "bcmxcp_io.h"
118
126
#include "bcmxcp.h"
119
127
 
120
128
#define DRIVER_NAME     "BCMXCP UPS driver"
121
 
#define DRIVER_VERSION  "0.21"
 
129
#define DRIVER_VERSION  "0.26"
 
130
 
 
131
#define MAX_NUT_NAME_LENGTH             128
 
132
#define NUT_OUTLET_POSITION             7
122
133
 
123
134
/* driver description structure */
124
135
upsdrv_info_t upsdrv_info = {
138
149
static float get_float(const unsigned char *data);
139
150
static void init_meter_map(void);
140
151
static void init_alarm_map(void);
 
152
static void init_command_map(void);
141
153
static void init_config(void);
142
154
static void init_limit(void);
143
155
static void init_ups_meter_map(const unsigned char *map, unsigned char len);
145
157
static void decode_meter_map_entry(const unsigned char *entry, const unsigned char format, char* value);
146
158
static int init_outlet(unsigned char len);
147
159
static int instcmd(const char *cmdname, const char *extra);
148
 
 
149
 
 
150
 
char *FreqTol[3] = {"+/-2%", "+/-5%", "+/-7"};
151
 
char *ABMStatus[4] = {"Charging", "Discharging", "Floating", "Resting"};
152
 
unsigned char AUTHOR[4] = {0xCF, 0x69, 0xE8, 0xD5};             /* Autorisation command */
 
160
static int setvar (const char *varname, const char *val);
 
161
 
 
162
static const char *nut_find_infoval(info_lkp_t *xcp2info, const double value);
 
163
 
 
164
const char *FreqTol[3] = {"+/-2%", "+/-5%", "+/-7"};
 
165
const char *ABMStatus[4] = {"Charging", "Discharging", "Floating", "Resting"};
 
166
/* Standard Authorization Block */
 
167
unsigned char AUTHOR[4] = {0xCF, 0x69, 0xE8, 0xD5};
153
168
int nphases = 0;
154
169
int outlet_block_len = 0;
155
 
char *cpu_name[5] = {"Cont:", "Inve:", "Rect:", "Netw:", "Disp:"};
156
 
 
157
 
/* get_word funktion from nut driver metasys.c */
 
170
const char *cpu_name[5] = {"Cont:", "Inve:", "Rect:", "Netw:", "Disp:"};
 
171
 
 
172
 
 
173
 
 
174
/* Battery test results */
 
175
info_lkp_t batt_test_info[] = {
 
176
        { 0, "No test initiated", NULL },
 
177
        { 1, "In progress", NULL },
 
178
        { 2, "Done and passed", NULL },
 
179
        { 3, "Aborted", NULL },
 
180
        { 4, "Done and error", NULL },
 
181
        { 5, "Test scheduled", NULL },
 
182
        /* Not sure about the meaning of the below ones! */
 
183
        { 6, NULL, NULL }, /* The string was present but it has now been removed */
 
184
        { 7, NULL, NULL }, /* The string was not installed at the last power up */
 
185
        { 0, NULL, NULL }
 
186
};
 
187
 
 
188
 
 
189
/* allocate storage for shared variables (extern in bcmxcp.h) */
 
190
BCMXCP_METER_MAP_ENTRY_t
 
191
        bcmxcp_meter_map[BCMXCP_METER_MAP_MAX];
 
192
BCMXCP_ALARM_MAP_ENTRY_t
 
193
        bcmxcp_alarm_map[BCMXCP_ALARM_MAP_MAX];
 
194
BCMXCP_STATUS_t
 
195
        bcmxcp_status;
 
196
 
 
197
 
 
198
/* get_word function from nut driver metasys.c */
158
199
int get_word(const unsigned char *buffer)       /* return an integer reading a word in the supplied buffer */
159
200
{
160
201
        unsigned char a, b;
198
239
        e = (src & 0x7F800000UL) >> 23;
199
240
        f = (src & 0x007FFFFFUL);
200
241
 
201
 
        if (e == 255 && f != 0) 
 
242
        if (e == 255 && f != 0)
202
243
        {
203
244
                /* NaN (Not a Number) */
204
245
                return FLT_MAX;
205
246
        }
206
 
        
 
247
 
207
248
        if (e == 255 && f == 0 && s == 1)
208
249
        {
209
250
                /* Negative infinity */
210
251
                return -FLT_MAX;
211
252
        }
212
 
         
 
253
 
213
254
        if (e == 255 && f == 0 && s == 0)
214
255
        {
215
256
                /* Positive infinity */
216
257
                return FLT_MAX;
217
258
        }
218
 
        
 
259
 
219
260
        if (e > 0 && e < 255)
220
261
        {
221
262
                /* Normal number */
230
271
                if (s) f = -f;
231
272
                return ldexp(f, -149);
232
273
        }
233
 
         
 
274
 
234
275
        if (e == 0 && f == 0 && (s == 1 || s == 0))
235
276
        {
236
277
                /* Zero */
242
283
        return 0;
243
284
}
244
285
 
245
 
 
 
286
/* lightweight function to calculate the 8-bit
 
287
 * two's complement checksum of buf, using XCP data length (including header)
 
288
 * the result must be 0 for the sequence data to be valid */
246
289
int checksum_test(const unsigned char *buf)
247
290
{
248
 
        unsigned char c;
249
 
        int i;
250
 
 
251
 
        c = 0;
252
 
        for(i = 0; i < 5 + buf[2]; i++)
253
 
                c += buf[i];
254
 
 
255
 
        return c == 0;
 
291
        unsigned char checksum = 0;
 
292
        int i, length;
 
293
 
 
294
        /* buf[2] is the length of the XCP frame ; add 5 for the header */
 
295
        length = (int)(buf[2]) + 5;
 
296
 
 
297
        for (i = 0; i < length; i++) {
 
298
                checksum += buf[i];
 
299
        }
 
300
        /* Compute the 8-bit, Two's Complement checksum now and return it */
 
301
        checksum = ((0x100 - checksum) & 0xFF);
 
302
        return (checksum == 0);
256
303
}
257
304
 
258
 
 
259
305
unsigned char calc_checksum(const unsigned char *buf)
260
306
{
261
307
        unsigned char c;
326
372
{
327
373
        /* Clean entire map */
328
374
        memset(&bcmxcp_alarm_map, 0, sizeof(BCMXCP_ALARM_MAP_ENTRY_t) * BCMXCP_ALARM_MAP_MAX);
329
 
        
 
375
 
330
376
        /* Set all alarm descriptions   */
331
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_AC_OVER_VOLTAGE].alarm_desc = "INVERTER_AC_OVER_VOLTAGE"; 
 
377
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_AC_OVER_VOLTAGE].alarm_desc = "INVERTER_AC_OVER_VOLTAGE";
332
378
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_AC_UNDER_VOLTAGE].alarm_desc = "INVERTER_AC_UNDER_VOLTAGE";
333
379
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OVER_OR_UNDER_FREQ].alarm_desc = "INVERTER_OVER_OR_UNDER_FREQ";
334
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_AC_OVER_VOLTAGE].alarm_desc = "BYPASS_AC_OVER_VOLTAGE"; 
 
380
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_AC_OVER_VOLTAGE].alarm_desc = "BYPASS_AC_OVER_VOLTAGE";
335
381
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_AC_UNDER_VOLTAGE].alarm_desc = "BYPASS_AC_UNDER_VOLTAGE";
336
382
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_OVER_OR_UNDER_FREQ].alarm_desc = "BYPASS_OVER_OR_UNDER_FREQ";
337
383
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_AC_OVER_VOLTAGE].alarm_desc = "INPUT_AC_OVER_VOLTAGE";
338
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_AC_UNDER_VOLTAGE].alarm_desc = "INPUT_AC_UNDER_VOLTAGE"; 
339
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_UNDER_OR_OVER_FREQ].alarm_desc = "INPUT_UNDER_OR_OVER_FREQ"; 
 
384
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_AC_UNDER_VOLTAGE].alarm_desc = "INPUT_AC_UNDER_VOLTAGE";
 
385
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_UNDER_OR_OVER_FREQ].alarm_desc = "INPUT_UNDER_OR_OVER_FREQ";
340
386
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_OVER_VOLTAGE].alarm_desc = "OUTPUT_OVER_VOLTAGE";
341
 
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_UNDER_VOLTAGE].alarm_desc = "OUTPUT_UNDER_VOLTAGE"; 
 
387
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_UNDER_VOLTAGE].alarm_desc = "OUTPUT_UNDER_VOLTAGE";
342
388
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_UNDER_OR_OVER_FREQ].alarm_desc = "OUTPUT_UNDER_OR_OVER_FREQ";
343
 
        bcmxcp_alarm_map[BCMXCP_ALARM_REMOTE_EMERGENCY_PWR_OFF].alarm_desc = "REMOTE_EMERGENCY_PWR_OFF"; 
 
389
        bcmxcp_alarm_map[BCMXCP_ALARM_REMOTE_EMERGENCY_PWR_OFF].alarm_desc = "REMOTE_EMERGENCY_PWR_OFF";
344
390
        bcmxcp_alarm_map[BCMXCP_ALARM_REMOTE_GO_TO_BYPASS].alarm_desc = "REMOTE_GO_TO_BYPASS";
345
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_6].alarm_desc = "BUILDING_ALARM_6"; 
346
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_5].alarm_desc = "BUILDING_ALARM_5"; 
347
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_4].alarm_desc = "BUILDING_ALARM_4"; 
348
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_3].alarm_desc = "BUILDING_ALARM_3"; 
349
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_2].alarm_desc = "BUILDING_ALARM_2"; 
350
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_1].alarm_desc = "BUILDING_ALARM_1"; 
 
391
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_6].alarm_desc = "BUILDING_ALARM_6";
 
392
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_5].alarm_desc = "BUILDING_ALARM_5";
 
393
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_4].alarm_desc = "BUILDING_ALARM_4";
 
394
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_3].alarm_desc = "BUILDING_ALARM_3";
 
395
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_2].alarm_desc = "BUILDING_ALARM_2";
 
396
        bcmxcp_alarm_map[BCMXCP_ALARM_BUILDING_ALARM_1].alarm_desc = "BUILDING_ALARM_1";
351
397
        bcmxcp_alarm_map[BCMXCP_ALARM_STATIC_SWITCH_OVER_TEMP].alarm_desc = "STATIC_SWITCH_OVER_TEMP";
352
398
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_OVER_TEMP].alarm_desc = "CHARGER_OVER_TEMP";
353
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_LOGIC_PWR_FAIL].alarm_desc = "CHARGER_LOGIC_PWR_FAIL"; 
 
399
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_LOGIC_PWR_FAIL].alarm_desc = "CHARGER_LOGIC_PWR_FAIL";
354
400
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_OVER_VOLTAGE_OR_CURRENT].alarm_desc = "CHARGER_OVER_VOLTAGE_OR_CURRENT";
355
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OVER_TEMP].alarm_desc = "INVERTER_OVER_TEMP"; 
 
401
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OVER_TEMP].alarm_desc = "INVERTER_OVER_TEMP";
356
402
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_OVERLOAD].alarm_desc = "OUTPUT_OVERLOAD";
357
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_INPUT_OVER_CURRENT].alarm_desc = "RECTIFIER_INPUT_OVER_CURRENT"; 
358
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OUTPUT_OVER_CURRENT].alarm_desc = "INVERTER_OUTPUT_OVER_CURRENT"; 
359
 
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_LINK_OVER_VOLTAGE].alarm_desc = "DC_LINK_OVER_VOLTAGE"; 
 
403
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_INPUT_OVER_CURRENT].alarm_desc = "RECTIFIER_INPUT_OVER_CURRENT";
 
404
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OUTPUT_OVER_CURRENT].alarm_desc = "INVERTER_OUTPUT_OVER_CURRENT";
 
405
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_LINK_OVER_VOLTAGE].alarm_desc = "DC_LINK_OVER_VOLTAGE";
360
406
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_LINK_UNDER_VOLTAGE].alarm_desc = "DC_LINK_UNDER_VOLTAGE";
361
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_FAILED].alarm_desc = "RECTIFIER_FAILED"; 
362
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_FAULT].alarm_desc = "INVERTER_FAULT"; 
363
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CONNECTOR_FAIL].alarm_desc = "BATTERY_CONNECTOR_FAIL"; 
 
407
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_FAILED].alarm_desc = "RECTIFIER_FAILED";
 
408
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_FAULT].alarm_desc = "INVERTER_FAULT";
 
409
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CONNECTOR_FAIL].alarm_desc = "BATTERY_CONNECTOR_FAIL";
364
410
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_BREAKER_FAIL].alarm_desc = "BYPASS_BREAKER_FAIL";
365
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_FAIL].alarm_desc = "CHARGER_FAIL"; 
366
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RAMP_UP_FAILED].alarm_desc = "RAMP_UP_FAILED"; 
367
 
        bcmxcp_alarm_map[BCMXCP_ALARM_STATIC_SWITCH_FAILED].alarm_desc = "STATIC_SWITCH_FAILED"; 
368
 
        bcmxcp_alarm_map[BCMXCP_ALARM_ANALOG_AD_REF_FAIL].alarm_desc = "ANALOG_AD_REF_FAIL"; 
 
411
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_FAIL].alarm_desc = "CHARGER_FAIL";
 
412
        bcmxcp_alarm_map[BCMXCP_ALARM_RAMP_UP_FAILED].alarm_desc = "RAMP_UP_FAILED";
 
413
        bcmxcp_alarm_map[BCMXCP_ALARM_STATIC_SWITCH_FAILED].alarm_desc = "STATIC_SWITCH_FAILED";
 
414
        bcmxcp_alarm_map[BCMXCP_ALARM_ANALOG_AD_REF_FAIL].alarm_desc = "ANALOG_AD_REF_FAIL";
369
415
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_UNCALIBRATED].alarm_desc = "BYPASS_UNCALIBRATED";
370
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_UNCALIBRATED].alarm_desc = "RECTIFIER_UNCALIBRATED"; 
 
416
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_UNCALIBRATED].alarm_desc = "RECTIFIER_UNCALIBRATED";
371
417
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_UNCALIBRATED].alarm_desc = "OUTPUT_UNCALIBRATED";
372
418
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_UNCALIBRATED].alarm_desc = "INVERTER_UNCALIBRATED";
373
 
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_VOLT_UNCALIBRATED].alarm_desc = "DC_VOLT_UNCALIBRATED"; 
 
419
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_VOLT_UNCALIBRATED].alarm_desc = "DC_VOLT_UNCALIBRATED";
374
420
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_CURRENT_UNCALIBRATED].alarm_desc = "OUTPUT_CURRENT_UNCALIBRATED";
375
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_CURRENT_UNCALIBRATED].alarm_desc = "RECTIFIER_CURRENT_UNCALIBRATED"; 
376
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CURRENT_UNCALIBRATED].alarm_desc = "BATTERY_CURRENT_UNCALIBRATED"; 
 
421
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_CURRENT_UNCALIBRATED].alarm_desc = "RECTIFIER_CURRENT_UNCALIBRATED";
 
422
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CURRENT_UNCALIBRATED].alarm_desc = "BATTERY_CURRENT_UNCALIBRATED";
377
423
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_ON_OFF_STAT_FAIL].alarm_desc = "INVERTER_ON_OFF_STAT_FAIL";
378
424
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CURRENT_LIMIT].alarm_desc = "BATTERY_CURRENT_LIMIT";
379
425
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_STARTUP_FAIL].alarm_desc = "INVERTER_STARTUP_FAIL";
380
426
        bcmxcp_alarm_map[BCMXCP_ALARM_ANALOG_BOARD_AD_STAT_FAIL].alarm_desc = "ANALOG_BOARD_AD_STAT_FAIL";
381
427
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_CURRENT_OVER_100].alarm_desc = "OUTPUT_CURRENT_OVER_100";
382
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_GROUND_FAULT].alarm_desc = "BATTERY_GROUND_FAULT"; 
383
 
        bcmxcp_alarm_map[BCMXCP_ALARM_WAITING_FOR_CHARGER_SYNC].alarm_desc = "WAITING_FOR_CHARGER_SYNC"; 
 
428
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_GROUND_FAULT].alarm_desc = "BATTERY_GROUND_FAULT";
 
429
        bcmxcp_alarm_map[BCMXCP_ALARM_WAITING_FOR_CHARGER_SYNC].alarm_desc = "WAITING_FOR_CHARGER_SYNC";
384
430
        bcmxcp_alarm_map[BCMXCP_ALARM_NV_RAM_FAIL].alarm_desc = "NV_RAM_FAIL";
385
431
        bcmxcp_alarm_map[BCMXCP_ALARM_ANALOG_BOARD_AD_TIMEOUT].alarm_desc = "ANALOG_BOARD_AD_TIMEOUT";
386
432
        bcmxcp_alarm_map[BCMXCP_ALARM_SHUTDOWN_IMMINENT].alarm_desc = "SHUTDOWN_IMMINENT";
387
433
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_LOW].alarm_desc = "BATTERY_LOW";
388
 
        bcmxcp_alarm_map[BCMXCP_ALARM_UTILITY_FAIL].alarm_desc = "UTILITY_FAIL"; 
389
 
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_SHORT_CIRCUIT].alarm_desc = "OUTPUT_SHORT_CIRCUIT"; 
 
434
        bcmxcp_alarm_map[BCMXCP_ALARM_UTILITY_FAIL].alarm_desc = "UTILITY_FAIL";
 
435
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_SHORT_CIRCUIT].alarm_desc = "OUTPUT_SHORT_CIRCUIT";
390
436
        bcmxcp_alarm_map[BCMXCP_ALARM_UTILITY_NOT_PRESENT].alarm_desc = "UTILITY_NOT_PRESENT";
391
 
        bcmxcp_alarm_map[BCMXCP_ALARM_FULL_TIME_CHARGING].alarm_desc = "FULL_TIME_CHARGING"; 
 
437
        bcmxcp_alarm_map[BCMXCP_ALARM_FULL_TIME_CHARGING].alarm_desc = "FULL_TIME_CHARGING";
392
438
        bcmxcp_alarm_map[BCMXCP_ALARM_FAST_BYPASS_COMMAND].alarm_desc = "FAST_BYPASS_COMMAND";
393
 
        bcmxcp_alarm_map[BCMXCP_ALARM_AD_ERROR].alarm_desc = "AD_ERROR"; 
 
439
        bcmxcp_alarm_map[BCMXCP_ALARM_AD_ERROR].alarm_desc = "AD_ERROR";
394
440
        bcmxcp_alarm_map[BCMXCP_ALARM_INTERNAL_COM_FAIL].alarm_desc = "INTERNAL_COM_FAIL";
395
441
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_SELFTEST_FAIL].alarm_desc = "RECTIFIER_SELFTEST_FAIL";
396
442
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_EEPROM_FAIL].alarm_desc = "RECTIFIER_EEPROM_FAIL";
397
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_EPROM_FAIL].alarm_desc = "RECTIFIER_EPROM_FAIL"; 
 
443
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_EPROM_FAIL].alarm_desc = "RECTIFIER_EPROM_FAIL";
398
444
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_LINE_VOLTAGE_LOSS].alarm_desc = "INPUT_LINE_VOLTAGE_LOSS";
399
445
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_DC_OVER_VOLTAGE].alarm_desc = "BATTERY_DC_OVER_VOLTAGE";
400
 
        bcmxcp_alarm_map[BCMXCP_ALARM_POWER_SUPPLY_OVER_TEMP].alarm_desc = "POWER_SUPPLY_OVER_TEMP"; 
 
446
        bcmxcp_alarm_map[BCMXCP_ALARM_POWER_SUPPLY_OVER_TEMP].alarm_desc = "POWER_SUPPLY_OVER_TEMP";
401
447
        bcmxcp_alarm_map[BCMXCP_ALARM_POWER_SUPPLY_FAIL].alarm_desc = "POWER_SUPPLY_FAIL";
402
 
        bcmxcp_alarm_map[BCMXCP_ALARM_POWER_SUPPLY_5V_FAIL].alarm_desc = "POWER_SUPPLY_5V_FAIL"; 
 
448
        bcmxcp_alarm_map[BCMXCP_ALARM_POWER_SUPPLY_5V_FAIL].alarm_desc = "POWER_SUPPLY_5V_FAIL";
403
449
        bcmxcp_alarm_map[BCMXCP_ALARM_POWER_SUPPLY_12V_FAIL].alarm_desc = "POWER_SUPPLY_12V_FAIL";
404
 
        bcmxcp_alarm_map[BCMXCP_ALARM_HEATSINK_OVER_TEMP].alarm_desc = "HEATSINK_OVER_TEMP"; 
 
450
        bcmxcp_alarm_map[BCMXCP_ALARM_HEATSINK_OVER_TEMP].alarm_desc = "HEATSINK_OVER_TEMP";
405
451
        bcmxcp_alarm_map[BCMXCP_ALARM_HEATSINK_TEMP_SENSOR_FAIL].alarm_desc = "HEATSINK_TEMP_SENSOR_FAIL";
406
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_CURRENT_OVER_125].alarm_desc = "RECTIFIER_CURRENT_OVER_125"; 
407
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_FAULT_INTERRUPT_FAIL].alarm_desc = "RECTIFIER_FAULT_INTERRUPT_FAIL"; 
408
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_POWER_CAPASITOR_FAIL].alarm_desc = "RECTIFIER_POWER_CAPASITOR_FAIL"; 
409
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_PROGRAM_STACK_ERROR].alarm_desc = "INVERTER_PROGRAM_STACK_ERROR"; 
410
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_BOARD_SELFTEST_FAIL].alarm_desc = "INVERTER_BOARD_SELFTEST_FAIL"; 
 
452
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_CURRENT_OVER_125].alarm_desc = "RECTIFIER_CURRENT_OVER_125";
 
453
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_FAULT_INTERRUPT_FAIL].alarm_desc = "RECTIFIER_FAULT_INTERRUPT_FAIL";
 
454
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_POWER_CAPASITOR_FAIL].alarm_desc = "RECTIFIER_POWER_CAPASITOR_FAIL";
 
455
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_PROGRAM_STACK_ERROR].alarm_desc = "INVERTER_PROGRAM_STACK_ERROR";
 
456
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_BOARD_SELFTEST_FAIL].alarm_desc = "INVERTER_BOARD_SELFTEST_FAIL";
411
457
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_AD_SELFTEST_FAIL].alarm_desc = "INVERTER_AD_SELFTEST_FAIL";
412
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_RAM_SELFTEST_FAIL].alarm_desc = "INVERTER_RAM_SELFTEST_FAIL"; 
 
458
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_RAM_SELFTEST_FAIL].alarm_desc = "INVERTER_RAM_SELFTEST_FAIL";
413
459
        bcmxcp_alarm_map[BCMXCP_ALARM_NV_MEMORY_CHECKSUM_FAIL].alarm_desc = "NV_MEMORY_CHECKSUM_FAIL";
414
460
        bcmxcp_alarm_map[BCMXCP_ALARM_PROGRAM_CHECKSUM_FAIL].alarm_desc = "PROGRAM_CHECKSUM_FAIL";
415
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_CPU_SELFTEST_FAIL].alarm_desc = "INVERTER_CPU_SELFTEST_FAIL"; 
416
 
        bcmxcp_alarm_map[BCMXCP_ALARM_NETWORK_NOT_RESPONDING].alarm_desc = "NETWORK_NOT_RESPONDING"; 
 
461
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_CPU_SELFTEST_FAIL].alarm_desc = "INVERTER_CPU_SELFTEST_FAIL";
 
462
        bcmxcp_alarm_map[BCMXCP_ALARM_NETWORK_NOT_RESPONDING].alarm_desc = "NETWORK_NOT_RESPONDING";
417
463
        bcmxcp_alarm_map[BCMXCP_ALARM_FRONT_PANEL_SELFTEST_FAIL].alarm_desc = "FRONT_PANEL_SELFTEST_FAIL";
418
 
        bcmxcp_alarm_map[BCMXCP_ALARM_NODE_EEPROM_VERIFICATION_ERROR].alarm_desc = "NODE_EEPROM_VERIFICATION_ERROR"; 
 
464
        bcmxcp_alarm_map[BCMXCP_ALARM_NODE_EEPROM_VERIFICATION_ERROR].alarm_desc = "NODE_EEPROM_VERIFICATION_ERROR";
419
465
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_AC_OVER_VOLT_TEST_FAIL].alarm_desc = "OUTPUT_AC_OVER_VOLT_TEST_FAIL";
420
 
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_DC_OVER_VOLTAGE].alarm_desc = "OUTPUT_DC_OVER_VOLTAGE"; 
421
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_PHASE_ROTATION_ERROR].alarm_desc = "INPUT_PHASE_ROTATION_ERROR"; 
422
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_RAMP_UP_TEST_FAILED].alarm_desc = "INVERTER_RAMP_UP_TEST_FAILED"; 
423
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OFF_COMMAND].alarm_desc = "INVERTER_OFF_COMMAND"; 
 
466
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_DC_OVER_VOLTAGE].alarm_desc = "OUTPUT_DC_OVER_VOLTAGE";
 
467
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_PHASE_ROTATION_ERROR].alarm_desc = "INPUT_PHASE_ROTATION_ERROR";
 
468
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_RAMP_UP_TEST_FAILED].alarm_desc = "INVERTER_RAMP_UP_TEST_FAILED";
 
469
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OFF_COMMAND].alarm_desc = "INVERTER_OFF_COMMAND";
424
470
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_ON_COMMAND].alarm_desc = "INVERTER_ON_COMMAND";
425
471
        bcmxcp_alarm_map[BCMXCP_ALARM_TO_BYPASS_COMMAND].alarm_desc = "TO_BYPASS_COMMAND";
426
472
        bcmxcp_alarm_map[BCMXCP_ALARM_FROM_BYPASS_COMMAND].alarm_desc = "FROM_BYPASS_COMMAND";
427
473
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTO_MODE_COMMAND].alarm_desc = "AUTO_MODE_COMMAND";
428
 
        bcmxcp_alarm_map[BCMXCP_ALARM_EMERGENCY_SHUTDOWN_COMMAND].alarm_desc = "EMERGENCY_SHUTDOWN_COMMAND"; 
 
474
        bcmxcp_alarm_map[BCMXCP_ALARM_EMERGENCY_SHUTDOWN_COMMAND].alarm_desc = "EMERGENCY_SHUTDOWN_COMMAND";
429
475
        bcmxcp_alarm_map[BCMXCP_ALARM_SETUP_SWITCH_OPEN].alarm_desc = "SETUP_SWITCH_OPEN";
430
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OVER_VOLT_INT].alarm_desc = "INVERTER_OVER_VOLT_INT"; 
 
476
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OVER_VOLT_INT].alarm_desc = "INVERTER_OVER_VOLT_INT";
431
477
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_UNDER_VOLT_INT].alarm_desc = "INVERTER_UNDER_VOLT_INT";
432
 
        bcmxcp_alarm_map[BCMXCP_ALARM_ABSOLUTE_DCOV_ACOV].alarm_desc = "ABSOLUTE_DCOV_ACOV"; 
 
478
        bcmxcp_alarm_map[BCMXCP_ALARM_ABSOLUTE_DCOV_ACOV].alarm_desc = "ABSOLUTE_DCOV_ACOV";
433
479
        bcmxcp_alarm_map[BCMXCP_ALARM_PHASE_A_CURRENT_LIMIT].alarm_desc = "PHASE_A_CURRENT_LIMIT";
434
480
        bcmxcp_alarm_map[BCMXCP_ALARM_PHASE_B_CURRENT_LIMIT].alarm_desc = "PHASE_B_CURRENT_LIMIT";
435
481
        bcmxcp_alarm_map[BCMXCP_ALARM_PHASE_C_CURRENT_LIMIT].alarm_desc = "PHASE_C_CURRENT_LIMIT";
436
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_NOT_AVAILABLE].alarm_desc = "BYPASS_NOT_AVAILABLE"; 
437
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_BREAKER_OPEN].alarm_desc = "RECTIFIER_BREAKER_OPEN"; 
438
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CONTACTOR_OPEN].alarm_desc = "BATTERY_CONTACTOR_OPEN"; 
 
482
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_NOT_AVAILABLE].alarm_desc = "BYPASS_NOT_AVAILABLE";
 
483
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_BREAKER_OPEN].alarm_desc = "RECTIFIER_BREAKER_OPEN";
 
484
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CONTACTOR_OPEN].alarm_desc = "BATTERY_CONTACTOR_OPEN";
439
485
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_CONTACTOR_OPEN].alarm_desc = "INVERTER_CONTACTOR_OPEN";
440
486
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_BREAKER_OPEN].alarm_desc = "BYPASS_BREAKER_OPEN";
441
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INV_BOARD_ACOV_INT_TEST_FAIL].alarm_desc = "INV_BOARD_ACOV_INT_TEST_FAIL"; 
 
487
        bcmxcp_alarm_map[BCMXCP_ALARM_INV_BOARD_ACOV_INT_TEST_FAIL].alarm_desc = "INV_BOARD_ACOV_INT_TEST_FAIL";
442
488
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OVER_TEMP_TRIP].alarm_desc = "INVERTER_OVER_TEMP_TRIP";
443
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INV_BOARD_ACUV_INT_TEST_FAIL].alarm_desc = "INV_BOARD_ACUV_INT_TEST_FAIL"; 
 
489
        bcmxcp_alarm_map[BCMXCP_ALARM_INV_BOARD_ACUV_INT_TEST_FAIL].alarm_desc = "INV_BOARD_ACUV_INT_TEST_FAIL";
444
490
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_VOLTAGE_FEEDBACK_ERROR].alarm_desc = "INVERTER_VOLTAGE_FEEDBACK_ERROR";
445
 
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_UNDER_VOLTAGE_TIMEOUT].alarm_desc = "DC_UNDER_VOLTAGE_TIMEOUT"; 
446
 
        bcmxcp_alarm_map[BCMXCP_ALARM_AC_UNDER_VOLTAGE_TIMEOUT].alarm_desc = "AC_UNDER_VOLTAGE_TIMEOUT"; 
 
491
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_UNDER_VOLTAGE_TIMEOUT].alarm_desc = "DC_UNDER_VOLTAGE_TIMEOUT";
 
492
        bcmxcp_alarm_map[BCMXCP_ALARM_AC_UNDER_VOLTAGE_TIMEOUT].alarm_desc = "AC_UNDER_VOLTAGE_TIMEOUT";
447
493
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_UNDER_VOLTAGE_WHILE_CHARGE].alarm_desc = "DC_UNDER_VOLTAGE_WHILE_CHARGE";
448
494
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_VOLTAGE_BIAS_ERROR].alarm_desc = "INVERTER_VOLTAGE_BIAS_ERROR";
449
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_PHASE_ROTATION].alarm_desc = "RECTIFIER_PHASE_ROTATION"; 
450
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_PHASER_ROTATION].alarm_desc = "BYPASS_PHASER_ROTATION"; 
 
495
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_PHASE_ROTATION].alarm_desc = "RECTIFIER_PHASE_ROTATION";
 
496
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_PHASER_ROTATION].alarm_desc = "BYPASS_PHASER_ROTATION";
451
497
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSTEM_INTERFACE_BOARD_FAIL].alarm_desc = "SYSTEM_INTERFACE_BOARD_FAIL";
452
498
        bcmxcp_alarm_map[BCMXCP_ALARM_PARALLEL_BOARD_FAIL].alarm_desc = "PARALLEL_BOARD_FAIL";
453
499
        bcmxcp_alarm_map[BCMXCP_ALARM_LOST_LOAD_SHARING_PHASE_A].alarm_desc = "LOST_LOAD_SHARING_PHASE_A";
454
500
        bcmxcp_alarm_map[BCMXCP_ALARM_LOST_LOAD_SHARING_PHASE_B].alarm_desc = "LOST_LOAD_SHARING_PHASE_B";
455
501
        bcmxcp_alarm_map[BCMXCP_ALARM_LOST_LOAD_SHARING_PHASE_C].alarm_desc = "LOST_LOAD_SHARING_PHASE_C";
456
502
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_OVER_VOLTAGE_TIMEOUT].alarm_desc = "DC_OVER_VOLTAGE_TIMEOUT";
457
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_TOTALLY_DISCHARGED].alarm_desc = "BATTERY_TOTALLY_DISCHARGED"; 
 
503
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_TOTALLY_DISCHARGED].alarm_desc = "BATTERY_TOTALLY_DISCHARGED";
458
504
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_PHASE_BIAS_ERROR].alarm_desc = "INVERTER_PHASE_BIAS_ERROR";
459
505
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_VOLTAGE_BIAS_ERROR_2].alarm_desc = "INVERTER_VOLTAGE_BIAS_ERROR_2";
460
 
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_LINK_BLEED_COMPLETE].alarm_desc = "DC_LINK_BLEED_COMPLETE"; 
 
506
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_LINK_BLEED_COMPLETE].alarm_desc = "DC_LINK_BLEED_COMPLETE";
461
507
        bcmxcp_alarm_map[BCMXCP_ALARM_LARGE_CHARGER_INPUT_CURRENT].alarm_desc = "LARGE_CHARGER_INPUT_CURRENT";
462
508
        bcmxcp_alarm_map[BCMXCP_ALARM_INV_VOLT_TOO_LOW_FOR_RAMP_LEVEL].alarm_desc = "INV_VOLT_TOO_LOW_FOR_RAMP_LEVEL";
463
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LOSS_OF_REDUNDANCY].alarm_desc = "LOSS_OF_REDUNDANCY"; 
464
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LOSS_OF_SYNC_BUS].alarm_desc = "LOSS_OF_SYNC_BUS"; 
465
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_BREAKER_SHUNT_TRIP].alarm_desc = "RECTIFIER_BREAKER_SHUNT_TRIP"; 
466
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LOSS_OF_CHARGER_SYNC].alarm_desc = "LOSS_OF_CHARGER_SYNC"; 
 
509
        bcmxcp_alarm_map[BCMXCP_ALARM_LOSS_OF_REDUNDANCY].alarm_desc = "LOSS_OF_REDUNDANCY";
 
510
        bcmxcp_alarm_map[BCMXCP_ALARM_LOSS_OF_SYNC_BUS].alarm_desc = "LOSS_OF_SYNC_BUS";
 
511
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_BREAKER_SHUNT_TRIP].alarm_desc = "RECTIFIER_BREAKER_SHUNT_TRIP";
 
512
        bcmxcp_alarm_map[BCMXCP_ALARM_LOSS_OF_CHARGER_SYNC].alarm_desc = "LOSS_OF_CHARGER_SYNC";
467
513
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_LOW_LEVEL_TEST_TIMEOUT].alarm_desc = "INVERTER_LOW_LEVEL_TEST_TIMEOUT";
468
514
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_BREAKER_OPEN].alarm_desc = "OUTPUT_BREAKER_OPEN";
469
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CONTROL_POWER_ON].alarm_desc = "CONTROL_POWER_ON"; 
 
515
        bcmxcp_alarm_map[BCMXCP_ALARM_CONTROL_POWER_ON].alarm_desc = "CONTROL_POWER_ON";
470
516
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_ON].alarm_desc = "INVERTER_ON";
471
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_ON].alarm_desc = "CHARGER_ON"; 
 
517
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_ON].alarm_desc = "CHARGER_ON";
472
518
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_ON].alarm_desc = "BYPASS_ON";
473
519
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_POWER_LOSS].alarm_desc = "BYPASS_POWER_LOSS";
474
 
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_MANUAL_BYPASS].alarm_desc = "ON_MANUAL_BYPASS"; 
475
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_MANUAL_TURN_OFF].alarm_desc = "BYPASS_MANUAL_TURN_OFF"; 
476
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_BLEEDING_DC_LINK_VOLT].alarm_desc = "INVERTER_BLEEDING_DC_LINK_VOLT"; 
 
520
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_MANUAL_BYPASS].alarm_desc = "ON_MANUAL_BYPASS";
 
521
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_MANUAL_TURN_OFF].alarm_desc = "BYPASS_MANUAL_TURN_OFF";
 
522
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_BLEEDING_DC_LINK_VOLT].alarm_desc = "INVERTER_BLEEDING_DC_LINK_VOLT";
477
523
        bcmxcp_alarm_map[BCMXCP_ALARM_CPU_ISR_ERROR].alarm_desc = "CPU_ISR_ERROR";
478
 
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSTEM_ISR_RESTART].alarm_desc = "SYSTEM_ISR_RESTART"; 
 
524
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSTEM_ISR_RESTART].alarm_desc = "SYSTEM_ISR_RESTART";
479
525
        bcmxcp_alarm_map[BCMXCP_ALARM_PARALLEL_DC].alarm_desc = "PARALLEL_DC";
480
526
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_NEEDS_SERVICE].alarm_desc = "BATTERY_NEEDS_SERVICE";
481
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CHARGING].alarm_desc = "BATTERY_CHARGING"; 
 
527
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_CHARGING].alarm_desc = "BATTERY_CHARGING";
482
528
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_NOT_CHARGED].alarm_desc = "BATTERY_NOT_CHARGED";
483
529
        bcmxcp_alarm_map[BCMXCP_ALARM_DISABLED_BATTERY_TIME].alarm_desc = "DISABLED_BATTERY_TIME";
484
 
        bcmxcp_alarm_map[BCMXCP_ALARM_SERIES_7000_ENABLE].alarm_desc = "SERIES_7000_ENABLE"; 
485
 
        bcmxcp_alarm_map[BCMXCP_ALARM_OTHER_UPS_ON].alarm_desc = "OTHER_UPS_ON"; 
 
530
        bcmxcp_alarm_map[BCMXCP_ALARM_SERIES_7000_ENABLE].alarm_desc = "SERIES_7000_ENABLE";
 
531
        bcmxcp_alarm_map[BCMXCP_ALARM_OTHER_UPS_ON].alarm_desc = "OTHER_UPS_ON";
486
532
        bcmxcp_alarm_map[BCMXCP_ALARM_PARALLEL_INVERTER].alarm_desc = "PARALLEL_INVERTER";
487
533
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_IN_PARALLEL].alarm_desc = "UPS_IN_PARALLEL";
488
534
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTPUT_BREAKER_REALY_FAIL].alarm_desc = "OUTPUT_BREAKER_REALY_FAIL";
489
535
        bcmxcp_alarm_map[BCMXCP_ALARM_CONTROL_POWER_OFF].alarm_desc = "CONTROL_POWER_OFF";
490
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_2_OVERLOAD_PHASE_A].alarm_desc = "LEVEL_2_OVERLOAD_PHASE_A"; 
491
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_2_OVERLOAD_PHASE_B].alarm_desc = "LEVEL_2_OVERLOAD_PHASE_B"; 
492
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_2_OVERLOAD_PHASE_C].alarm_desc = "LEVEL_2_OVERLOAD_PHASE_C"; 
493
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_3_OVERLOAD_PHASE_A].alarm_desc = "LEVEL_3_OVERLOAD_PHASE_A"; 
494
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_3_OVERLOAD_PHASE_B].alarm_desc = "LEVEL_3_OVERLOAD_PHASE_B"; 
495
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_3_OVERLOAD_PHASE_C].alarm_desc = "LEVEL_3_OVERLOAD_PHASE_C"; 
496
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_4_OVERLOAD_PHASE_A].alarm_desc = "LEVEL_4_OVERLOAD_PHASE_A"; 
497
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_4_OVERLOAD_PHASE_B].alarm_desc = "LEVEL_4_OVERLOAD_PHASE_B"; 
498
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_4_OVERLOAD_PHASE_C].alarm_desc = "LEVEL_4_OVERLOAD_PHASE_C"; 
499
 
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_ON_BATTERY].alarm_desc = "UPS_ON_BATTERY"; 
 
536
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_2_OVERLOAD_PHASE_A].alarm_desc = "LEVEL_2_OVERLOAD_PHASE_A";
 
537
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_2_OVERLOAD_PHASE_B].alarm_desc = "LEVEL_2_OVERLOAD_PHASE_B";
 
538
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_2_OVERLOAD_PHASE_C].alarm_desc = "LEVEL_2_OVERLOAD_PHASE_C";
 
539
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_3_OVERLOAD_PHASE_A].alarm_desc = "LEVEL_3_OVERLOAD_PHASE_A";
 
540
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_3_OVERLOAD_PHASE_B].alarm_desc = "LEVEL_3_OVERLOAD_PHASE_B";
 
541
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_3_OVERLOAD_PHASE_C].alarm_desc = "LEVEL_3_OVERLOAD_PHASE_C";
 
542
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_4_OVERLOAD_PHASE_A].alarm_desc = "LEVEL_4_OVERLOAD_PHASE_A";
 
543
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_4_OVERLOAD_PHASE_B].alarm_desc = "LEVEL_4_OVERLOAD_PHASE_B";
 
544
        bcmxcp_alarm_map[BCMXCP_ALARM_LEVEL_4_OVERLOAD_PHASE_C].alarm_desc = "LEVEL_4_OVERLOAD_PHASE_C";
 
545
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_ON_BATTERY].alarm_desc = "UPS_ON_BATTERY";
500
546
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_ON_BYPASS].alarm_desc = "UPS_ON_BYPASS";
501
547
        bcmxcp_alarm_map[BCMXCP_ALARM_LOAD_DUMPED].alarm_desc = "LOAD_DUMPED";
502
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LOAD_ON_INVERTER].alarm_desc = "LOAD_ON_INVERTER"; 
503
 
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_ON_COMMAND].alarm_desc = "UPS_ON_COMMAND"; 
 
548
        bcmxcp_alarm_map[BCMXCP_ALARM_LOAD_ON_INVERTER].alarm_desc = "LOAD_ON_INVERTER";
 
549
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_ON_COMMAND].alarm_desc = "UPS_ON_COMMAND";
504
550
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_OFF_COMMAND].alarm_desc = "UPS_OFF_COMMAND";
505
 
        bcmxcp_alarm_map[BCMXCP_ALARM_LOW_BATTERY_SHUTDOWN].alarm_desc = "LOW_BATTERY_SHUTDOWN"; 
 
551
        bcmxcp_alarm_map[BCMXCP_ALARM_LOW_BATTERY_SHUTDOWN].alarm_desc = "LOW_BATTERY_SHUTDOWN";
506
552
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTO_ON_ENABLED].alarm_desc = "AUTO_ON_ENABLED";
507
553
        bcmxcp_alarm_map[BCMXCP_ALARM_SOFTWARE_INCOMPABILITY_DETECTED].alarm_desc = "SOFTWARE_INCOMPABILITY_DETECTED";
508
554
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_TEMP_SENSOR_FAILED].alarm_desc = "INVERTER_TEMP_SENSOR_FAILED";
509
 
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_START_OCCURED].alarm_desc = "DC_START_OCCURED"; 
 
555
        bcmxcp_alarm_map[BCMXCP_ALARM_DC_START_OCCURED].alarm_desc = "DC_START_OCCURED";
510
556
        bcmxcp_alarm_map[BCMXCP_ALARM_IN_PARALLEL_OPERATION].alarm_desc = "IN_PARALLEL_OPERATION";
511
557
        bcmxcp_alarm_map[BCMXCP_ALARM_SYNCING_TO_BYPASS].alarm_desc = "SYNCING_TO_BYPASS";
512
 
        bcmxcp_alarm_map[BCMXCP_ALARM_RAMPING_UPS_UP].alarm_desc = "RAMPING_UPS_UP"; 
 
558
        bcmxcp_alarm_map[BCMXCP_ALARM_RAMPING_UPS_UP].alarm_desc = "RAMPING_UPS_UP";
513
559
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_ON_DELAY].alarm_desc = "INVERTER_ON_DELAY";
514
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_ON_DELAY].alarm_desc = "CHARGER_ON_DELAY"; 
515
 
        bcmxcp_alarm_map[BCMXCP_ALARM_WAITING_FOR_UTIL_INPUT].alarm_desc = "WAITING_FOR_UTIL_INPUT"; 
516
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CLOSE_BYPASS_BREAKER].alarm_desc = "CLOSE_BYPASS_BREAKER"; 
517
 
        bcmxcp_alarm_map[BCMXCP_ALARM_TEMPORARY_BYPASS_OPERATION].alarm_desc = "TEMPORARY_BYPASS_OPERATION"; 
 
560
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_ON_DELAY].alarm_desc = "CHARGER_ON_DELAY";
 
561
        bcmxcp_alarm_map[BCMXCP_ALARM_WAITING_FOR_UTIL_INPUT].alarm_desc = "WAITING_FOR_UTIL_INPUT";
 
562
        bcmxcp_alarm_map[BCMXCP_ALARM_CLOSE_BYPASS_BREAKER].alarm_desc = "CLOSE_BYPASS_BREAKER";
 
563
        bcmxcp_alarm_map[BCMXCP_ALARM_TEMPORARY_BYPASS_OPERATION].alarm_desc = "TEMPORARY_BYPASS_OPERATION";
518
564
        bcmxcp_alarm_map[BCMXCP_ALARM_SYNCING_TO_OUTPUT].alarm_desc = "SYNCING_TO_OUTPUT";
519
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_FAILURE].alarm_desc = "BYPASS_FAILURE"; 
 
565
        bcmxcp_alarm_map[BCMXCP_ALARM_BYPASS_FAILURE].alarm_desc = "BYPASS_FAILURE";
520
566
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTO_OFF_COMMAND_EXECUTED].alarm_desc = "AUTO_OFF_COMMAND_EXECUTED";
521
 
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTO_ON_COMMAND_EXECUTED].alarm_desc = "AUTO_ON_COMMAND_EXECUTED"; 
 
567
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTO_ON_COMMAND_EXECUTED].alarm_desc = "AUTO_ON_COMMAND_EXECUTED";
522
568
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_TEST_FAILED].alarm_desc = "BATTERY_TEST_FAILED";
523
569
        bcmxcp_alarm_map[BCMXCP_ALARM_FUSE_FAIL].alarm_desc = "FUSE_FAIL";
524
 
        bcmxcp_alarm_map[BCMXCP_ALARM_FAN_FAIL].alarm_desc = "FAN_FAIL"; 
 
570
        bcmxcp_alarm_map[BCMXCP_ALARM_FAN_FAIL].alarm_desc = "FAN_FAIL";
525
571
        bcmxcp_alarm_map[BCMXCP_ALARM_SITE_WIRING_FAULT].alarm_desc = "SITE_WIRING_FAULT";
526
572
        bcmxcp_alarm_map[BCMXCP_ALARM_BACKFEED_CONTACTOR_FAIL].alarm_desc = "BACKFEED_CONTACTOR_FAIL";
527
573
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_BUCK].alarm_desc = "ON_BUCK";
528
 
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_BOOST].alarm_desc = "ON_BOOST"; 
 
574
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_BOOST].alarm_desc = "ON_BOOST";
529
575
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_DOUBLE_BOOST].alarm_desc = "ON_DOUBLE_BOOST";
530
 
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERIES_DISCONNECTED].alarm_desc = "BATTERIES_DISCONNECTED"; 
 
576
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERIES_DISCONNECTED].alarm_desc = "BATTERIES_DISCONNECTED";
531
577
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_CABINET_OVER_TEMP].alarm_desc = "UPS_CABINET_OVER_TEMP";
532
578
        bcmxcp_alarm_map[BCMXCP_ALARM_TRANSFORMER_OVER_TEMP].alarm_desc = "TRANSFORMER_OVER_TEMP";
533
 
        bcmxcp_alarm_map[BCMXCP_ALARM_AMBIENT_UNDER_TEMP].alarm_desc = "AMBIENT_UNDER_TEMP"; 
 
579
        bcmxcp_alarm_map[BCMXCP_ALARM_AMBIENT_UNDER_TEMP].alarm_desc = "AMBIENT_UNDER_TEMP";
534
580
        bcmxcp_alarm_map[BCMXCP_ALARM_AMBIENT_OVER_TEMP].alarm_desc = "AMBIENT_OVER_TEMP";
535
581
        bcmxcp_alarm_map[BCMXCP_ALARM_CABINET_DOOR_OPEN].alarm_desc = "CABINET_DOOR_OPEN";
536
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CABINET_DOOR_OPEN_VOLT_PRESENT].alarm_desc = "CABINET_DOOR_OPEN_VOLT_PRESENT"; 
 
582
        bcmxcp_alarm_map[BCMXCP_ALARM_CABINET_DOOR_OPEN_VOLT_PRESENT].alarm_desc = "CABINET_DOOR_OPEN_VOLT_PRESENT";
537
583
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTO_SHUTDOWN_PENDING].alarm_desc = "AUTO_SHUTDOWN_PENDING";
538
584
        bcmxcp_alarm_map[BCMXCP_ALARM_TAP_SWITCHING_REALY_PENDING].alarm_desc = "TAP_SWITCHING_REALY_PENDING";
539
 
        bcmxcp_alarm_map[BCMXCP_ALARM_UNABLE_TO_CHARGE_BATTERIES].alarm_desc = "UNABLE_TO_CHARGE_BATTERIES"; 
 
585
        bcmxcp_alarm_map[BCMXCP_ALARM_UNABLE_TO_CHARGE_BATTERIES].alarm_desc = "UNABLE_TO_CHARGE_BATTERIES";
540
586
        bcmxcp_alarm_map[BCMXCP_ALARM_STARTUP_FAILURE_CHECK_EPO].alarm_desc = "STARTUP_FAILURE_CHECK_EPO";
541
587
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTOMATIC_STARTUP_PENDING].alarm_desc = "AUTOMATIC_STARTUP_PENDING";
542
 
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_FAILED].alarm_desc = "MODEM_FAILED"; 
 
588
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_FAILED].alarm_desc = "MODEM_FAILED";
543
589
        bcmxcp_alarm_map[BCMXCP_ALARM_INCOMING_MODEM_CALL_STARTED].alarm_desc = "INCOMING_MODEM_CALL_STARTED";
544
590
        bcmxcp_alarm_map[BCMXCP_ALARM_OUTGOING_MODEM_CALL_STARTED].alarm_desc = "OUTGOING_MODEM_CALL_STARTED";
545
 
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_CONNECTION_ESTABLISHED].alarm_desc = "MODEM_CONNECTION_ESTABLISHED"; 
546
 
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_CALL_COMPLETED_SUCCESS].alarm_desc = "MODEM_CALL_COMPLETED_SUCCESS"; 
 
591
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_CONNECTION_ESTABLISHED].alarm_desc = "MODEM_CONNECTION_ESTABLISHED";
 
592
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_CALL_COMPLETED_SUCCESS].alarm_desc = "MODEM_CALL_COMPLETED_SUCCESS";
547
593
        bcmxcp_alarm_map[BCMXCP_ALARM_MODEM_CALL_COMPLETED_FAIL].alarm_desc = "MODEM_CALL_COMPLETED_FAIL";
548
 
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_BREAKER_FAIL].alarm_desc = "INPUT_BREAKER_FAIL"; 
 
594
        bcmxcp_alarm_map[BCMXCP_ALARM_INPUT_BREAKER_FAIL].alarm_desc = "INPUT_BREAKER_FAIL";
549
595
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSINIT_IN_PROGRESS].alarm_desc = "SYSINIT_IN_PROGRESS";
550
 
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTOCALIBRATION_FAIL].alarm_desc = "AUTOCALIBRATION_FAIL"; 
551
 
        bcmxcp_alarm_map[BCMXCP_ALARM_SELECTIVE_TRIP_OF_MODULE].alarm_desc = "SELECTIVE_TRIP_OF_MODULE"; 
 
596
        bcmxcp_alarm_map[BCMXCP_ALARM_AUTOCALIBRATION_FAIL].alarm_desc = "AUTOCALIBRATION_FAIL";
 
597
        bcmxcp_alarm_map[BCMXCP_ALARM_SELECTIVE_TRIP_OF_MODULE].alarm_desc = "SELECTIVE_TRIP_OF_MODULE";
552
598
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_OUTPUT_FAILURE].alarm_desc = "INVERTER_OUTPUT_FAILURE";
553
599
        bcmxcp_alarm_map[BCMXCP_ALARM_ABNORMAL_OUTPUT_VOLT_AT_STARTUP].alarm_desc = "ABNORMAL_OUTPUT_VOLT_AT_STARTUP";
554
600
        bcmxcp_alarm_map[BCMXCP_ALARM_RECTIFIER_OVER_TEMP].alarm_desc = "RECTIFIER_OVER_TEMP";
555
 
        bcmxcp_alarm_map[BCMXCP_ALARM_CONFIG_ERROR].alarm_desc = "CONFIG_ERROR"; 
 
601
        bcmxcp_alarm_map[BCMXCP_ALARM_CONFIG_ERROR].alarm_desc = "CONFIG_ERROR";
556
602
        bcmxcp_alarm_map[BCMXCP_ALARM_REDUNDANCY_LOSS_DUE_TO_OVERLOAD].alarm_desc = "REDUNDANCY_LOSS_DUE_TO_OVERLOAD";
557
 
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_ALTERNATE_AC_SOURCE].alarm_desc = "ON_ALTERNATE_AC_SOURCE"; 
 
603
        bcmxcp_alarm_map[BCMXCP_ALARM_ON_ALTERNATE_AC_SOURCE].alarm_desc = "ON_ALTERNATE_AC_SOURCE";
 
604
        bcmxcp_alarm_map[BCMXCP_ALARM_IN_HIGH_EFFICIENCY_MODE].alarm_desc = "IN_HIGH_EFFICIENCY_MODE";
 
605
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSTEM_NOTICE_ACTIVE].alarm_desc = "SYSTEM_NOTICE_ACTIVE";
 
606
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSTEM_ALARM_ACTIVE].alarm_desc = "SYSTEM_ALARM_ACTIVE";
 
607
        bcmxcp_alarm_map[BCMXCP_ALARM_ALTERNATE_POWER_SOURCE_NOT_AVAILABLE].alarm_desc = "ALTERNATE_POWER_SOURCE_NOT_AVAILABLE";
 
608
        bcmxcp_alarm_map[BCMXCP_ALARM_CURRENT_BALANCE_FAILURE].alarm_desc = "CURRENT_BALANCE_FAILURE";
 
609
        bcmxcp_alarm_map[BCMXCP_ALARM_CHECK_AIR_FILTER].alarm_desc = "CHECK_AIR_FILTER";
 
610
        bcmxcp_alarm_map[BCMXCP_ALARM_SUBSYSTEM_NOTICE_ACTIVE].alarm_desc = "SUBSYSTEM_NOTICE_ACTIVE";
 
611
        bcmxcp_alarm_map[BCMXCP_ALARM_SUBSYSTEM_ALARM_ACTIVE].alarm_desc = "SUBSYSTEM_ALARM_ACTIVE";
 
612
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_ON_COMMAND].alarm_desc = "CHARGER_ON_COMMAND";
 
613
        bcmxcp_alarm_map[BCMXCP_ALARM_CHARGER_OFF_COMMAND].alarm_desc = "CHARGER_OFF_COMMAND";
 
614
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_NORMAL].alarm_desc = "UPS_NORMAL";
 
615
        bcmxcp_alarm_map[BCMXCP_ALARM_INVERTER_PHASE_ROTATION].alarm_desc = "INVERTER_PHASE_ROTATION";
 
616
        bcmxcp_alarm_map[BCMXCP_ALARM_UPS_OFF].alarm_desc = "UPS_OFF";
 
617
        bcmxcp_alarm_map[BCMXCP_ALARM_EXTERNAL_COMMUNICATION_FAILURE].alarm_desc = "EXTERNAL_COMMUNICATION_FAILURE";
 
618
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_TEST_INPROGRESS].alarm_desc = "BATTERY_TEST_INPROGRESS";
 
619
        bcmxcp_alarm_map[BCMXCP_ALARM_SYSTEM_TEST_INPROGRESS].alarm_desc = "SYSTEM_TEST_INPROGRESS";
 
620
        bcmxcp_alarm_map[BCMXCP_ALARM_BATTERY_TEST_ABORTED].alarm_desc = "BATTERY_TEST_ABORTED";
 
621
 
 
622
}
 
623
 
 
624
/* Get information on UPS commands */
 
625
void init_command_map()
 
626
{
 
627
        unsigned char answer[PW_ANSWER_MAX_SIZE];
 
628
        int res;
 
629
 
 
630
        upsdebugx(1, "entering init_command_map()");
 
631
 
 
632
        res = command_read_sequence(PW_COMMAND_LIST_REQ, answer);
 
633
        if (res <= 0)
 
634
                upsdebugx(2, "No command list block.");
 
635
        else
 
636
                upsdebugx(2, "Command list block supported.");
 
637
 
 
638
        /* FIXME: to be completed */
558
639
}
559
640
 
560
641
void init_ups_meter_map(const unsigned char *map, unsigned char len)
561
642
{
562
643
        unsigned int iIndex, iOffset = 0;
563
 
        
 
644
 
564
645
        /* In case of debug - make explanation of values */
565
646
        upsdebugx(2, "Index\tOffset\tFormat\tNUT\n");
566
 
        
 
647
 
567
648
        /* Loop thru map */
568
649
        for (iIndex = 0; iIndex < len && iIndex < BCMXCP_METER_MAP_MAX; iIndex++)
569
650
        {
596
677
        *value = '\0';
597
678
        if (entry == (unsigned char *)NULL || format == 0x00)
598
679
                return;
599
 
        
 
680
 
600
681
        /* Get data based on format */
601
682
        if (format == 0xf0) {
602
683
                /* Long integer */
660
741
{
661
742
        unsigned int iIndex = 0, iOffset = 0;
662
743
        int alarm = 0;
663
 
        
 
744
 
664
745
        /* In case of debug - make explanation of values */
665
746
        upsdebugx(2, "Index\tAlarm\tSupported\n");
666
747
 
667
748
        /* Loop thru map */
668
749
        for (iIndex = 0; iIndex < len && iIndex < BCMXCP_ALARM_MAP_MAX / 8; iIndex++)
669
 
        { 
 
750
        {
670
751
                /* Bit 0 */
671
752
                iOffset = iIndex * 8;
672
753
                if (map[iIndex] & 0x01)
832
913
 
833
914
int init_outlet(unsigned char len)
834
915
{
835
 
        unsigned char answer[len];
 
916
        unsigned char answer[PW_ANSWER_MAX_SIZE];
836
917
        int iIndex = 0, res, num;
837
918
        int num_outlet, size_outlet;
838
919
        int outlet_num, outlet_state;
842
923
        res = command_read_sequence(PW_OUT_MON_BLOCK_REQ, answer);
843
924
        if (res <= 0)
844
925
                fatal_with_errno(EXIT_FAILURE, "Could not communicate with the ups");
 
926
        else
 
927
                upsdebugx(1, "init_outlet(%i), res=%i", len, res);
845
928
 
846
929
        num_outlet = answer[iIndex++];
847
 
        upsdebugx(2, "Number of outlets: %d\n", num_outlet); 
 
930
        upsdebugx(2, "Number of outlets: %d\n", num_outlet);
848
931
 
849
932
        size_outlet = answer[iIndex++];
850
 
        upsdebugx(2, "Number of bytes: %d\n", size_outlet); 
 
933
        upsdebugx(2, "Number of bytes: %d\n", size_outlet);
851
934
 
852
935
        for(num = 1 ; num <= num_outlet ; num++) {
853
936
                outlet_num = answer[iIndex++];
865
948
                upsdebugx(2, "Auto delay off: %d\n", auto_dly_off);
866
949
                snprintf(outlet_name, sizeof(outlet_name)-1, "outlet.%d.delay.shutdown", num);
867
950
                dstate_setinfo(outlet_name, "%d", auto_dly_off);
 
951
        dstate_setflags(outlet_name, ST_FLAG_RW | ST_FLAG_STRING);
 
952
        dstate_setaux(outlet_name, 5);
868
953
 
869
954
                auto_dly_on = get_word(answer+iIndex);
870
955
                iIndex += 2;
871
956
                upsdebugx(2, "Auto delay on: %d\n", auto_dly_on);
872
957
                snprintf(outlet_name, sizeof(outlet_name)-1, "outlet.%d.delay.start", num);
873
958
                dstate_setinfo(outlet_name, "%d", auto_dly_on);
874
 
        }       
 
959
        dstate_setflags(outlet_name, ST_FLAG_RW | ST_FLAG_STRING);
 
960
        dstate_setaux(outlet_name, 5);
 
961
        }
875
962
 
876
963
        return num_outlet;
877
964
 
879
966
 
880
967
void init_config(void)
881
968
{
882
 
        unsigned char answer[256];
 
969
        unsigned char answer[PW_ANSWER_MAX_SIZE];
883
970
        int voltage = 0, res, len;
884
971
        char sValue[17];
885
972
 
886
 
        res = command_read_sequence(PW_CONFIG_BLOC_REQ, answer);
 
973
        res = command_read_sequence(PW_CONFIG_BLOCK_REQ, answer);
887
974
        if (res <= 0)
888
975
                fatal_with_errno(EXIT_FAILURE, "Could not communicate with the ups");
889
976
 
892
979
 
893
980
        /* Nominal output voltage of ups */
894
981
        voltage = get_word((answer + BCMXCP_CONFIG_BLOCK_NOMINAL_OUTPUT_VOLTAGE));
895
 
        
 
982
 
896
983
        if (voltage != 0)
897
984
                dstate_setinfo("output.voltage.nominal", "%d", voltage);
898
985
 
899
986
        /* UPS serial number */
900
987
        sValue[16] = 0;
901
 
        
 
988
 
902
989
        snprintf(sValue, 16, "%s", answer + BCMXCP_CONFIG_BLOCK_SERIAL_NUMBER);
903
990
        len = 0;
904
991
 
908
995
                        break;
909
996
                }
910
997
        }
911
 
        
 
998
 
912
999
        dstate_setinfo("ups.serial", "%s", sValue);
913
 
        
 
1000
 
914
1001
}
915
1002
 
916
1003
void init_limit(void)
917
1004
{
918
 
        unsigned char answer[256];
 
1005
        unsigned char answer[PW_ANSWER_MAX_SIZE];
919
1006
        int value, res;
920
 
        char *horn_stat[3] = {"disabled", "enabled", "muted"};
 
1007
        const char *horn_stat[3] = {"disabled", "enabled", "muted"};
921
1008
 
922
1009
        res = command_read_sequence(PW_LIMIT_BLOCK_REQ, answer);
923
1010
        if (res <= 0) {
1007
1094
 
1008
1095
void upsdrv_initinfo(void)
1009
1096
{
1010
 
        unsigned char answer[256];
 
1097
        unsigned char answer[PW_ANSWER_MAX_SIZE];
1011
1098
        char *pTmp;
1012
1099
        char outlet_name[27];
 
1100
        char power_rating[10];
1013
1101
        int iRating = 0, iIndex = 0, res, len;
1014
1102
        int ncpu = 0, buf;
1015
1103
        int conf_block_len = 0, alarm_block_len = 0, cmd_list_len = 0;
1022
1110
                bcmxcp_status.shutdowndelay = atoi(getval("shutdown_delay"));
1023
1111
        else
1024
1112
                bcmxcp_status.shutdowndelay = 120;
1025
 
                
 
1113
 
1026
1114
        /* Get information on UPS from UPS ID block */
1027
1115
        res = command_read_sequence(PW_ID_BLOCK_REQ, answer);
1028
1116
        if (res <= 0)
1050
1138
 
1051
1139
                dstate_setinfo("ups.firmware", "%s", pTmp);
1052
1140
 
1053
 
                free(pTmp);
1054
 
 
1055
1141
                /* Increment index to point at end of CPU bytes. */
1056
1142
                iIndex += len * 2;
1057
1143
        }
1058
1144
 
 
1145
        free(pTmp);
 
1146
 
1059
1147
        /* Get rating in kVA, if present */
1060
1148
        if ((iRating = answer[iIndex++]) > 0)
1061
1149
                iRating *= 1000;
1076
1164
 
1077
1165
        /* Skip UPS' phase angle, as NUT do not care */
1078
1166
        iIndex += 1;
1079
 
        
 
1167
 
 
1168
        /* set manufacturer name */
 
1169
        dstate_setinfo("ups.mfr", "Eaton");
 
1170
 
1080
1171
        /* Get length of UPS description */
1081
1172
        len = answer[iIndex++];
1082
1173
 
1083
 
        /* Make a temporary buffer and store model description and VA rating in it */
1084
 
        pTmp = xmalloc(len+10);
 
1174
        /* Extract and reformat the model string */
 
1175
        pTmp = xmalloc(len+15);
1085
1176
        snprintf(pTmp, len + 1, "%s", answer + iIndex);
1086
1177
        pTmp[len+1] = 0;
1087
1178
        iIndex += len;
1088
 
 
1089
 
        /* Make a nice model string and tell NUT about it */
1090
 
        snprintfcat(pTmp, len+10, " %dVA", iRating);
1091
 
        dstate_setinfo("ups.model", "%s", pTmp);
 
1179
        /* power rating in the model name is in the form "<rating>i"
 
1180
         * ie "1500i", "500i", ...
 
1181
         * some models already includes it, so check to avoid duplication */
 
1182
        snprintf(power_rating, sizeof(power_rating), "%ii", iRating);
 
1183
        if (strstr(pTmp, power_rating) == NULL) {
 
1184
                snprintfcat(pTmp, len+10, " %s", power_rating);
 
1185
        }
 
1186
        dstate_setinfo("ups.model", "%s", rtrim(pTmp, ' '));
1092
1187
        free(pTmp);
1093
1188
 
1094
1189
        /* Get meter map info from ups, and init our map */
1095
1190
        len = answer[iIndex++];
1096
 
        upsdebugx(2, "Length of meter map: %d\n", len); 
 
1191
        upsdebugx(2, "Length of meter map: %d\n", len);
1097
1192
        init_ups_meter_map(answer+iIndex, len);
1098
1193
        iIndex += len;
1099
1194
 
1100
1195
        /* Next is alarm map */
1101
1196
        len = answer[iIndex++];
1102
 
        upsdebugx(2, "Length of alarm map: %d\n", len); 
 
1197
        upsdebugx(2, "Length of alarm map: %d\n", len);
1103
1198
        init_ups_alarm_map(answer+iIndex, len);
1104
1199
        iIndex += len;
1105
1200
 
1106
1201
        /* Then the Config_block_length */
1107
1202
        conf_block_len = get_word(answer+iIndex);
1108
 
        upsdebugx(2, "Lengt of Config_block: %d\n", conf_block_len);
 
1203
        upsdebugx(2, "Length of Config_block: %d\n", conf_block_len);
1109
1204
        iIndex += 2;
1110
1205
 
1111
1206
        /* Next is statistics map */
1112
1207
        len = answer[iIndex++];
1113
 
        upsdebugx(2, "Length of statistics map: %d\n", len); 
 
1208
        upsdebugx(2, "Length of statistics map: %d\n", len);
1114
1209
        /* init_statistics_map(answer+iIndex, len); */
1115
1210
        iIndex += len;
1116
1211
 
1127
1222
        iIndex += 1;
1128
1223
 
1129
1224
        /* Size of command list block */
1130
 
        cmd_list_len = get_word(answer+iIndex);
1131
 
        upsdebugx(2, "Lengt of command list: %d\n", cmd_list_len);
 
1225
        if (iIndex < res)
 
1226
                cmd_list_len = get_word(answer+iIndex);
 
1227
        upsdebugx(2, "Length of command list: %d\n", cmd_list_len);
1132
1228
        iIndex += 2;
1133
1229
 
1134
1230
        /* Size of outlet monitoring block */
1135
 
        outlet_block_len = get_word(answer+iIndex);
1136
 
        upsdebugx(2, "Lengt of outlet_block: %d\n", outlet_block_len);
 
1231
        if (iIndex < res)
 
1232
                outlet_block_len = get_word(answer+iIndex);
 
1233
        upsdebugx(2, "Length of outlet_block: %d\n", outlet_block_len);
1137
1234
        iIndex += 2;
1138
1235
 
1139
1236
        /* Size of the alarm block */
1140
 
        alarm_block_len = get_word(answer+iIndex);
1141
 
        upsdebugx(2, "Lengt of alarm_block: %d\n", alarm_block_len);
 
1237
        if (iIndex < res)
 
1238
                alarm_block_len = get_word(answer+iIndex);
 
1239
        upsdebugx(2, "Length of alarm_block: %d\n", alarm_block_len);
1142
1240
        /* End of UPS ID block request */
1143
1241
 
1144
1242
        /* Due to a bug in PW5115 firmware, we need to use blocklength > 8.
1145
 
        The protocol state that outlet block is only implemented if ther is
1146
 
        at least 2 outlet block. 5115 has only one outlet, but has outlet block. */ 
 
1243
        The protocol state that outlet block is only implemented if there is
 
1244
        at least 2 outlet block. 5115 has only one outlet, but has outlet block! */
1147
1245
        if (outlet_block_len > 8) {
1148
1246
                len = init_outlet(outlet_block_len);
1149
1247
 
1158
1256
 
1159
1257
        /* Get information on UPS extended limits */
1160
1258
        init_limit();
1161
 
        
1162
 
        /* Add instant commands */
 
1259
 
 
1260
        /* Get information on UPS commands */
 
1261
        if (cmd_list_len)
 
1262
                init_command_map();
 
1263
 
 
1264
        /* FIXME: leave up to init_command_map() to add instant commands? */
1163
1265
        dstate_addcmd("shutdown.return");
1164
1266
        dstate_addcmd("shutdown.stayoff");
1165
1267
        dstate_addcmd("test.battery.start");
1166
1268
 
1167
1269
        upsh.instcmd = instcmd;
 
1270
    upsh.setvar = setvar;
1168
1271
 
1169
1272
        return;
1170
1273
}
1171
1274
 
1172
1275
void upsdrv_updateinfo(void)
1173
1276
{
1174
 
        unsigned char answer[256]; 
 
1277
        unsigned char answer[PW_ANSWER_MAX_SIZE];
1175
1278
        char sValue[128];
1176
 
        int iIndex, res; 
 
1279
        int iIndex, res;
1177
1280
        float output, max_output, fValue = 0.0f;
 
1281
        int batt_status = 0;
 
1282
        const char      *nutvalue;
1178
1283
 
1179
1284
        /* Get info from UPS */
1180
1285
        res = command_read_sequence(PW_METER_BLOCK_REQ, answer);
1181
 
        
 
1286
 
1182
1287
        if (res <= 0){
1183
1288
                upslogx(LOG_ERR, "Short read from UPS");
1184
1289
                dstate_datastale();
1206
1311
                decode_meter_map_entry(answer + bcmxcp_meter_map[BCMXCP_METER_MAP_OUTPUT_VA_BAR_CHART].meter_block_index,
1207
1312
                                         bcmxcp_meter_map[BCMXCP_METER_MAP_OUTPUT_VA_BAR_CHART].format, sValue);
1208
1313
                max_output = atof(sValue);
1209
 
                
 
1314
 
1210
1315
                fValue = 0.0;
1211
1316
                if (max_output > 0.0)
1212
1317
                        fValue = 100 * (output / max_output);
1221
1326
                decode_meter_map_entry(answer + bcmxcp_meter_map[BCMXCP_METER_MAP_LOAD_CURR_PHASE_A_BAR_CHART].meter_block_index,
1222
1327
                                         bcmxcp_meter_map[BCMXCP_METER_MAP_LOAD_CURR_PHASE_A_BAR_CHART].format, sValue);
1223
1328
                max_output = atof(sValue);
1224
 
                
 
1329
 
1225
1330
                fValue = 0.0;
1226
1331
                if (max_output > 0.0)
1227
1332
                        fValue = 100 * (output / max_output);
1229
1334
        }
1230
1335
 
1231
1336
        /* Due to a bug in PW5115 firmware, we need to use blocklength > 8.
1232
 
        The protocol state that outlet block is only implemented if ther is
1233
 
        at least 2 outlet block. 5115 has only one outlet, but has outlet block. */ 
 
1337
        The protocol state that outlet block is only implemented if there is
 
1338
        at least 2 outlet block. 5115 has only one outlet, but has outlet block. */
1234
1339
        if (outlet_block_len > 8) {
1235
1340
                init_outlet(outlet_block_len);
1236
1341
        }
1263
1368
                                        if (iIndex == BCMXCP_ALARM_BATTERY_LOW) {
1264
1369
                                                bcmxcp_status.alarm_low_battery = 1;
1265
1370
                                        }
 
1371
 
 
1372
                                        if (iIndex == BCMXCP_ALARM_BATTERY_TEST_FAILED) {
 
1373
                                                bcmxcp_status.alarm_replace_battery = 1;
 
1374
                                        }
 
1375
 
 
1376
                                        if (iIndex == BCMXCP_ALARM_BATTERY_NEEDS_SERVICE) {
 
1377
                                                bcmxcp_status.alarm_replace_battery = 1;
 
1378
                                        }
1266
1379
                                }
1267
1380
                        }
1268
1381
                }
1292
1405
 
1293
1406
                /* Set status */
1294
1407
                status_init();
1295
 
        
 
1408
 
1296
1409
                switch (status) {
1297
1410
                        case 0x50: /* On line, everything is fine */
1298
1411
                                status_set("OL");
1335
1448
                        status_set("OB");
1336
1449
                if (bcmxcp_status.alarm_low_battery)
1337
1450
                        status_set("LB");
 
1451
                if (bcmxcp_status.alarm_replace_battery)
 
1452
                        status_set("RB");
1338
1453
 
1339
1454
                status_commit();
1340
 
        } 
 
1455
        }
 
1456
 
 
1457
        /* Get battery info from UPS, if exist */
 
1458
        res = command_read_sequence(PW_BATTERY_REQ, answer);
 
1459
        if (res <= 0)
 
1460
        {
 
1461
                upsdebugx(1, "Failed to read Battery Status from UPS");
 
1462
        }
 
1463
        else
 
1464
        {
 
1465
                /* Only parse the status (first byte)
 
1466
                 *  Powerware 5115 RM output:
 
1467
                 *   02 00 78 1d 42 00 e0 17 42 1e 00 00 00 00 00 00 00 00 00 01 03
 
1468
                 *  Powerware 9130 output:
 
1469
                 *   03 0a d7 25 42 0a d7 25 42 00 9a 19 6d 43 cd cc 4c 3e 01 00 01 03
 
1470
                 */
 
1471
                upsdebug_hex(2, "Battery Status", answer, res);
 
1472
                batt_status = answer[0];
 
1473
 
 
1474
                if ((nutvalue = nut_find_infoval(batt_test_info, batt_status)) != NULL) {
 
1475
                        dstate_setinfo("ups.test.result", "%s", nutvalue);
 
1476
                        upsdebugx(2, "Battery Status = %s (%i)", nutvalue, batt_status);
 
1477
                }
 
1478
                else {
 
1479
                        upsdebugx(1, "Failed to extract Battery Status from answer");
 
1480
                }
 
1481
        }
1341
1482
 
1342
1483
        dstate_dataok();
1343
1484
}
1346
1487
{
1347
1488
        /* tell the UPS to shut down, then return - DO NOT SLEEP HERE */
1348
1489
        unsigned char answer[5], cbuf[3];
1349
 
        
 
1490
 
1350
1491
        int res, sec;
1351
1492
 
1352
1493
        /* Get vars from ups.conf */
1358
1499
        /* maybe try to detect the UPS here, but try a shutdown even if
1359
1500
                 it doesn't respond at first if possible */
1360
1501
        send_write_command(AUTHOR, 4);
1361
 
        
1362
 
        sleep(1);       /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1502
 
 
1503
        sleep(PW_SLEEP);        /* Need to. Have to wait at least 0,25 sec max 16 sec */
1363
1504
 
1364
1505
        cbuf[0] = PW_LOAD_OFF_RESTART;
1365
1506
        cbuf[1] = (unsigned char)(bcmxcp_status.shutdowndelay & 0x00ff);        /* "delay" sec delay for shutdown, */
1366
1507
        cbuf[2] = (unsigned char)(bcmxcp_status.shutdowndelay >> 8);            /* hige byte sec. From ups.conf. */
1367
 
        
 
1508
 
1368
1509
        res = command_write_sequence(cbuf, 3, answer);
1369
1510
        if (res <= 0) {
1370
1511
                upslogx(LOG_ERR, "Short read from UPS");
1371
1512
                dstate_datastale();
1372
1513
                return;
1373
1514
        }
1374
 
        
 
1515
 
1375
1516
        sec = (256 * (unsigned char)answer[3]) + (unsigned char)answer[2];
1376
 
        
1377
 
        /* NOTE: get the respons, and return info code located as first data byte after 4 header bytes.
 
1517
 
 
1518
        /* NOTE: get the response, and return info code located as first data byte after 4 header bytes.
1378
1519
                Is implemented in answers to command packet's.
1379
1520
        0x31 Accepted
1380
1521
        0x32 not implemented
1385
1526
        0x37 Accepted with parameter adjusted
1386
1527
        */
1387
1528
        switch ((unsigned char) answer[0]) {
1388
 
        
 
1529
 
1389
1530
                case 0x31: {
1390
1531
                        upsdrv_comm_good();
1391
1532
                        upslogx(LOG_NOTICE,"Going down in %d sec", sec);
1392
1533
                        break;
1393
1534
                        }
1394
1535
                case 0x33: {
1395
 
                        fatalx(EXIT_FAILURE, "shutdown disbled by front panel");
 
1536
                        fatalx(EXIT_FAILURE, "shutdown disabled by front panel");
1396
1537
                        break;
1397
1538
                        }
1398
1539
                case 0x36: {
1409
1550
 
1410
1551
static int instcmd(const char *cmdname, const char *extra)
1411
1552
{
1412
 
        unsigned char answer[5], cbuf[6];
1413
 
 
 
1553
        unsigned char answer[128], cbuf[6];
 
1554
        char varname[32];
 
1555
        const char *varvalue = NULL;
1414
1556
        int res, sec;
1415
 
        
1416
 
        
 
1557
        int sddelay = 0x03;     /* outlet off in 3 seconds, by default */
 
1558
 
 
1559
        upsdebugx(1, "entering instcmd(%s)", cmdname);
 
1560
 
1417
1561
        /* ojw0000 outlet power cycle for PW5125 and perhaps others */
1418
1562
        if (!strcasecmp(cmdname, "outlet.1.shutdown.return")
1419
1563
                || !strcasecmp(cmdname, "outlet.2.shutdown.return")
1421
1565
            ) {
1422
1566
                send_write_command(AUTHOR, 4);
1423
1567
 
1424
 
                sleep(1);       /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1568
                sleep(PW_SLEEP);        /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1569
 
 
1570
                /* Get the shutdown delay, if any */
 
1571
                snprintf(varname, sizeof(varname)-1, "outlet.%c.delay.shutdown", cmdname[7]);
 
1572
                if ((varvalue = dstate_getinfo(varname)) != NULL) {
 
1573
                        sddelay = atoi(varvalue);
 
1574
                }
1425
1575
 
1426
1576
                cbuf[0] = PW_LOAD_OFF_RESTART;
1427
 
                cbuf[1] = 0x03; /* outlet off in 3 seconds */
1428
 
                cbuf[2] = 0x00; /* high byte of the 2 byte time argument */
 
1577
                cbuf[1] = sddelay & 0xff;
 
1578
                cbuf[2] = sddelay >> 8;         /* high byte of the 2 byte time argument */
1429
1579
                cbuf[3] = ( '1' == cmdname[7] ? 0x01 : 0x02); /* which outlet load segment?  Assumes '1' or '2' at position 8 of the command string. */
1430
1580
 
1431
1581
                /* ojw00000 the following copied from command "shutdown.return" below 2007Apr5 */
1435
1585
                        dstate_datastale();
1436
1586
                        return -1;
1437
1587
                }
1438
 
        
 
1588
 
1439
1589
                sec = (256 * (unsigned char)answer[3]) + (unsigned char)answer[2];
1440
 
        
 
1590
 
1441
1591
                switch ((unsigned char) answer[0]) {
1442
 
        
 
1592
 
1443
1593
                        case 0x31: {
1444
1594
                                upslogx(LOG_NOTICE,"Going down in %d sec", sec);
1445
1595
                                return STAT_INSTCMD_HANDLED;
1464
1614
 
1465
1615
        } /* ojw0000 end outlet power cycle */
1466
1616
 
 
1617
        /* FIXME: call upsdrv_shutdown() or use the present one! */
1467
1618
        if (!strcasecmp(cmdname, "shutdown.return")) {
1468
1619
                send_write_command(AUTHOR, 4);
1469
 
        
1470
 
                sleep(1);       /* Need to. Have to wait at least 0,25 sec max 16 sec */
1471
 
        
 
1620
 
 
1621
                sleep(PW_SLEEP);        /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1622
 
1472
1623
                cbuf[0] = PW_LOAD_OFF_RESTART;
1473
1624
                cbuf[1] = (unsigned char)(bcmxcp_status.shutdowndelay & 0x00ff);        /* "delay" sec delay for shutdown, */
1474
 
                cbuf[2] = (unsigned char)(bcmxcp_status.shutdowndelay >> 8);            /* hige byte sec. From ups.conf. */
1475
 
        
 
1625
                cbuf[2] = (unsigned char)(bcmxcp_status.shutdowndelay >> 8);            /* high byte sec. From ups.conf. */
 
1626
 
1476
1627
                res = command_write_sequence(cbuf, 3, answer);
1477
1628
                if (res <= 0) {
1478
1629
                        upslogx(LOG_ERR, "Short read from UPS");
1479
1630
                        dstate_datastale();
1480
1631
                        return -1;
1481
1632
                }
1482
 
        
 
1633
 
1483
1634
                sec = (256 * (unsigned char)answer[3]) + (unsigned char)answer[2];
1484
 
        
 
1635
 
1485
1636
                switch ((unsigned char) answer[0]) {
1486
 
        
 
1637
 
1487
1638
                        case 0x31: {
1488
1639
                                upslogx(LOG_NOTICE,"Going down in %d sec", sec);
1489
1640
                                return STAT_INSTCMD_HANDLED;
1490
1641
                                break;
1491
1642
                                }
1492
1643
                        case 0x33: {
1493
 
                                upslogx(LOG_NOTICE, "[%s] disbled by front panel", cmdname);
 
1644
                                upslogx(LOG_NOTICE, "[%s] disabled by front panel", cmdname);
1494
1645
                                return STAT_INSTCMD_UNKNOWN;
1495
1646
                                break;
1496
1647
                                }
1510
1661
 
1511
1662
        if (!strcasecmp(cmdname, "shutdown.stayoff")) {
1512
1663
                send_write_command(AUTHOR, 4);
1513
 
        
1514
 
                sleep(1);       /* Need to. Have to wait at least 0,25 sec max 16 sec */
1515
 
        
 
1664
 
 
1665
                sleep(PW_SLEEP);        /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1666
 
1516
1667
                res = command_read_sequence(PW_UPS_OFF, answer);
1517
1668
                if (res <= 0) {
1518
1669
                        upslogx(LOG_ERR, "Short read from UPS");
1519
1670
                        dstate_datastale();
1520
1671
                        return -1;
1521
1672
                }
1522
 
        
 
1673
 
1523
1674
                switch ((unsigned char) answer[0]) {
1524
 
        
 
1675
 
1525
1676
                        case 0x31: {
1526
1677
                                upslogx(LOG_NOTICE,"[%s] Going down NOW", cmdname);
1527
1678
                                return STAT_INSTCMD_HANDLED;
1528
1679
                                break;
1529
1680
                                }
1530
1681
                        case 0x33: {
1531
 
                                upslogx(LOG_NOTICE, "[%s] disbled by front panel", cmdname);
 
1682
                                upslogx(LOG_NOTICE, "[%s] disabled by front panel", cmdname);
1532
1683
                                return STAT_INSTCMD_UNKNOWN;
1533
1684
                                break;
1534
1685
                                }
1538
1689
                                break;
1539
1690
                                }
1540
1691
                        default: {
1541
 
                                upslogx(LOG_NOTICE, "[%s] not supported", cmdname);
 
1692
                                upslogx(LOG_NOTICE, "[%s] not supported (code %c)",
 
1693
                                        cmdname, (unsigned char) answer[0]);
1542
1694
                                return STAT_INSTCMD_UNKNOWN;
1543
1695
                                break;
1544
1696
                                }
1546
1698
 
1547
1699
        }
1548
1700
 
 
1701
        /* Note: test result will be parsed from Battery status block,
 
1702
         * part of the update loop, and published into ups.test.result
 
1703
         */
1549
1704
        if (!strcasecmp(cmdname, "test.battery.start")) {
1550
1705
                send_write_command(AUTHOR, 4);
1551
 
        
1552
 
                sleep(1);       /* Need to. Have to wait at least 0,25 sec max 16 sec */
1553
 
        
 
1706
 
 
1707
                sleep(PW_SLEEP);        /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1708
 
1554
1709
                cbuf[0] = PW_INIT_BAT_TEST;
1555
1710
                cbuf[1] = 0x0A;                 /* 10 sec start delay for test.*/
1556
1711
                cbuf[2] = 0x1E;                 /* 30 sec test duration.*/
1557
 
                
 
1712
 
1558
1713
                res = command_write_sequence(cbuf, 3, answer);
1559
1714
                if (res <= 0) {
1560
1715
                        upslogx(LOG_ERR, "Short read from UPS");
1561
1716
                        dstate_datastale();
1562
1717
                        return -1;
1563
1718
                }
1564
 
        
 
1719
 
1565
1720
                switch ((unsigned char) answer[0]) {
1566
 
        
 
1721
 
1567
1722
                        case 0x31: {
1568
1723
                                upslogx(LOG_NOTICE,"[%s] Testing now", cmdname);
1569
1724
                                return STAT_INSTCMD_HANDLED;
1570
1725
                                break;
1571
1726
                                }
1572
1727
                        case 0x33: {
1573
 
                                upslogx(LOG_NOTICE, "[%s] disbled by front panel", cmdname);
 
1728
                                upslogx(LOG_NOTICE, "[%s] disabled by front panel", cmdname);
1574
1729
                                return STAT_INSTCMD_UNKNOWN;
1575
1730
                                break;
1576
1731
                                }
1585
1740
                                break;
1586
1741
                                }
1587
1742
                }
1588
 
                /* Get test info from UPS ?
1589
 
                         Should we wait for 50 sec and get the
1590
 
                         answer from the test.
1591
 
                         Or return, as we may lose line power
1592
 
                         and need to do a shutdown.*/
1593
 
                
1594
1743
        }
1595
 
        
 
1744
 
1596
1745
        upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname);
1597
1746
        return STAT_INSTCMD_UNKNOWN;
1598
1747
}
1609
1758
        addvar(VAR_VALUE, "baud_rate", "Specify communication speed (ex: 9600)");
1610
1759
}
1611
1760
 
 
1761
int setvar (const char *varname, const char *val)
 
1762
{
 
1763
        unsigned char answer[128], cbuf[5];
 
1764
        char namebuf[MAX_NUT_NAME_LENGTH];
 
1765
        int res, sec, outlet_num;
 
1766
        int onOff_setting = PW_AUTO_OFF_DELAY;
 
1767
 
 
1768
        upsdebugx(1, "entering setvar(%s, %s)", varname, val);
 
1769
 
 
1770
        strncpy(namebuf, varname, sizeof(namebuf));
 
1771
        namebuf[NUT_OUTLET_POSITION] = 'n'; /* Assumes a maximum of 9 outlets */
 
1772
 
 
1773
        if ( (strcasecmp(namebuf, "outlet.n.delay.start")) &&
 
1774
                (strcasecmp(namebuf, "outlet.n.delay.shutdown")) ) {
 
1775
                        return STAT_SET_UNKNOWN;
 
1776
        }
 
1777
 
 
1778
        if (outlet_block_len <= 8) {
 
1779
                return STAT_SET_INVALID;
 
1780
        }
 
1781
 
 
1782
        if (!strcasecmp(namebuf, "outlet.n.delay.start")) {
 
1783
                onOff_setting = PW_AUTO_ON_DELAY;
 
1784
        }
 
1785
 
 
1786
        send_write_command(AUTHOR, 4);
 
1787
        sleep(PW_SLEEP);        /* Need to. Have to wait at least 0,25 sec max 16 sec */
 
1788
 
 
1789
        outlet_num = varname[NUT_OUTLET_POSITION] - '0';
 
1790
        if (outlet_num < 1 || outlet_num > 9) {
 
1791
                return STAT_SET_INVALID;
 
1792
        }
 
1793
 
 
1794
        sec = atoi(val);
 
1795
        /* Check value:
 
1796
         *      0-32767 are valid values
 
1797
         *      -1 means no Automatic off or restart
 
1798
         * for Auto Off Delay:
 
1799
         *      0-30 are valid but ill-advised */
 
1800
        if (sec < -1 || sec > 0x7FFF) {
 
1801
                return STAT_SET_INVALID;
 
1802
        }
 
1803
 
 
1804
        cbuf[0] = PW_SET_OUTLET_COMMAND;        /* Cmd */
 
1805
        cbuf[1] = onOff_setting;                        /* Set Auto Off (1) or On (2) Delay */
 
1806
        cbuf[2] = outlet_num;                           /* Outlet number */
 
1807
        cbuf[3] = sec&0xff;                                     /* Delay in seconds LSB */
 
1808
        cbuf[4] = sec>>8;                                       /* Delay in seconds MSB */
 
1809
 
 
1810
        res = command_write_sequence(cbuf, 5, answer);
 
1811
        if (res <= 0) {
 
1812
                upslogx(LOG_ERR, "Short read from UPS");
 
1813
                dstate_datastale();
 
1814
                return -1;
 
1815
        }
 
1816
 
 
1817
        switch ((unsigned char) answer[0]) {
 
1818
 
 
1819
                case 0x31: {
 
1820
                        upslogx(LOG_NOTICE,"Outlet %d %s delay set to %d sec",
 
1821
                                outlet_num, (onOff_setting == PW_AUTO_ON_DELAY)?"start":"shutdown", sec);
 
1822
                        dstate_setinfo(varname, "%d", sec);
 
1823
                        return STAT_SET_HANDLED;
 
1824
                        break;
 
1825
                        }
 
1826
                case 0x33: {
 
1827
                        upslogx(LOG_NOTICE, "Set [%s] failed due to UPS busy", varname);
 
1828
                        /* TODO: we should probably retry... */
 
1829
                        return STAT_SET_UNKNOWN;
 
1830
                        break;
 
1831
                        }
 
1832
                case 0x35: {
 
1833
                        upslogx(LOG_NOTICE, "Set [%s %s] failed due to parameter out of range", varname, val);
 
1834
                        return STAT_SET_UNKNOWN;
 
1835
                        break;
 
1836
                        }
 
1837
                case 0x36: {
 
1838
                        upslogx(LOG_NOTICE, "Set [%s %s] failed due to invalid parameter", varname, val);
 
1839
                        return STAT_SET_UNKNOWN;
 
1840
                        break;
 
1841
                        }
 
1842
                default: {
 
1843
                        upslogx(LOG_NOTICE, "Set [%s] not supported", varname);
 
1844
                        return STAT_SET_FAILED;
 
1845
                        break;
 
1846
                        }
 
1847
        }
 
1848
 
 
1849
        return STAT_SET_INVALID;
 
1850
}
 
1851
 
 
1852
/*******************************
 
1853
 * Extracted from usbhid-ups.c *
 
1854
 *******************************/
 
1855
 
 
1856
/* find the NUT value matching that XCP Item value */
 
1857
static const char *nut_find_infoval(info_lkp_t *xcp2info, const double value)
 
1858
{
 
1859
        info_lkp_t      *info_lkp;
 
1860
 
 
1861
        /* if a conversion function is defined, use 'value' as argument for it */
 
1862
        if (xcp2info->fun != NULL) {
 
1863
                return xcp2info->fun(value);
 
1864
        }
 
1865
 
 
1866
        /* use 'value' as an index for a lookup in an array */
 
1867
        for (info_lkp = xcp2info; info_lkp->nut_value != NULL; info_lkp++) {
 
1868
                if (info_lkp->xcp_value == (long)value) {
 
1869
                        upsdebugx(5, "nut_find_infoval: found %s (value: %ld)", info_lkp->nut_value, (long)value);
 
1870
                        return info_lkp->nut_value;
 
1871
                }
 
1872
        }
 
1873
 
 
1874
        upsdebugx(3, "hu_find_infoval: no matching INFO_* value for this XCP value (%g)", value);
 
1875
        return NULL;
 
1876
}