2
Copyright (C) 2001 Michael Spanier <mail@michael-spanier.de>
4
masterguard.c created on 15.8.2001
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
/********************************************************************
24
* Please if you edit this code convert tabs to spaces and use
25
* four characters indent.
26
* If you don't know what this means use the vim editor.
31
********************************************************************/
41
#define DRIVERVERSION "0.22"
47
/********************************************************************
49
* Helper function to split a sting into words by splitting at the
52
* Adds up to maxlen characters to the char word.
53
* Returns NULL on reaching the end of the string.
55
********************************************************************/
56
char *StringSplit( char *source, char *word, int maxlen )
63
len = strlen( source );
64
for( i = 0; i < len; i++ )
66
if( source[i] == ' ' )
69
return source + i + 1;
78
/********************************************************************
80
* Helper function to drop all whitespaces within a string.
82
* "word" must be large enought to hold "source", for the worst case
83
* "word" has to be exacly the size of "source".
85
********************************************************************/
86
void StringStrip( char *source, char *word )
93
len = strlen( source );
94
for( i = 0; i < len; i++ )
96
if( source[i] == ' ' )
98
if( source[i] == '\n' )
100
if( source[i] == '\t' )
102
word[wc] = source[i];
108
/********************************************************************
110
* Function parses the status flags which occure in the Q1 and Q3
111
* command. Sets the INFO_STATUS value ( OL, OB, ... )
113
********************************************************************/
114
void parseFlags( char *flags )
118
if( flags[0] == '1' )
123
if( flags[1] == '1' )
126
if( flags[2] == '1' )
129
/* this has no mapping */
131
if( flags[3] == '1' )
132
setinfo( INFO_ALRM_GENERAL, "1" );
136
/* and these are... ? */
138
if( flags[5] == '1' )
140
if( flags[6] == '1' )
147
printf( "Status is %s\n", dstate_getinfo("ups.status"));
150
/********************************************************************
152
* Function parses the response of the query1 ( "Q1" ) command.
153
* Also sets various values (IPFreq ... )
155
********************************************************************/
156
void query1( char *buf )
158
#define WORDMAXLEN 255
159
char value[WORDMAXLEN];
160
char word[WORDMAXLEN];
166
printf( "Q1 Buffer is : %s\n" , buf + 1 );
172
newPOS = StringSplit( oldPOS, word, WORDMAXLEN );
173
StringStrip( word, value);
178
printf( "value=%s\n", value );
185
dstate_setinfo("input.voltage", "%s", value );
188
/* IP Fault Voltage */
192
dstate_setinfo("output.voltage", "%s", value);
196
dstate_setinfo("ups.load", "%s", value );
200
dstate_setinfo("input.frequency", "%s", value);
203
/* Battery Cell Voltage */
204
dstate_setinfo("battery.voltage", "%s", value);
207
/* UPS Temperature */
208
dstate_setinfo("ups.temperature", "%s", value );
215
/* Should never be reached */
221
while( newPOS != NULL );
224
/********************************************************************
226
* Function parses the response of the query3 ( "Q3" ) command.
227
* Also sets various values (IPFreq ... )
229
********************************************************************/
230
void query3( char *buf )
232
#define WORDMAXLEN 255
233
char value[WORDMAXLEN];
234
char word[WORDMAXLEN];
240
printf( "Q3 Buffer is : %s\n" , buf+1 );
246
newPOS = StringSplit( oldPOS, word, WORDMAXLEN );
247
StringStrip( word, value);
256
printf( "value=%s\n", value );
266
dstate_setinfo("input.voltage", "%s", value );
269
/* Input Fault Voltage */
273
dstate_setinfo("output.voltage", "%s", value);
277
dstate_setinfo("output.current", "%s", value );
280
/* Input Frequency */
281
dstate_setinfo("input.frequency", "%s", value);
284
/* Battery Cell Voltage */
285
dstate_setinfo("battery.voltage", "%s", value);
289
dstate_setinfo("ups.temperature", "%s", value );
292
/* Estimated Runtime */
293
dstate_setinfo("battery.runtime", "%s", value);
297
dstate_setinfo("battery.charge", "%s", value);
307
/* This should never be reached */
308
/* printf( "DEFAULT\n" ); */
314
while( newPOS != NULL );
317
/********************************************************************
319
* Function to parse the WhoAmI response of the UPS. Also sets the
320
* values of the firmware version and the UPS identification.
322
********************************************************************/
323
void parseWH( char *buf )
325
strncpy( name, buf + 16, 30 );
327
strncpy( firmware, buf + 4, 5 );
330
printf( "Name = %s, Firmware Version = %s\n", name, firmware );
333
/********************************************************************
335
* Function to parse the old and possible broken WhoAmI response
336
* and set the values for the firmware Version and the identification
339
********************************************************************/
340
void parseOldWH( char *buf )
342
strncpy( name, buf + 4, 12 );
344
strncpy( firmware, buf, 4 );
347
printf( "Name = %s, Firmware Version = %s\n", name, firmware );
350
/********************************************************************
352
* Function to fake a WhoAmI response of a UPS that returns NAK.
354
********************************************************************/
357
strcpy( name, "GenericUPS" );
358
strcpy( firmware, "unkn" );
360
printf( "Name = %s, Firmware Version = %s\n", name, firmware );
363
int ups_ident( void )
368
/* Check presence of Q1 */
369
ret = upssend( "Q1\x0D" );
370
ret = upsrecv( buf, 250, '\x0D', "");
374
/* No Q1 response found */
381
printf( "Found Q1\n" );
385
/* Check presence of Q3 */
386
ret = upssend( "Q3\x0D" );
387
ret = upsrecv( buf, 250, '\x0D', "");
392
printf( "Found Q3\n" );
396
/* Check presence of WH ( Who am I ) */
397
ret = upssend( "WH\x0D" );
398
ret = upsrecv( buf, 250, '\x0D', "");
403
printf( "WH found\n" );
409
printf( "Old (broken) WH found\n" );
412
else if( ret == 3 && strcmp(buf, "NAK") == 0 )
415
printf( "WH was NAKed\n" );
421
printf( "WH says <%s> with length %i\n", buf, ret );
423
"New WH String found. Please report to maintainer\n" );
428
/********************************************************************
433
********************************************************************/
434
void upsdrv_help( void )
439
/********************************************************************
441
* Function to initialize the fields of the ups driver.
443
********************************************************************/
444
void upsdrv_initinfo(void)
446
dstate_setinfo("ups.mfr", "MASTERGUARD");
447
dstate_setinfo("ups.model", "unknown");
450
dstate_addcmd("test.battery.stop");
451
dstate_addcmd("test.battery.start");
454
if( strlen( name ) > 0 )
455
dstate_setinfo("ups.model", "%s", name);
456
if( strlen( firmware ) > 0 )
457
dstate_setinfo("ups.firmware", "%s", firmware);
459
dstate_setinfo("driver.version.internal", "%s", DRIVERVERSION);
462
/********************************************************************
464
* This is the main function. It gets called if the driver wants
465
* to update the ups status and the informations.
467
********************************************************************/
468
void upsdrv_updateinfo(void)
475
printf( "update info\n" );
489
/* Should never be reached */
492
fatalx("Error, no Query mode defined. Please file bug against driver.");
498
upsrecv( buf, 250, '\x0D', "\n");
504
printf( "buf = %s len = %i\n", buf, ret );
505
upslog( LOG_ERR, "Error in UPS response " );
510
/* Parse the response from the UPS */
525
/********************************************************************
527
* Called if the driver wants to shutdown the UPS.
528
* ( also used by the "-k" command line switch )
530
* This cuts the utility from the UPS after 20 seconds and restores
531
* the utility one minute _after_ the utility to the UPS has restored
533
********************************************************************/
534
void upsdrv_shutdown(void)
536
/* ups will come up within a minute if utility is restored */
537
upssend( "S.2R0001\x0D" );
540
/********************************************************************
542
* Populate the command line switches.
544
* CS: Cancel the shutdown process
546
********************************************************************/
547
void upsdrv_makevartable(void)
549
addvar( VAR_FLAG, "CS", "Cancel Shutdown" );
552
/********************************************************************
554
* The UPS banner shown during the startup.
555
* Spiffy isn't it? ;-)
557
********************************************************************/
558
void upsdrv_banner(void)
560
printf("Network UPS Tools - MASTERGUARD UPS driver %s (%s)\n\n",
561
DRIVERVERSION, UPS_VERSION);
565
/********************************************************************
567
* This is the first function called by the UPS driver.
568
* Detects the UPS and handles the command line args.
570
********************************************************************/
571
void upsdrv_initups(void)
577
/* setup serial port */
579
open_serial( device_path, B2400 );
589
if( ups_ident( ) != 1 )
591
/* at least two good identifications */
592
if( (count - fail) == 2 )
597
} while( (count<MAXTRIES) | (good) );
601
printf( "No MASTERGUARD UPS found\n" );
605
printf( "MASTERGUARD UPS found\n" );
607
/* Cancel Shutdown */
615
/********************************************************************
618
* As you probably know vim is the best editor ever ;-)
621
* vim:ts=4:sw=4:tw=78:et
623
********************************************************************/
625
void upsdrv_cleanup(void)