UPS: apcupsd clean sources
[tomato.git] / release / src / router / apcupsd / src / drivers / apcsmart / smartoper.c
blobf63736c80dca8501e61f29225c266c17bc4dab1b
1 /*
2 * smartoper.c
4 * Functions for SmartUPS operations
5 */
7 /*
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,
24 * MA 02111-1307, USA.
27 #include "apc.h"
28 #include "apcsmart.h"
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
36 writechar('S', ups);
38 // Check whether the UPS has acknowledged the power-off command.
39 // The command only succeeds if UPS was on battery.
40 sleep(5);
41 getline(response, sizeof response, ups);
42 if (strcmp(response, "OK") == 0 || (strcmp(response, "*") == 0))
43 goto acked;
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 */
57 sleep(2);
58 writechar('0', ups);
59 sleep(2);
60 writechar('0', ups);
61 sleep(2);
63 getline(response, sizeof(response), ups);
64 if ((strcmp(response, "OK") == 0) || (strcmp(response, "*") == 0))
65 goto acked;
67 writechar('0', ups);
68 sleep(2);
70 getline(response, sizeof(response), ups);
71 if ((strcmp(response, "OK") == 0) || (strcmp(response, "*") == 0))
72 goto acked;
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);
78 acked:
79 // Shutdown command was accepted
80 apcsmart_ups_warn_shutdown(ups, shutdown_delay);
81 return 1;
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)
91 char response[32];
94 * K K command
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
100 writechar('K', ups);
101 sleep(2);
102 writechar('K', ups);
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");
106 return 0;
109 apcsmart_ups_warn_shutdown(ups, shutdown_delay);
110 return 1;
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);
118 } else {
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)
128 char response[32];
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;