1
/* cyberpower.c - Network UPS Tools driver for Cyber Power Systems units
3
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
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.
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.
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.
22
#include <sys/ioctl.h>
23
#include <sys/termios.h>
25
/* adjust bizarre UPS data to observed voltage data */
26
int voltconvert(unsigned char in)
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 };
35
for (i = 0; i < 19; i++) {
37
return (in + v_adj[i]);
44
/* map UPS data to realistic percentages */
45
int battconvert(unsigned char in)
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 */
55
return (b_val[in - 160]);
58
/* more wacky mapping - get the picture yet? */
105
{ 216, 255, 40, 70 },
109
float tempconvert(unsigned char in)
111
int i, j, found, count;
114
for (i = 0; temptab[i].sz != 0; i++)
115
if ((temptab[i].st <= in) && (temptab[i].end >= in))
119
upslogx(LOG_ERR, "tempconvert: unhandled value %d", in);
123
count = temptab[found].end - temptab[found].st + 1;
125
for (i = 0; i < count; i++) {
126
j = temptab[found].st + (i * temptab[found].sz);
128
if ((in - j) < temptab[found].sz) {
129
return ((float)((in - j) / temptab[found].sz) +
130
temptab[found].base + i);
134
upslogx(LOG_ERR, "tempconvert: fell through with %d", in);
138
void sendtoups(char ch)
140
write(upsfd, &ch, 1);
144
/* power down the attached load immediately */
145
void upsdrv_shutdown(void)
150
void upsdrv_updateinfo(void)
153
char ch, buf[SMALLBUF], stbuf[SMALLBUF];
160
memset(buf, '\0', sizeof(buf));
162
ret = read(upsfd, &ch, 1);
167
upslogx(LOG_ERR, "Invalid start char 0x%02x", buf[0] & 0xff);
171
if ((buf[4] != 46) || (buf[8] != 46)) {
172
upslogx(LOG_ERR, "Invalid separator in response");
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]));
181
memset(stbuf, '\0', sizeof(stbuf));
184
strcat(stbuf, "OFF ");
187
strcat(stbuf, "LB ");
190
strcat(stbuf, "OB ");
192
strcat(stbuf, "OL ");
194
if (stbuf[strlen(stbuf)-1] == ' ')
195
stbuf[strlen(stbuf)-1] = '\0';
197
setinfo(INFO_STATUS, "%s", stbuf);
201
void instcmd(int auxcmd, int dlen, char *data)
205
upslogx(LOG_INFO, "instcmd: unknown type 0x%04x",
210
/* install pointers to functions for msg handlers called from msgparse */
211
void setuphandlers(void)
213
upsh.instcmd = instcmd;
216
void upsdrv_banner(void)
218
printf("Network UPS Tools - CyberPower driver 0.01 (%s)\n", UPS_VERSION);
220
experimental_driver = 1;
223
void upsdrv_help(void)
227
void upsdrv_makevartable(void)
231
/* prep the serial port */
232
void upsdrv_initups(void)
234
int dtr_bit = TIOCM_DTR;
235
int rts_bit = TIOCM_RTS;
238
open_serial(device_path, B1200);
240
/* dtr high, rts high */
241
ioctl(upsfd, TIOCMBIS, &rts_bit);
242
ioctl(upsfd, TIOCMBIS, &dtr_bit);
244
tcgetattr(upsfd, &tio);
245
tio.c_cflag = 0 | CS8 | CLOCAL | ~CRTSCTS | CREAD;
247
tio.c_cflag &= ~(PARODD|CSTOPB|HUPCL|CRTSCTS);
249
cfsetispeed(&tio, B1200);
250
cfsetospeed(&tio, B1200);
251
tcsetattr(upsfd, TCSANOW, &tio);
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);
263
/* poll once to put in some good data */
267
void upsdrv_initinfo(void)
272
res = init_communication();
274
printf("Unable to detect a CyberPower UPS on port %s\n",
276
printf("Check the cabling, port name or model name and try again\n");
281
addinfo(INFO_MFR, "CyberPower", 0, 0);
285
printf("Detected %s on %s\n", getdata(INFO_MODEL), device_path);
290
int upsdrv_infomax(void) { return 16; }