4 * Functions for SmartUPS operations
8 * Copyright (C) 2001-2004 Kern Sibbald
9 * Copyright (C) 1996-99 Andre M. Hedrick <andre@suse.com>
10 * Copyright (C) 1999-2001 Riccardo Facchetti <riccardo@apcupsd.org>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General
14 * Public License as published by the Free Software Foundation.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public
22 * License along with this program; if not, write to the Free
23 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 int apcsmart_ups_kill_power(UPSINFO
*ups
)
32 char response
[32] = {0};
33 int shutdown_delay
= apcsmart_ups_get_shutdown_delay(ups
);
35 // Ask for soft shutdown
38 // Check whether the UPS has acknowledged the power-off command.
39 // The command only succeeds if UPS was on battery.
41 getline(response
, sizeof response
, ups
);
42 if (strcmp(response
, "OK") == 0 || (strcmp(response
, "*") == 0))
45 // 'S' command failed, most likely because utility power was restored.
46 // We still need to power cycle the UPS however since the OS has been
47 // shut down already. We will issue the shutdown-and-return command
48 // '@000' which works even if UPS is online.
50 // Experiments show that the UPS needs delays between chars
51 // to accept this command. Old code is written to send 2 zeros
52 // first, check for a response, and then send a third zero if
53 // command needs it. I've never seen an UPS that needs only 2 zeros
54 // but apparently someone did, so code is preserved.
56 writechar('@', ups
); /* Shutdown now, try two 0s first */
63 getline(response
, sizeof(response
), ups
);
64 if ((strcmp(response
, "OK") == 0) || (strcmp(response
, "*") == 0))
70 getline(response
, sizeof(response
), ups
);
71 if ((strcmp(response
, "OK") == 0) || (strcmp(response
, "*") == 0))
74 // Both shutdown techniques failed. We have one more we can try, but
75 // UPS will power off and stay off in this case.
76 return apcsmart_ups_shutdown_with_delay(ups
, shutdown_delay
);
79 // Shutdown command was accepted
80 apcsmart_ups_warn_shutdown(ups
, shutdown_delay
);
84 int apcsmart_ups_shutdown(UPSINFO
*ups
)
86 return apcsmart_ups_shutdown_with_delay(ups
, apcsmart_ups_get_shutdown_delay(ups
));
89 int apcsmart_ups_shutdown_with_delay(UPSINFO
*ups
, int shutdown_delay
)
96 * This method should turn the UPS off completely according to this article:
97 * http://nam-en.apc.com/cgi-bin/nam_en.cfg/php/enduser/std_adp.php?p_faqid=604
103 getline(response
, sizeof response
, ups
);
104 if (strcmp(response
, "*") != 0 && strcmp(response
, "OK") != 0) {
105 log_event(ups
, LOG_WARNING
, "Failed to issue shutdown command!\n");
109 apcsmart_ups_warn_shutdown(ups
, shutdown_delay
);
113 void apcsmart_ups_warn_shutdown(UPSINFO
*ups
, int shutdown_delay
)
115 if (shutdown_delay
> 0) {
116 log_event(ups
, LOG_WARNING
,
117 "UPS will power off after %d seconds ...\n", shutdown_delay
);
119 log_event(ups
, LOG_WARNING
,
120 "UPS will power off after the configured delay ...\n");
122 log_event(ups
, LOG_WARNING
,
123 "Please power off your UPS before rebooting your computer ...\n");
126 int apcsmart_ups_get_shutdown_delay(UPSINFO
*ups
)
130 writechar(ups
->UPS_Cmd
[CI_DSHUTD
], ups
);
131 getline(response
, sizeof(response
), ups
);
132 return (int)atof(response
);
135 int apcsmart_ups_check_state(UPSINFO
*ups
)
137 return getline(NULL
, 0, ups
) == SUCCESS
? 1 : 0;