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

« back to all changes in this revision

Viewing changes to drivers/hp.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2005-07-20 19:48:50 UTC
  • mto: (16.1.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20050720194850-oo61wjr33rrx2mre
Tags: upstream-2.0.2
ImportĀ upstreamĀ versionĀ 2.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* hp.c - support for HP Powertrust UPS
2
 
 
3
 
   Copyright (C) 2002  Richard Muratti <rick@ccoz.com>
4
 
 
5
 
   This program is free software; you can redistribute it and/or modify
6
 
   it under the terms of the GNU General Public License as published by
7
 
   the Free Software Foundation; either version 2 of the License, or
8
 
   (at your option) any later version.
9
 
 
10
 
   This program is distributed in the hope that it will be useful,
11
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
   GNU General Public License for more details.
14
 
 
15
 
   You should have received a copy of the GNU General Public License
16
 
   along with this program; if not, write to the Free Software
17
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
 
*/
19
 
 
20
 
/*
21
 
I have two HP Powertrust units
22
 
A2997A 1800VA Rack Mount
23
 
A2941A  600VA Floor Standing
24
 
 
25
 
Here's what i have discovered about these units.
26
 
 
27
 
+--------+-----+------+------+
28
 
|Cables  | UPS | DB25 | DB9* |
29
 
|--------+-----+------+------+
30
 
|Receive |  1  |  3   |  3   |
31
 
|Transmit|  2  |  2   |  2   |
32
 
|Ground  |  9  |  7   |  5   |
33
 
|--------+-----+------+------+
34
 
 
35
 
*) Cable used for A2994A; RX and TX appear to be exchanged
36
 
 
37
 
Comms
38
 
1200N81
39
 
 
40
 
Commands
41
 
CAPS
42
 
        Online  Offline Comment
43
 
        
44
 
A       $       !       Status % Low Batt
45
 
B       066.7   066.7   Battery Voltage
46
 
C       027.0   027.0   Temp
47
 
D       ??      ??
48
 
E       ??      ??
49
 
F       050.0   050.0   Frequency
50
 
G       ??      ??
51
 
H       ??      ??
52
 
I       ??      ??      
53
 
G       ??      ??
54
 
K       >       <       KnnnKnnn Kill UPS after nnn seconds (ie dont restart)
55
 
L       233.0   000.0   Line Voltage
56
 
M       ??      ??
57
 
N       NM      NM      [CR] gives CM response
58
 
O       231.0   231.0   Output Voltage
59
 
P       ddd.d   ddd.d   unsupported/future values
60
 
Q       <       <       
61
 
R       ddd.d   ddd.d   unsupported/future values
62
 
S       <       >       SnnnSnnn Shutdown UPS after nnn is seconds
63
 
T       ??      ??
64
 
U       >       >       Self test 10 Sec
65
 
V       1.00    1.00    Firmware Version
66
 
W       HP^...  HP^...  ID String + Capablilities
67
 
X       >       >
68
 
Y       ??      ??
69
 
Z       >       <       ZnnnZnnn does something but what???
70
 
 
71
 
 
72
 
Notes:
73
 
On power up UPS will send '('
74
 
On power good UPS will send '$' ie after going off batt
75
 
On power fail UPS will send '!'
76
 
On low batt UPS will send '%'
77
 
 
78
 
It seems that they are sent only once
79
 
so its best to poll for them using 'A'
80
 
 
81
 
Shutdown/kill only work if UPS is on battery.
82
 
To force set UPS in test mode 'U' then issue
83
 
SnnnSnnn or KnnnKnnn
84
 
 
85
 
UPS sends ')' on successful shutdown
86
 
 
87
 
 
88
 
 
89
 
TODO:
90
 
What do P & R values represent.
91
 
What does ZnnnZnnn do.
92
 
What does N do.
93
 
 
94
 
 
95
 
if you can add to the above please feel fee to do so
96
 
but email me with any changes.
97
 
 
98
 
Cheers
99
 
Rick
100
 
*/
101
 
 
102
 
 
103
 
#include "main.h"
104
 
#include <sys/ioctl.h>
105
 
 
106
 
#define ENDCHAR 13
107
 
#define IGNCHARS  "\n"
108
 
 
109
 
#define NUM_MODELS  sizeof(modeltab)/sizeof(modeltab[0])
110
 
#define SD_RESTART  0
111
 
#define SD_HALT     1
112
 
 
113
 
 
114
 
/* used external variables */
115
 
extern int debug_level;      /* debug level, set by "-D" in main.c */
116
 
extern int sddelay;          /* shutdown delay, set by "-d $delay" in main.c */
117
 
extern int do_forceshutdown; /* shutdown delay, set by "-k" in main.c */
118
 
 
119
 
 
120
 
 
121
 
struct {
122
 
        char    *model;
123
 
        char    *id_string;
124
 
}       modeltab[] =
125
 
{
126
 
        { "A2997A","HP^V230^F50^R01800^O230^P1"},
127
 
        { "A2941A","HP^V230^F50^R00600^O230^P1"},
128
 
        { "A2994A","HP^V230^F50^R01300^O230^P1"}
129
 
        /* 
130
 
         Add More Models Here
131
 
         Some Models may have more than one id string
132
 
         ie 110 volt countries
133
 
        */
134
 
};
135
 
 
136
 
int     sdtype;
137
 
 
138
 
 
139
 
/* TODO: roll this into upscommon ala bestups */
140
 
void sendstring(char * string, int len, int delay)
141
 
{
142
 
        int     i;
143
 
 
144
 
        for (i=0; (i<len); i++) {
145
 
                upssendchar(string[i]);
146
 
                usleep(delay);
147
 
        }
148
 
}
149
 
 
150
 
 
151
 
void instcmd (int auxcmd, int dlen, char *data)
152
 
{
153
 
 
154
 
        /* TODO: reply to upsd? */
155
 
 
156
 
        switch (auxcmd) {
157
 
                /* Special cases */
158
 
                case CMD_BTEST0:        /* Stop Battery Test*/
159
 
                        
160
 
                        break;
161
 
                case CMD_BTEST1:        /* Start Battery Test*/
162
 
                        upssendchar ('U'); 
163
 
                        break;
164
 
                default:
165
 
                        upslogx(LOG_INFO,"instcmd: unknown or unimplemented type 0x%04x\n",auxcmd);
166
 
                        return;
167
 
        }
168
 
}
169
 
 
170
 
 
171
 
 
172
 
void setuphandlers()
173
 
{
174
 
        upsh.instcmd = instcmd;
175
 
}
176
 
 
177
 
 
178
 
 
179
 
void init_serial(void)
180
 
{
181
 
        int     clr_bit = TIOCM_DTR | TIOCM_RTS;
182
 
        ioctl(upsfd, TIOCMBIC, &clr_bit);
183
 
}
184
 
 
185
 
/* replacement for the old "installinfo" hack-job */
186
 
static void poll_data(const char *var, char reqchar)
187
 
{
188
 
        char    tmp[SMALLBUF];
189
 
 
190
 
        upssendchar(reqchar);
191
 
        upsrecv(tmp, sizeof(tmp), ENDCHAR, IGNCHARS);
192
 
 
193
 
        dstate_setinfo(var, "%s", tmp);
194
 
}
195
 
 
196
 
void ups_model (void)
197
 
{
198
 
        int i;
199
 
 
200
 
        /* Get Ident String     */
201
 
        poll_data("ups.id", 'W');
202
 
 
203
 
 
204
 
        /* Lookup UPS Model */
205
 
        for (i=0; i < NUM_MODELS;i++) {
206
 
           if (strncmp (dstate_getinfo("ups.id"),modeltab[i].id_string,strlen(modeltab[i].id_string)) == 0)
207
 
              dstate_setinfo("ups.model", "%s", modeltab[i].model);
208
 
        }
209
 
}
210
 
 
211
 
void upsdrv_initinfo(void)
212
 
{
213
 
        dstate_setinfo("ups.mfr", "HP");
214
 
 
215
 
        dstate_addcmd("battery.test.start");
216
 
        dstate_addcmd("battery.test.stop");
217
 
        
218
 
        ups_model ();
219
 
 
220
 
        printf("Detected %s [%s] on %s\n", dstate_getinfo("ups.mfr"),
221
 
                dstate_getinfo("ups.model"), device_path);
222
 
 
223
 
        setuphandlers();
224
 
 
225
 
}
226
 
 
227
 
void upsdrv_updateinfo(void)
228
 
{
229
 
        unsigned char recBuf[10];
230
 
 
231
 
 
232
 
        poll_data("input.voltage", 'L');
233
 
        poll_data("output.voltage", 'O');
234
 
        poll_data("input.frequency", 'F');
235
 
        poll_data("ups.temperature", 'C');
236
 
        poll_data("battery.voltage", 'B');
237
 
 
238
 
        upssendchar ('A');
239
 
        upsrecv((char *)recBuf,sizeof(recBuf)-1,ENDCHAR,IGNCHARS);
240
 
 
241
 
        status_init();          
242
 
 
243
 
        switch (recBuf[0]) {
244
 
 
245
 
                case '%':               /* on battery, low battery */
246
 
                        status_set("LB");
247
 
 
248
 
                        /* FALLTHROUGH */
249
 
 
250
 
                case '!':               /* on battery */
251
 
                        status_set("OB");
252
 
                        break;
253
 
                
254
 
                case '$':               /* on line */
255
 
                        status_set("OL");
256
 
                        break;
257
 
 
258
 
                default:
259
 
                        upslogx(LOG_INFO,"unknown UPS status byte 0x%04x\n",
260
 
                                recBuf[0]);
261
 
 
262
 
                        return;         /* don't commit */
263
 
        }
264
 
 
265
 
        status_commit();
266
 
}
267
 
 
268
 
void upsdrv_shutdown(void)
269
 
{
270
 
        char  tmp [10];
271
 
 
272
 
 
273
 
        /* Put UPS in Self Test Mode */
274
 
        upssendchar ('U');
275
 
        upsrecvchars(tmp,1);
276
 
        usleep(100);
277
 
 
278
 
 
279
 
        /* Issue Shutdown/Kill Command */
280
 
        if (sdtype == SD_RESTART) {
281
 
           printf("UPS shutdown in '%d' seconds.\nUPS will RESTART on AC Power Good\n", sddelay);
282
 
           snprintf (tmp, sizeof(tmp), "S%03dS%03d",sddelay,sddelay);
283
 
        }else{
284
 
           printf("UPS shutdown in '%d' seconds.\nUPS will NOT RESTART on AC Power Good\n", sddelay);
285
 
           snprintf (tmp, sizeof(tmp), "K%03dK%03d",sddelay,sddelay);   
286
 
        }
287
 
                   
288
 
        sendstring (tmp,9,10);
289
 
}
290
 
 
291
 
void upsdrv_help(void)
292
 
{
293
 
        printf("\nShutdown types:\n");
294
 
        printf("  restart: UPS Will shutdown and will RESTART on AC Power Good (default)\n");
295
 
        printf("  halt:    UPS Will shutdown and will NOT RESTART on AC Power Good\n");
296
 
 
297
 
}
298
 
 
299
 
/* list flags and values that you want to receive via -x */
300
 
void upsdrv_makevartable(void)
301
 
{
302
 
        /* allow '-x xyzzy' */
303
 
        /* addvar(VAR_FLAG, "xyzzy", "Enable xyzzy mode"); */
304
 
 
305
 
        /* allow '-x foo=<some value>' */
306
 
        
307
 
        addvar(VAR_VALUE, "shutdown", "halt/<restart>");
308
 
}
309
 
 
310
 
void upsdrv_banner(void)
311
 
{
312
 
        printf("Network UPS Tools - HP Powertrust UPS driver 0.01 (%s)\n", UPS_VERSION);
313
 
}
314
 
 
315
 
void upsdrv_initups(void)
316
 
{
317
 
        /* this driver doesn't do sanity checks in upsdrv_updateinfo */
318
 
        broken_driver = 1;
319
 
        return;
320
 
 
321
 
        open_serial (device_path,B1200);
322
 
        init_serial();
323
 
        
324
 
        
325
 
         if (NULL == getval("shutdown"))
326
 
            sdtype = SD_RESTART;
327
 
         else
328
 
            if (strcmp (getval("shutdown"),"halt") == 0)
329
 
               sdtype = SD_HALT;
330
 
 
331
 
}
332
 
 
333
 
void upsdrv_cleanup(void)
334
 
{
335
 
}