]> git.pld-linux.org Git - packages/nut.git/blame - everups.c
- BR libusb-compat to make it work with libusb 1.0.0
[packages/nut.git] / everups.c
CommitLineData
003ccfa3 1/* everups.c - support for Ever UPS models
2
3 Copyright (C) 2003 Mikolaj Tutak <mtutak@eranet.pl>
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#include "main.h"
21#include <sys/ioctl.h>
22
23#define DEFAULT_SERIALNUMBER "Unknown"
24
25#define BATT_DISCHARGED_VOLT 100.0 /* battery completly discharged */
26#define BATT_MIN_OB_VOLTAGE 105.0 /* min. battery voltage for OB work - default */
27#define BATT_MAX_OB_VOLTAGE 125.0 /* 100% charged battery - OB */
28#define BATT_MAX_OFF_VOLT 134.0 /* 100% charged battery - OFF */
29#define BATT_MAX_OL_VOLT 140.0 /* 100% charged battery - OL*/
30
31#define EVER_SET_FLAGS 13
32#define EVER_SET_SBTIME 28
33
34#define EVER_GET_FLAGS 141
35#define EVER_GET_MODEL 173
36#define EVER_GET_STATUS 175
37#define EVER_GET_BATTV 189
38#define EVER_GET_LINEV 245
39
40#define EVER_FRAME_INIT 208
41
42#define EVER_FRAME_ACK 208
43#define EVER_FRAME_NACK 209
44
45#define EVER_FLAG_RESET 1 /* ??? */
46#define EVER_FLAG_SELFTEST 2
47#define EVER_FLAG_BEEPOFF 4
48#define EVER_FLAG_POWEROFF 8
49#define EVER_FLAG_SELFTESTFAIL 16 /* ??? */
50#define EVER_FLAG_5 32
51#define EVER_FLAG_6 64
52#define EVER_FLAG_7 128
53
54
55char *ever_serialnumber = DEFAULT_SERIALNUMBER;
56unsigned char ever_upstype = 0;
57unsigned char ever_debug = 0;
58unsigned int batt_min_ob_voltage = BATT_MIN_OB_VOLTAGE;
59
60/* used external variables */
61extern int sddelay; /* shutdown delay, set by "-d $delay" in main.c */
62extern int do_forceshutdown; /* shutdown delay, set by "-k" in main.c */
63
64int ever_initframe(int tries)
65{
66 int i;
67 unsigned char buffer[2];
68
69 for( i=0; i<tries ; i++ ) {
70 upssendchar( EVER_FRAME_INIT );
71 upsrecvchars( (char*)buffer, 1 );
72
73 if( buffer[0] == EVER_FRAME_ACK )
74 return 1;
75
76 if( buffer[0] == EVER_FRAME_NACK )
77 upsrecvchars( (char*)buffer, 2 );
78
79 /* tcflush( upsfd, TCIOFLUSH ); */
80 upsflushin(0, nut_debug_level, "");
81 usleep( 250000 );
82 };
83
84 /* tcflush( upsfd, TCIOFLUSH ); */
85 upsflushin(0, nut_debug_level, "");
86 upslogx( LOG_INFO, "everups: ever_initframe() failed (%i tries)", tries );
87 return 0;
88}
89
90int ever_initups()
91{
92 unsigned char tmp[2];
93
94 if( !ever_initframe(5) )
95 return 0;
96
97 upssendchar( EVER_FRAME_INIT );
98 upsrecvchars( (char*)tmp, 2 );
99 usleep( 250000 );
100
101 return 1;
102}
103
104int ever_getupstype()
105{
106 if( !ever_initframe(1) )
107 return 0;
108
109 upssendchar( EVER_GET_MODEL );
110 upsrecvchars( (char*)&ever_upstype, 1 );
111 return 1;
112}
113
114char *ever_getupsname()
115{
116 switch(ever_upstype)
117 {
118 case 67: return "NET 500-DPC";
119 case 68: return "NET 700-DPC";
120 case 69: return "NET 1000-DPC";
121 case 70: return "NET 1400-DPC";
122 case 71: return "NET 2200-DPC";
123
124 case 73: return "NET 700-DPC";
125 case 74: return "NET 1000-DPC";
126 case 75: return "NET 1400-DPC";
127 case 76: return "NET 500-DPC";
128
129 case 81: return "AP 450-PRO";
130 case 82: return "AP 650-PRO";
131
132 default: return "Unknown";
133 }
134}
135
136void ever_change_flags(unsigned char set_flags, unsigned char reset_flags)
137{
138 unsigned char ups_flags;
139
140 if ( !ever_initframe(2) )
141 return;
142
143 upssendchar( EVER_GET_FLAGS );
144 upsrecvchars( (char*)&ups_flags, 1 );
145
146 if ( !ever_initframe(1) )
147 return;
148
149 upssendchar( EVER_SET_FLAGS );
150 upssendchar( (ups_flags|set_flags)&(~reset_flags) );
151}
152
153void ever_beepon(void)
154{
155 ever_change_flags( 0, EVER_FLAG_BEEPOFF|EVER_FLAG_POWEROFF );
156}
157
158void ever_beepoff(void)
159{
160 ever_change_flags( EVER_FLAG_BEEPOFF, EVER_FLAG_POWEROFF );
161}
162
163void ever_poweroff(int delay)
164{
165 if ( !ever_initframe(2) )
166 return;
167
168 upssendchar( EVER_SET_SBTIME );
169 upssendchar( (char)((float)delay/1.28+0.5) ); /* (1*1.28) sec */
170
171 ever_change_flags( EVER_FLAG_POWEROFF, 0 );
172}
173
174void ever_poweron(void)
175{
176 ever_change_flags( EVER_FLAG_RESET, EVER_FLAG_POWEROFF );
177}
178
179void ever_autotest(void)
180{
181 ever_change_flags( EVER_FLAG_SELFTEST, EVER_FLAG_SELFTESTFAIL|EVER_FLAG_POWEROFF );
182}
183
184/* registered instant commands */
185void instcmd (int auxcmd, int dlen, char *data)
186{
187 switch (auxcmd) {
188 case CMD_BTEST1: /* start battery test */
189 ever_autotest();
190 break;
191 case CMD_OFF: /* power off load */
192 ever_poweroff(0);
193 break;
194 case CMD_ON: /* power on load */
195 ever_poweron();
196 break;
197 default:
198 upslogx( LOG_ERR, "instcmd: unknown type 0x%04x\n", auxcmd );
199 }
200}
201
202void setvar (int auxcmd, int dlen, char *data)
203{
204 switch (auxcmd) {
205 case INFO_LOWXFER:
206 break;
207
208 case INFO_HIGHXFER:
209 break;
210
211 case INFO_AUDIBLEALRM:
212 upslogx( LOG_ERR, "setvar: unknown type %i\n", dlen );
213 if( dlen == 3 && data[0]=='O' && data[1]=='F' && data[2]=='F' )
214 ever_beepoff();
215 else
216 ever_beepon();
217 break;
218
219 default:
220 upslogx( LOG_ERR, "setvar: unknown type 0x%04x\n", auxcmd );
221 }
222}
223
224void init_serial(void)
225{
226 int clr_bit = TIOCM_DTR | TIOCM_RTS;
227 ioctl( upsfd, TIOCMBIC, &clr_bit );
228}
229
230void upsdrv_updateinfo(void)
231{
232 int battery = 0;
233 int standby = 0;
234 char temp[VALSIZE];
235 unsigned char recBuf[2];
236 unsigned char ups_status;
237 unsigned char ups_flags;
238 unsigned int accuVoltage;
239 unsigned int lineVoltage;
240 double batteryCharge;
241
242 /****
243 Line status
244 175->UPS, UPS=HGFEDCBA
245 A=1 - battery
246 A=0 & C=1 - standby
247 ****/
248
249 if( !ever_initframe(2) )
250 return;
251
252 upssendchar( EVER_GET_STATUS );
253 upsrecvchars( (char*)&ups_status, 1 );
254
255 battery = ( (ups_status&5)==4 );
256 standby = ( (ups_status&1)==1 );
257
258 /****
259 Read UPS flags
260 ****/
261
262 if ( !ever_initframe(1) )
263 return;
264
265 upssendchar( EVER_GET_FLAGS );
266 upsrecvchars( (char*)&ups_flags, 1 );
267
268 /****
269 Accumulator voltage value
270 ****/
271
272 if( !ever_initframe(1) )
273 return;
274
275 upssendchar( EVER_GET_BATTV );
276 upsrecvchars( (char*)recBuf, 1 );
277
278 accuVoltage = 150*(recBuf[0])/255;
279
280 /****
281 Line voltage
282 ****/
283
284 if( !ever_initframe(1) )
285 return;
286
287 upssendchar( EVER_GET_LINEV );
288 upsrecvchars( (char*)recBuf, 2 );
289
290 if ( ever_upstype > 72 && ever_upstype < 77)
291 lineVoltage = 100*(recBuf[0]+256*recBuf[1])/352;
292 else
293 lineVoltage = 100*(recBuf[0]+256*recBuf[1])/372;
294
295 /****
296 Battery charge
297 ****/
298
299
300 if( battery )
301 batteryCharge = 100.0 * (accuVoltage - BATT_DISCHARGED_VOLT) / (BATT_MAX_OB_VOLTAGE - BATT_DISCHARGED_VOLT);
302 else if( standby )
303 batteryCharge = 100.0 * (accuVoltage - BATT_DISCHARGED_VOLT) / (BATT_MAX_OFF_VOLT - BATT_DISCHARGED_VOLT);
304 else /* online */
305 batteryCharge = 100.0 * (accuVoltage - BATT_DISCHARGED_VOLT) / (BATT_MAX_OL_VOLT - BATT_DISCHARGED_VOLT);
306
307 if( batteryCharge > 100 )
308 batteryCharge = 100;
309 else if( batteryCharge < 0 )
310 batteryCharge = 0;
311
312 status_init();
313
314 if( standby )
315 status_set( "OFF" );
316 else if( battery )
317 status_set( "OB" );
318 else
319 status_set( "OL" );
320
321 if( battery && accuVoltage <= batt_min_ob_voltage )
322 status_set( "LB" );
323
324 /***
325 if( ups_flags&EVER_FLAG_POWEROFF )
326 status_set( "OFFPEND" );
327 ***/
328
329 if( ups_flags&EVER_FLAG_SELFTEST )
330 status_set( "TESTPEND" );
331
332 if( ups_flags&EVER_FLAG_SELFTESTFAIL )
333 status_set( "TESTFAIL" );
334
335 status_commit();
336
337 snprintf( temp, VALSIZE, "%03u", lineVoltage );
338 setinfo ( INFO_UTILITY, temp );
339
340 snprintf( temp,VALSIZE, "%03.1f", (double)accuVoltage/10.0 );
341 setinfo ( INFO_BATTVOLT, temp );
342
343 snprintf( temp, VALSIZE, "%03.1f", batteryCharge );
344 setinfo ( INFO_BATTPCT, temp );
345
346 setinfo( INFO_AUDIBLEALRM, (ups_flags&EVER_FLAG_BEEPOFF)?"OFF":"ON" );
347
348 setinfo( INFO_LOWXFER, "???" );
349 setinfo( INFO_HIGHXFER, "???" );
350
351 if( ever_debug > 0 ) {
352 setinfo( INFO_COPYRIGHT, "STAT:%02X FLAG:%02X min OB: %2.1fV", (int)ups_status, (int)ups_flags, (double)batt_min_ob_voltage/10.0 );
353 }
354
355
356 writeinfo();
357}
358
359/* initialize UPS */
360void upsdrv_initups(void)
361{
362 /* check serial number from arguments */
363 if( getval("serialnumber") != NULL ) {
364 ever_serialnumber = getval("serialnumber");
365 };
366
367 if( getval("minbattvolt") != NULL ) {
368 int minbattvolt = (int)(atof(getval("minbattvolt"))*10);
369
370 if( minbattvolt >= BATT_DISCHARGED_VOLT && minbattvolt <= BATT_MAX_OB_VOLTAGE )
371 batt_min_ob_voltage = minbattvolt;
372 };
373
374 if( getval("debug") != NULL ) {
375 ever_debug = atoi( getval("debug") );
376 };
377
378 upsdebugx( 1, "Values of arguments:" );
379 upsdebugx( 1, " serial number: '%s'", ever_serialnumber );
380
381 open_serial( device_path, B300 );
382 init_serial();
383
384 ever_initups();
385 ever_getupstype();
386}
387
388void upsdrv_shutdown(void)
389{
390 if (do_forceshutdown == 1) {
391 /* power down the attached load immediately */
392 printf("Forced UPS shutdown triggered, do it...\n");
393 } else {
394 /* power down the attached load after the given delay */
395 printf("UPS shutdown with '%d' seconds delay triggered, wait now...\n", sddelay);
396 sleep(sddelay);
397 };
398
399 ever_poweroff(2); /* power off load after 2 sec */
400}
401
402/* display help */
403void upsdrv_help(void)
404{
405}
406
407/* display banner */
408void upsdrv_banner(void)
409{
410 printf("Network UPS Tools - Ever UPS driver 0.02 (%s)\n\n", UPS_VERSION);
411}
412
413/* tell main how many entries we need */
414int upsdrv_infomax(void)
415{
416 return 32;
417}
418
419/* initialize information */
420void upsdrv_initinfo(void)
421{
422 /* write constant data for this model */
423 addinfo( INFO_MFR, "Ever", 0, 0 );
424 addinfo( INFO_MODEL, ever_getupsname(), 0, 0 );
425 addinfo( INFO_SERIAL, ever_serialnumber, 0, 0 );
426
427 /* add other things to monitor */
428 addinfo( INFO_STATUS, "", 0, 0 );
429 addinfo( INFO_UTILITY, "", 0, 0 );
430 addinfo( INFO_BATTPCT, "", 0, 0 );
431 addinfo( INFO_BATTVOLT, "", 0, 0 );
432
433 /* now add the instant commands */
434 addinfo( INFO_INSTCMD, "", 0, CMD_BTEST1 );
435 addinfo( INFO_INSTCMD, "", 0, CMD_OFF );
436 addinfo( INFO_INSTCMD, "", 0, CMD_ON );
437
438 /* RW variables */
439 addinfo( INFO_AUDIBLEALRM, "", FLAG_RW | FLAG_ENUM, 2 );
440 addinfo( INFO_ENUM, "ON", 1, INFO_AUDIBLEALRM );
441 addinfo( INFO_ENUM, "OFF", 0, INFO_AUDIBLEALRM );
442 addinfo( INFO_LOWXFER, "", FLAG_RW | FLAG_STRING, 3 );
443 addinfo( INFO_HIGHXFER, "", FLAG_RW | FLAG_STRING, 3 );
444
445 /* display debug info as copyright */
446 if( ever_debug > 0 ) {
447 addinfo( INFO_COPYRIGHT, "", 0, 0 );
448 }
449
450 upsh.instcmd = instcmd;
451 upsh.setvar = setvar;
452}
453
454/* list flags and values that you want to receive via -x */
455void upsdrv_makevartable(void)
456{
457 char temp[256];
458
459 addvar( VAR_VALUE, "serialnumber", "Specify serial number, because it cannot detected automagically (default="DEFAULT_SERIALNUMBER")" );
460
461 snprintf( temp, 256, "Specify battery voltage when UPS change state from OB to LB (min=%2.1fV, max=%2.1fV, default=%2.1f)",
462 (double)BATT_DISCHARGED_VOLT/10.0, (double)BATT_MAX_OB_VOLTAGE/10.0, (double)BATT_MIN_OB_VOLTAGE/10.0 );
463 addvar( VAR_VALUE, "minbattvolt", temp );
464
465 addvar( VAR_VALUE, "debug", "Specify this param if you want to debug driver" );
466}
This page took 0.117398 seconds and 4 git commands to generate.