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

« back to all changes in this revision

Viewing changes to models/cyberpower.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Quette
  • Date: 2004-05-28 13:10:01 UTC
  • mto: (16.1.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040528131001-yj2m9qcez4ya2w14
Tags: upstream-1.4.2
ImportĀ upstreamĀ versionĀ 1.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* cyberpower.c - Network UPS Tools driver for Cyber Power Systems units
2
 
 
3
 
   Copyright (C) 2001  Russell Kroll <rkroll@exploits.org>
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., 675 Mass Ave, Cambridge, MA 02139, USA.              
18
 
*/
19
 
 
20
 
#include "main.h"
21
 
 
22
 
#include <sys/ioctl.h>
23
 
#include <sys/termios.h>
24
 
 
25
 
/* adjust bizarre UPS data to observed voltage data */
26
 
int voltconvert(unsigned char in)
27
 
{
28
 
        int v_end[43] = { 36, 51, 55, 60, 65, 70, 75, 80, 85, 91, 98, 103, 108, 113, 118, 123, 128, 133, 138, 143, 148, 153, 158, 163, 168, 173, 178, 183, 188, 193, 198, 203, 208, 213, 218, 223, 228, 233, 238, 243, 248, 253, 255 };
29
 
        int v_adj[43] = {  3,  4,  5,  4,  3,  2,  1,  0, -1, -2, -3,  -4,  -5,  -6,  -7,  -8,  -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -32, -33, -34, -35 };
30
 
        int     i;
31
 
 
32
 
        if (in < 27)
33
 
                return 0;
34
 
 
35
 
        for (i = 0; i < 19; i++) { 
36
 
                if (in <= v_end[i]) {
37
 
                        return (in + v_adj[i]);
38
 
                }
39
 
        }
40
 
 
41
 
        return 0;
42
 
}
43
 
 
44
 
/* map UPS data to realistic percentages */
45
 
int battconvert(unsigned char in)
46
 
{
47
 
        int b_val[26] = {0, 1, 1, 2, 3, 4, 6, 8, 10, 12, 15, 18, 22, 26, 30, 35, 40, 46, 52, 58, 66, 73, 81, 88, 99, 100 }; /* XXX - for load of 0 */
48
 
 
49
 
        if (in > 185)
50
 
                return 100;
51
 
 
52
 
        if (in < 160)
53
 
                return 0;
54
 
 
55
 
        return (b_val[in - 160]);
56
 
}
57
 
 
58
 
/* more wacky mapping - get the picture yet? */
59
 
 
60
 
struct {
61
 
        int     st;
62
 
        int     end;
63
 
        int     sz;
64
 
        int     base;
65
 
}       temptab[] =
66
 
{
67
 
        {   0,  39, 5,  0 },
68
 
        {  40,  43, 4,  8 }, 
69
 
        {  44,  78, 5,  9 },
70
 
        {  79,  82, 4, 16 },
71
 
        {  83, 117, 5, 17 },
72
 
        { 118, 121, 4, 24 },
73
 
        { 122, 133, 3, 25 },
74
 
        { 134, 135, 2, 29 },
75
 
        { 136, 143, 4, 30 },
76
 
        { 144, 146, 3, 32 },
77
 
        { 147, 150, 4, 33 },
78
 
        { 151, 156, 3, 34 },
79
 
        { 157, 164, 2, 36 },
80
 
        { 165, 170, 3, 40 },
81
 
        { 171, 172, 2, 42 },
82
 
        { 173, 175, 3, 43 },
83
 
        { 176, 183, 2, 44 },
84
 
        { 184, 184, 1, 48 },
85
 
        { 185, 188, 2, 49 },
86
 
        { 189, 190, 2, 51 },
87
 
        { 191, 191, 1, 52 },
88
 
        { 192, 193, 2, 53 },
89
 
        { 194, 194, 1, 54 },
90
 
        { 195, 196, 2, 55 },
91
 
        { 197, 197, 1, 56 },
92
 
        { 198, 199, 2, 57 },
93
 
        { 200, 200, 1, 58 },
94
 
        { 201, 202, 2, 59 },
95
 
        { 203, 203, 1, 60 },
96
 
        { 204, 205, 2, 61 },
97
 
        { 206, 206, 1, 62 },
98
 
        { 207, 208, 2, 63 },
99
 
        { 209, 209, 1, 64 },
100
 
        { 210, 211, 2, 65 },
101
 
        { 212, 212, 1, 66 },
102
 
        { 213, 213, 1, 67 },
103
 
        { 214, 214, 1, 68 },
104
 
        { 215, 215, 1, 69 },
105
 
        { 216, 255, 40, 70 },
106
 
        {   0,   0, 0,  0 },
107
 
};
108
 
 
109
 
float tempconvert(unsigned char in)
110
 
{
111
 
        int     i, j, found, count;
112
 
 
113
 
        found = -1;
114
 
        for (i = 0; temptab[i].sz != 0; i++)
115
 
                if ((temptab[i].st <= in) && (temptab[i].end >= in))
116
 
                        found = i;
117
 
 
118
 
        if (found == -1) {
119
 
                upslogx(LOG_ERR, "tempconvert: unhandled value %d", in);
120
 
                return 0;
121
 
        }
122
 
 
123
 
        count = temptab[found].end - temptab[found].st + 1;
124
 
 
125
 
        for (i = 0; i < count; i++) {
126
 
                j = temptab[found].st + (i * temptab[found].sz);
127
 
 
128
 
                if ((in - j) < temptab[found].sz) {
129
 
                        return ((float)((in - j) / temptab[found].sz) + 
130
 
                                temptab[found].base + i);
131
 
                }
132
 
        }
133
 
 
134
 
        upslogx(LOG_ERR, "tempconvert: fell through with %d", in);
135
 
        return 0;
136
 
}
137
 
 
138
 
void sendtoups(char ch)
139
 
{
140
 
        write(upsfd, &ch, 1);
141
 
        usleep(50000);
142
 
}
143
 
 
144
 
/* power down the attached load immediately */
145
 
void upsdrv_shutdown(void)
146
 
{
147
 
        /* XXX */
148
 
}
149
 
 
150
 
void upsdrv_updateinfo(void)
151
 
{
152
 
        int     ret, count;
153
 
        char    ch, buf[SMALLBUF], stbuf[SMALLBUF];
154
 
 
155
 
        sendtoups('D');
156
 
        sendtoups(13);
157
 
 
158
 
        count = 0;
159
 
 
160
 
        memset(buf, '\0', sizeof(buf));
161
 
        while (count < 14) {
162
 
                ret = read(upsfd, &ch, 1);
163
 
                buf[count++] = ch;
164
 
        }
165
 
 
166
 
        if (buf[0] != '#') {
167
 
                upslogx(LOG_ERR, "Invalid start char 0x%02x", buf[0] & 0xff);
168
 
                return;
169
 
        }
170
 
 
171
 
        if ((buf[4] != 46) || (buf[8] != 46)) {
172
 
                upslogx(LOG_ERR, "Invalid separator in response");
173
 
                return;
174
 
        }
175
 
 
176
 
        setinfo(INFO_UPSTEMP, "%2.1f", tempconvert(buf[6]));
177
 
        setinfo(INFO_BATTPCT, "%03d", battconvert(buf[5]));
178
 
        setinfo(INFO_LOADPCT, "%03d", (buf[3] & 0xff) * 2);
179
 
        setinfo(INFO_UTILITY, "%03d", voltconvert(buf[1]));
180
 
 
181
 
        memset(stbuf, '\0', sizeof(stbuf));
182
 
 
183
 
        if (buf[9] & 2)
184
 
                strcat(stbuf, "OFF ");
185
 
 
186
 
        if (buf[9] & 64)
187
 
                strcat(stbuf, "LB ");
188
 
 
189
 
        if (buf[9] & 128)
190
 
                strcat(stbuf, "OB ");
191
 
        else
192
 
                strcat(stbuf, "OL ");
193
 
 
194
 
        if (stbuf[strlen(stbuf)-1] == ' ')
195
 
                stbuf[strlen(stbuf)-1] = '\0';
196
 
 
197
 
        setinfo(INFO_STATUS, "%s", stbuf);
198
 
        writeinfo();
199
 
}
200
 
 
201
 
void instcmd(int auxcmd, int dlen, char *data)
202
 
{
203
 
        switch(auxcmd) {
204
 
                default:
205
 
                        upslogx(LOG_INFO, "instcmd: unknown type 0x%04x",
206
 
                                auxcmd);
207
 
        }
208
 
}
209
 
 
210
 
/* install pointers to functions for msg handlers called from msgparse */
211
 
void setuphandlers(void)
212
 
{
213
 
        upsh.instcmd = instcmd;
214
 
}
215
 
 
216
 
void upsdrv_banner(void)
217
 
{
218
 
        printf("Network UPS Tools - CyberPower driver 0.01 (%s)\n", UPS_VERSION);
219
 
 
220
 
        experimental_driver = 1;
221
 
}
222
 
 
223
 
void upsdrv_help(void)
224
 
{
225
 
}
226
 
 
227
 
void upsdrv_makevartable(void)
228
 
{
229
 
}
230
 
 
231
 
/* prep the serial port */
232
 
void upsdrv_initups(void)
233
 
{
234
 
        int dtr_bit = TIOCM_DTR;
235
 
        int rts_bit = TIOCM_RTS;
236
 
        struct termios tio;
237
 
 
238
 
        open_serial(device_path, B1200);
239
 
 
240
 
        /* dtr high, rts high */
241
 
        ioctl(upsfd, TIOCMBIS, &rts_bit);
242
 
        ioctl(upsfd, TIOCMBIS, &dtr_bit);
243
 
 
244
 
        tcgetattr(upsfd, &tio);
245
 
        tio.c_cflag = 0 | CS8 | CLOCAL | ~CRTSCTS | CREAD;
246
 
        cfmakeraw(&tio);
247
 
        tio.c_cflag &= ~(PARODD|CSTOPB|HUPCL|CRTSCTS);
248
 
 
249
 
        cfsetispeed(&tio, B1200);
250
 
        cfsetospeed(&tio, B1200);
251
 
        tcsetattr(upsfd, TCSANOW, &tio);
252
 
}
253
 
 
254
 
void getbaseinfo()
255
 
{
256
 
        addinfo(INFO_MODEL, "AVR700", 0, 0);    /* XXX */
257
 
        addinfo(INFO_UPSTEMP, "", 0, 0);
258
 
        addinfo(INFO_BATTPCT, "", 0, 0);
259
 
        addinfo(INFO_LOADPCT, "", 0, 0);
260
 
        addinfo(INFO_UTILITY, "", 0, 0);
261
 
        addinfo(INFO_STATUS, "", 0, 0);
262
 
 
263
 
        /* poll once to put in some good data */
264
 
        upsdrv_updateinfo();
265
 
}
266
 
 
267
 
void upsdrv_initinfo(void)
268
 
{
269
 
        /* XXX: probe */
270
 
 
271
 
#if 0
272
 
        res = init_communication();
273
 
        if (res == -1) {
274
 
                printf("Unable to detect a CyberPower UPS on port %s\n", 
275
 
                        device_path);
276
 
                printf("Check the cabling, port name or model name and try again\n");
277
 
                exit(1);
278
 
        }
279
 
#endif
280
 
 
281
 
        addinfo(INFO_MFR, "CyberPower", 0, 0);
282
 
 
283
 
        getbaseinfo();
284
 
 
285
 
        printf("Detected %s on %s\n", getdata(INFO_MODEL), device_path); 
286
 
 
287
 
        setuphandlers(); 
288
 
}
289
 
 
290
 
int upsdrv_infomax(void) { return 16; }