Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce sdcommands option and shutdown.default INSTCMD to all drivers #2686

Merged
merged 97 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
f6eb991
Introduce "sdcommands" setting for all drivers [#2670]
jimklimov Nov 10, 2024
ccddee5
drivers/mge-utalk.c: update to use "sdcommands" [#2670]
jimklimov Nov 14, 2024
4cf357a
drivers/everups.c: update to use "sdcommands" and have an instcmd() a…
jimklimov Nov 14, 2024
aa08ae5
drivers/adelsystem_cbi.c: update to use "sdcommands" and move logic f…
jimklimov Nov 14, 2024
e775b01
drivers/al175.c: update to use "sdcommands" (if customized by user) […
jimklimov Nov 14, 2024
1286775
drivers/apc_modbus.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 14, 2024
f8da375
drivers/apcsmart-old.c: update to use "sdcommands" (if customized by …
jimklimov Nov 14, 2024
b8fb714
drivers/apcsmart.c: update to use "sdcommands" (if customized by user…
jimklimov Nov 14, 2024
c18e0aa
drivers/apcupsd-ups.c: update to use "sdcommands" (if customized by u…
jimklimov Nov 14, 2024
ac1b463
drivers/asem.c: update to use "sdcommands" (if customized by user) [#…
jimklimov Nov 14, 2024
cd19aa9
drivers/bcmxcp.c: update to use "sdcommands" (if customized by user) …
jimklimov Nov 14, 2024
14a62df
drivers/belkin.c: update to use "sdcommands" and move logic from upsd…
jimklimov Nov 14, 2024
2ab7f2c
drivers/belkinunv.c: update to use "sdcommands" (if customized by use…
jimklimov Nov 14, 2024
b0d683a
drivers/bestfcom.c: update to use "sdcommands" and move logic from up…
jimklimov Nov 14, 2024
675db77
drivers/bestfortress.c: update to use "sdcommands" and move logic fro…
jimklimov Nov 14, 2024
5fe1576
drivers/bestuferrups.c: update to use "sdcommands" and move logic fro…
jimklimov Nov 14, 2024
fd42c1b
drivers/bestups.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 14, 2024
465552c
drivers/bicker_ser.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 14, 2024
4230032
drivers/blazer*.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 14, 2024
e738dbc
drivers/clone-outlet.c: update to use "sdcommands" (if customized by …
jimklimov Nov 14, 2024
fd6b951
drivers/clone.c: update to use "sdcommands" (if customized by user) […
jimklimov Nov 14, 2024
e79cdea
drivers/dummy-ups.c: update to use "sdcommands" (if customized by use…
jimklimov Nov 14, 2024
34b24b6
drivers/etapro.c: update to use "sdcommands" and move logic from upsd…
jimklimov Nov 15, 2024
80d583d
drivers/gamatronic.c: update to use "sdcommands" and move logic from …
jimklimov Nov 15, 2024
37af651
drivers/gamatronic.c: fix misplaced upslogx(1, ...) by upsdebugx()
jimklimov Nov 15, 2024
889c77e
drivers/generic_gpio_common.c: update to use "sdcommands" (if customi…
jimklimov Nov 15, 2024
37d51c4
drivers/generic_modbus.c: update to use "sdcommands" and move logic f…
jimklimov Nov 15, 2024
d16a41a
drivers/genericups.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 15, 2024
dea5b93
drivers/huawei-ups2000.c: update to use "sdcommands" (if customized b…
jimklimov Nov 15, 2024
2377d06
drivers/hwmon_ina219.c: update to use "sdcommands" (if customized by …
jimklimov Nov 15, 2024
fb89803
drivers/isbmex.c: update to use "sdcommands" and move logic from upsd…
jimklimov Nov 15, 2024
fceaa02
drivers/ivtscd.c: update to use "sdcommands" (if customized by user) …
jimklimov Nov 15, 2024
e6c5f05
drivers/liebert-esp2.c: update to use "sdcommands" (if customized by …
jimklimov Nov 15, 2024
a594018
drivers/liebert-gxe.c: update to use "sdcommands" (if customized by u…
jimklimov Nov 15, 2024
3392211
drivers/liebert.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 15, 2024
ac118f4
drivers/macosx-ups.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 15, 2024
6ad244c
drivers/masterguard.c: update to use "sdcommands" and move logic from…
jimklimov Nov 15, 2024
360a6b7
drivers/metasys.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 16, 2024
9e89bd1
drivers/microdowell.c: update to use "sdcommands" (if customized by u…
jimklimov Nov 16, 2024
ae2ae3a
drivers/microsol*.c: update to use "sdcommands" (if customized by use…
jimklimov Nov 16, 2024
3f6b070
drivers/netxml-ups.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 16, 2024
3c16437
drivers/nut-ipmipsu.c: update to use "sdcommands" (if customized by u…
jimklimov Nov 16, 2024
30b6a16
drivers/nutdrv_atcl_usb.c: update to use "sdcommands" and move logic …
jimklimov Nov 16, 2024
9758ee0
drivers/nutdrv_siemens_sitop.c: update to use "sdcommands" (if custom…
jimklimov Nov 16, 2024
699311f
drivers/nutdrv_qx.c: update to use "sdcommands" (if customized by use…
jimklimov Nov 16, 2024
c76f864
drivers/oneac.c: update to use "sdcommands" (if customized by user) […
jimklimov Nov 16, 2024
14fa750
drivers/optiups.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 17, 2024
ecd5bc9
drivers/phoenixcontact_modbus.c: update to use "sdcommands" (if custo…
jimklimov Nov 17, 2024
a74c8e9
drivers/pijuice.c: update to use "sdcommands" and move logic from ups…
jimklimov Nov 17, 2024
0a92a24
drivers/powercom.c: update to use "sdcommands" (if customized by user…
jimklimov Nov 18, 2024
bcf91c7
drivers/powerman.c: update to use "sdcommands" (if customized by user…
jimklimov Nov 18, 2024
d5d5dcb
drivers/powerp*.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 18, 2024
705e4f7
drivers/rhino.c: update to use "sdcommands" (if customized by user) […
jimklimov Nov 18, 2024
2c144c6
drivers/richcomm_usb.c: update to use "sdcommands" and move logic fro…
jimklimov Nov 18, 2024
4c5d3c3
drivers/riello_ser.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 18, 2024
964d740
drivers/riello_usb.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 18, 2024
7a7aea1
drivers/safenet.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 18, 2024
fc8cc45
drivers/skel.c: update to use "sdcommands" (if customized by user) [#…
jimklimov Nov 18, 2024
7355b93
drivers/sms_ser.c: update to use "sdcommands" (if customized by user)…
jimklimov Nov 18, 2024
a0fe95c
drivers/*.c: for networked drivers (snmp, netxml, IPMI, modbus/TCP) c…
jimklimov Nov 18, 2024
55bf0c0
drivers/snmp-ups.c: update to use "sdcommands" (if customized by user…
jimklimov Nov 18, 2024
23fd46f
drivers/socomec_jbus.c: update to use "sdcommands" (if customized by …
jimklimov Nov 18, 2024
349d421
drivers/solis.c: update to use "sdcommands" (if customized by user) […
jimklimov Nov 18, 2024
ac93000
drivers/tripplite.c: update to use "sdcommands" (if customized by use…
jimklimov Nov 18, 2024
57f7d07
drivers/tripplite_usb.c: update to use "sdcommands" (if customized by…
jimklimov Nov 18, 2024
db20fcc
drivers/tripplitesu.c: update to use "sdcommands" (if customized by u…
jimklimov Nov 18, 2024
1908ca6
drivers/upscode2.c: update to use "sdcommands" (if customized by user…
jimklimov Nov 18, 2024
a0fcfac
drivers/victronups.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 18, 2024
3fb5481
drivers/usbhid-ups.c: update to use "sdcommands" (if customized by us…
jimklimov Nov 18, 2024
3612f7a
include/common.h, docs/new-drivers.txt, NEWS.adoc: define common EF_E…
jimklimov Nov 18, 2024
33d3b21
drivers/*.c: use common EF_EXIT_FAILURE and EF_EXIT_SUCCESS arg value…
jimklimov Nov 18, 2024
2b79651
drivers/*.c, drivers/main.h: introduce and use a common handling_upsd…
jimklimov Nov 18, 2024
a25e052
drivers/ivtscd.c: comment about upsdrv_shutdown() oddness in this dri…
jimklimov Nov 18, 2024
2d9926d
drivers/powercom.c: drop checks for HAVE___ATTRIBUTE__NORETURN in ins…
jimklimov Nov 18, 2024
cc55e5a
drivers/main.{c,h}, docs: introduce `shutdown.default` INSTCMD concep…
jimklimov Nov 18, 2024
7d98b52
drivers/main.c: update some comments
jimklimov Nov 19, 2024
7b52ab9
drivers/main.c: implement INSTCMD "shutdown.default" as a way to call…
jimklimov Nov 19, 2024
59acc68
drivers/main.c: do_loop_shutdown_commands(): shortcut for "shutdown.d…
jimklimov Nov 19, 2024
40a0212
drivers/main.{c,h}: rename upsdrv_shutdown_default() => upsdrv_shutdo…
jimklimov Nov 19, 2024
00b291a
drivers/main.{c,h}: call upsdrv_shutdown_sdcommands_or_default() not …
jimklimov Nov 19, 2024
25250b0
drivers/main.{c,h}, drivers/dstate.c: introduce main_instcmd_fallback…
jimklimov Nov 19, 2024
17cf2da
drivers/main.{c,h}: introduce MAX_SDCOMMANDS_DEPTH for do_loop_shutdo…
jimklimov Nov 19, 2024
a94bc83
drivers/main.c: update some comments [#2670]
jimklimov Nov 19, 2024
be0a35a
drivers/*.c: simplify upsdrv_shutdown() back, as only "shutdown.defau…
jimklimov Nov 19, 2024
d0b42c4
drivers/main.c: move do_forceshutdown handling to be after upsdrv_ini…
jimklimov Nov 19, 2024
fbef5c5
Revert "drivers/main.{c,h}, drivers/dstate.c: introduce main_instcmd_…
jimklimov Nov 19, 2024
1d92ded
drivers/main.c: do_loop_shutdown_commands(): handle "shutdown.default…
jimklimov Nov 19, 2024
decb643
Merge branch 'master' into issue-2670
jimklimov Nov 30, 2024
edde0c3
Merge branch 'master' into issue-2670
jimklimov Dec 1, 2024
a480b29
Merge branch 'master' into issue-2670
jimklimov Dec 2, 2024
2c7d98b
drivers/dstate.c: revise logging of "Got INSTCMD, but driver lacks a …
jimklimov Dec 2, 2024
2072d83
data/cmdvartab: document CMDDESC shutdown.default [#2686]
jimklimov Dec 2, 2024
aaf254d
clients/ups{rw,cmd}.c: when reporting "OK" without "TRACKING", issue …
jimklimov Dec 2, 2024
35edb4f
clients/ups{rw,cmd}.c: enable use of NUT_DEBUG_LEVEL envvar
jimklimov Dec 2, 2024
a9b75b1
drivers/upsdrvquery.c, NEWS.adoc: upsdrvquery_read_timeout(): fix pri…
jimklimov Dec 2, 2024
08efbcd
Merge branch 'master' into issue-2670
jimklimov Dec 4, 2024
b804bf8
Merge branch 'master' into issue-2670
jimklimov Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ https://github.com/networkupstools/nut/milestone/11
a `*_s()` variant was available was not handled correctly. [PR #2583]
* A recently introduced `allow_killpower` did not actually work as an
`ups.conf` flag (only as a protocol command). [issue #2605, PR #2606]
* The ability of two copies of the driver program to talk to each other
with `upsdrvquery.c` code was not complete for the case of indefinite
`select()` wait timeout. Now `upsdrvquery_read_timeout()` fixed private
use of `struct timeval={-1,-1}` as a trigger to `select(..., NULL)`,
as logged in one part of code and not handled in the other, for the
indefinite wait [#1922, #2392, #2686, #2670]

- development iterations of NUT should now identify with not only the semantic
version of a preceding release, but with git-derived information about the
Expand Down Expand Up @@ -339,6 +345,24 @@ during a NUT build.
for `bcmxcp_usb`, `richcomm_usb` and `nutdrv_atcl_usb` drivers for now
[#1763, #1764, #1768, #2580]

- all drivers should now support the optional `sdcommands` setting with
a site-local list of instant commands to handle `upsdrv_shutdown()`,
which may be useful in cases when the driver's built-in commands
(or their order) do not meet the goals of particular NUT deployment.
This can also help with shutdown endgame testing, using a mock command like
starting the beeper (where supported) to verify that the UPS communications
happen as expected, without compromising the load connected to the UPS.
+
Also defined `EF_EXIT_SUCCESS` and `EF_EXIT_FAILURE` in `include/common.h`
to avoid magic numbers in code like `set_exit_flag(-2)`, and revised whether
it is getting set at all in "killpower" vs. other cases, based on new
`handling_upsdrv_shutdown` internal flag.
+
NOTE: during this overhaul, many older drivers got their first ever supported
INSTCMD such as `shutdown.return`, `shutdown.stayoff` or `load.off`. Default
logic that was previously the content of `upsdrv_shutdown()` methods was often
relocated into new `shutdown.default` INSTCMD definitions. [#2670]

- common code:
* introduced a `NUT_DEBUG_SYSLOG` environment variable to tweak activation
of syslog message emission (and related detachment of `stderr` when
Expand Down
18 changes: 16 additions & 2 deletions clients/upscmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ static void do_cmd(char **argv, const int argc)
) {
/* reply as usual */
fprintf(stderr, "%s\n", buf);
upsdebugx(1, "%s: 'OK' only means the NUT data server accepted the request as valid, "
"but as we did not wait for result, we do not know if it was handled in fact.",
__func__);
return;
}

Expand Down Expand Up @@ -282,9 +285,20 @@ int main(int argc, char **argv)
uint16_t port;
ssize_t ret;
int have_un = 0, have_pw = 0, cmdlist = 0;
char buf[SMALLBUF * 2], username[SMALLBUF], password[SMALLBUF];
char buf[SMALLBUF * 2], username[SMALLBUF], password[SMALLBUF], *s = NULL;
const char *prog = xbasename(argv[0]);

/* NOTE: Caller must `export NUT_DEBUG_LEVEL` to see debugs for upsc
* and NUT methods called from it. This line aims to just initialize
* the subsystem, and set initial timestamp. Debugging the client is
* primarily of use to developers, so is not exposed via `-D` args.
*/
s = getenv("NUT_DEBUG_LEVEL");
if (s && str_to_int(s, &i, 10) && i > 0) {
nut_debug_level = i;
}
upsdebugx(1, "Starting NUT client: %s", prog);

while ((i = getopt(argc, argv, "+lhu:p:t:wV")) != -1) {

switch (i)
Expand Down Expand Up @@ -459,6 +473,6 @@ int main(int argc, char **argv)
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
#if (defined NUT_PLATFORM_AIX)
void do_upsconf_args(char *upsname, char *var, char *val) {
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
}
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
18 changes: 16 additions & 2 deletions clients/upsrw.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ static void do_set(const char *varname, const char *newval)
) {
/* reply as usual */
fprintf(stderr, "%s\n", buf);
upsdebugx(1, "%s: 'OK' only means the NUT data server accepted the request as valid, "
"but as we did not wait for result, we do not know if it was handled in fact.",
__func__);
return;
}

Expand Down Expand Up @@ -641,7 +644,18 @@ int main(int argc, char **argv)
int i;
uint16_t port;
const char *prog = xbasename(argv[0]);
char *password = NULL, *username = NULL, *setvar = NULL;
char *password = NULL, *username = NULL, *setvar = NULL, *s = NULL;

/* NOTE: Caller must `export NUT_DEBUG_LEVEL` to see debugs for upsc
* and NUT methods called from it. This line aims to just initialize
* the subsystem, and set initial timestamp. Debugging the client is
* primarily of use to developers, so is not exposed via `-D` args.
*/
s = getenv("NUT_DEBUG_LEVEL");
if (s && str_to_int(s, &i, 10) && i > 0) {
nut_debug_level = i;
}
upsdebugx(1, "Starting NUT client: %s", prog);

while ((i = getopt(argc, argv, "+hls:p:t:u:wV")) != -1) {
switch (i)
Expand Down Expand Up @@ -717,6 +731,6 @@ int main(int argc, char **argv)
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
#if (defined NUT_PLATFORM_AIX)
void do_upsconf_args(char *upsname, char *var, char *val) {
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
}
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
6 changes: 6 additions & 0 deletions conf/ups.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ maxretry = 3
#
# The default value for this parameter is 0.
#
# sdcommands: OPTIONAL. Comma-separated list of instant command name(s)
# to send to the UPS when you request its shutdown. For more
# details about relevant use-cases see the ups.conf manual page.
#
# The default value is built into each driver (where supported).
#
# desc: optional, to keep a note of the UPS purpose, location, etc.
#
# nolock: optional, and not recommended for use in this file.
Expand Down
1 change: 1 addition & 0 deletions data/cmdvartab
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ CMDDESC driver.reload-or-exit "Reload running driver configuration from the file

CMDDESC load.off "Turn off the load immediately"
CMDDESC load.on "Turn on the load immediately"
CMDDESC shutdown.default "Run the driver-defined UPS shutdown sequence (as opposed to user-configured 'sdcommands')"
CMDDESC shutdown.return "Turn off the load and return when power is back"
CMDDESC shutdown.stayoff "Turn off the load and remain off"
CMDDESC shutdown.stop "Stop a shutdown in progress"
Expand Down
25 changes: 25 additions & 0 deletions docs/man/ups.conf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,31 @@ set this to -1.
+
The default value for this parameter is 0.

*sdcommands*::

Optional. Comma-separated list of instant command name(s) to send to
the UPS when you request its shutdown.
+
Default logic is built into each driver (where supported) and can be
referenced here as the `shutdown.default` value.
+
The primary use-case is for devices whose drivers "natively" support
trying several commands, but the built-in order of those calls a
command that is mis-handled by the specific device model (so the
handling is reported as successful and the loop stops, but nothing
happens as far as the load power-down is concerned).
+
Another use-case is differentiation of automated power-off scenarios
where the UPS and its load should stay "OFF" (e.g. by building emergency
power-off) vs. those where the load should return to work automatically
when it is safe to do so. NOTE: This would *currently* need editing of
`ups.conf` for such cases before `nutshutdown` sees the file; but could
be better automated in future NUT releases.
+
NOTE: User-provided commands may be something other than actual shutdown,
e.g. a beeper to test that the INSTCMD happened such and when expected,
and the device was contacted, without impacting the load fed by the UPS.

*allow_killpower*::
Optional. This allows you to request `driver.killpower` instant command,
to immediately call the driver-specific default implementation of
Expand Down
7 changes: 4 additions & 3 deletions docs/new-drivers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,10 @@ process.
This method should not directly `exit()` the driver program (neither
should it call `fatalx()` nor `fatal_with_errno()` methods). It can
`upslogx(LOG_ERR, ...)` or `upslog_with_errno(LOG_ERR, ...)`, and then
`set_exit_flag(N)` if required (`-1` for `EXIT_FAILURE` and `-2` for
`EXIT_SUCCESS` which would be handled in the standard driver loop or
`forceshutdown()` method of `main.c`).
`set_exit_flag(N)` if required, using values `EF_EXIT_FAILURE` (`-1`)
for eventual `exit(EXIT_FAILURE)` and `EF_EXIT_SUCCESS` (`-2`) for
`exit(EXIT_SUCCESS)`, which would be handled in the standard driver
loop or in `forceshutdown()` method of `main.c`.

Data types
----------
Expand Down
7 changes: 7 additions & 0 deletions docs/nut-names.txt
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,13 @@ Instant commands
| load.on | Turn on the load immediately
| load.off.delay | Turn off the load possibly after a delay
| load.on.delay | Turn on the load possibly after a delay
| shutdown.default | Run default driver-defined (device-specific)
routine, primarily intended for emergency
poweroff performed as part of FSD handling;
often an alias to other `shutdown.*` and/or
`load.off` operations or a chain to try
several of those. See also `sdcommands` in
common driver options.
| shutdown.return | Turn off the load possibly after a delay
and return when power is back
| shutdown.stayoff | Turn off the load possibly after a delay
Expand Down
5 changes: 4 additions & 1 deletion docs/nut.dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 3260 utf-8
personal_ws-1.1 en 3263 utf-8
AAC
AAS
ABI
Expand Down Expand Up @@ -2765,6 +2765,7 @@ screenshots
scriptname
sd
sdcmd
sdcommands
sddelay
sdk
sdl
Expand Down Expand Up @@ -2989,6 +2990,7 @@ timehead
timername
timestamp
timeticks
timeval
tios
tmp
tmpfiles
Expand Down Expand Up @@ -3087,6 +3089,7 @@ upsdebugx
upsdev
upsdrv
upsdrvctl
upsdrvquery
upsdrvsvcctl
upserror
upsfetch
Expand Down
88 changes: 60 additions & 28 deletions drivers/adelsystem_cbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <timehead.h>

#define DRIVER_NAME "NUT ADELSYSTEM DC-UPS CB/CBI driver"
#define DRIVER_VERSION "0.03"
#define DRIVER_VERSION "0.04"

/* variables */
static modbus_t *mbctx = NULL; /* modbus memory context */
Expand All @@ -49,7 +49,6 @@ static uint32_t mod_resp_to_us = MODRESP_TIMEOUT_us; /* set the modbus response
static uint32_t mod_byte_to_s = MODBYTE_TIMEOUT_s; /* set the modbus byte time out (us) */
static uint32_t mod_byte_to_us = MODBYTE_TIMEOUT_us; /* set the modbus byte time out (us) */


/* initialize alarm structs */
void alrminit(void);

Expand Down Expand Up @@ -193,6 +192,11 @@ void upsdrv_initinfo(void)
/* register instant commands */
dstate_addcmd("load.off");

/* FIXME: Check with the device what this instcmd
* (nee upsdrv_shutdown() contents) actually does!
*/
dstate_addcmd("shutdown.stayoff");

/* set callback for instant commands */
upsh.instcmd = upscmd;
}
Expand Down Expand Up @@ -464,33 +468,24 @@ void upsdrv_updateinfo(void)
/* shutdown UPS */
void upsdrv_shutdown(void)
{
int rval;
int cnt = FSD_REPEAT_CNT; /* shutdown repeat counter */
struct timeval start;
long etime;

/* retry sending shutdown command on error */
while ((rval = upscmd("load.off", NULL)) != STAT_INSTCMD_HANDLED && cnt > 0) {
rval = gettimeofday(&start, NULL);
if (rval < 0) {
upslog_with_errno(LOG_ERR, "upscmd: gettimeofday");
}
/* Only implement "shutdown.default"; do not invoke
* general handling of other `sdcommands` here */

/* wait for an increasing time interval before sending shutdown command */
while ((etime = time_elapsed(&start)) < ( FSD_REPEAT_INTRV / cnt));
upsdebugx(2, "ERROR: load.off failed, wait for %lims, retries left: %d\n", etime, cnt - 1);
cnt--;
}
switch (rval) {
case STAT_INSTCMD_FAILED:
case STAT_INSTCMD_INVALID:
fatalx(EXIT_FAILURE, "shutdown failed");
case STAT_INSTCMD_UNKNOWN:
fatalx(EXIT_FAILURE, "shutdown not supported");
default:
break;
}
upslogx(LOG_INFO, "shutdown command executed");
/*
* WARNING: When using RTU TCP, this driver will probably
* never support shutdowns properly, except on some systems:
* In order to be of any use, the driver should be called
* near the end of the system halt script (or a service
* management framework's equivalent, if any). By that
* time we, in all likelyhood, won't have basic network
* capabilities anymore, so we could never send this
* command to the UPS. This is not an error, but rather
* a limitation (on some platforms) of the interface/media
* used for these devices.
*/
int ret = do_loop_shutdown_commands("shutdown.stayoff", NULL);
if (handling_upsdrv_shutdown > 0)
set_exit_flag(ret == STAT_INSTCMD_HANDLED ? EF_EXIT_SUCCESS : EF_EXIT_FAILURE);
}

/* print driver usage info */
Expand Down Expand Up @@ -832,6 +827,43 @@ int upscmd(const char *cmd, const char *arg)
upsdebugx(2, "load.off: addr: 0x%x, data: %d", regs[FSD].xaddr, data);
rval = STAT_INSTCMD_HANDLED;
}
} else if (!strcasecmp(cmd, "shutdown.stayoff")) {
/* FIXME: Which one is this actually -
* "shutdown.stayoff" or "shutdown.return"? */
int cnt = FSD_REPEAT_CNT; /* shutdown repeat counter */
struct timeval start;
long etime;

/* retry sending shutdown command on error */
while ((rval = upscmd("load.off", NULL)) != STAT_INSTCMD_HANDLED && cnt > 0) {
rval = gettimeofday(&start, NULL);
if (rval < 0) {
upslog_with_errno(LOG_ERR, "upscmd: gettimeofday");
}

/* wait for an increasing time interval before sending shutdown command */
while ((etime = time_elapsed(&start)) < ( FSD_REPEAT_INTRV / cnt));
upsdebugx(2, "ERROR: load.off failed, wait for %lims, retries left: %d\n", etime, cnt - 1);
cnt--;
}
switch (rval) {
case STAT_INSTCMD_FAILED:
case STAT_INSTCMD_INVALID:
upslog_with_errno(LOG_ERR, "instcmd: %s failed", cmd);
if (handling_upsdrv_shutdown > 0)
set_exit_flag(EF_EXIT_FAILURE);
break;
case STAT_INSTCMD_UNKNOWN:
upslog_with_errno(LOG_ERR, "instcmd: %s not supported", cmd);
if (handling_upsdrv_shutdown > 0)
set_exit_flag(EF_EXIT_FAILURE);
break;
default:
upslogx(LOG_INFO, "shutdown command executed");
if (handling_upsdrv_shutdown > 0)
set_exit_flag(EF_EXIT_SUCCESS);
break;
}
} else {
upslogx(LOG_NOTICE, "instcmd: unknown command [%s] [%s]", cmd, arg);
rval = STAT_INSTCMD_UNKNOWN;
Expand Down
8 changes: 6 additions & 2 deletions drivers/al175.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ typedef uint8_t byte_t;


#define DRIVER_NAME "Eltek AL175/COMLI driver"
#define DRIVER_VERSION "0.15"
#define DRIVER_VERSION "0.16"

/* driver description structure */
upsdrv_info_t upsdrv_info = {
Expand Down Expand Up @@ -1267,6 +1267,9 @@ void upsdrv_updateinfo(void)

void upsdrv_shutdown(void)
{
/* Only implement "shutdown.default"; do not invoke
* general handling of other `sdcommands` here */

/* TODO use TOGGLE_PRS_ONOFF for shutdown */

/* tell the UPS to shut down, then return - DO NOT SLEEP HERE */
Expand All @@ -1276,7 +1279,8 @@ void upsdrv_shutdown(void)

/* replace with a proper shutdown function */
upslogx(LOG_ERR, "shutdown not supported");
set_exit_flag(-1);
if (handling_upsdrv_shutdown > 0)
set_exit_flag(EF_EXIT_FAILURE);

/* you may have to check the line status since the commands
for toggling power are frequently different for OL vs. OB */
Expand Down
Loading
Loading