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

« back to all changes in this revision

Viewing changes to drivers/bestuferrups.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:
6
6
   Russell.   It has no test battery command since my ME3100 does this
7
7
   by itself. (same as Grant's driver in this respect)
8
8
 
 
9
   Support for model RE added by Tim Thompson (7/22/04)
 
10
   
9
11
   Copyright (C) 2002  Andreas Wrede  <andreas@planix.com>
10
12
   Copyright (C) 2000  John Stone  <johns@megapixel.com>
11
13
   Copyright (C) 2000  Grant Taylor <gtaylor@picante.com>
12
14
   Copyright (C) 1999  Russell Kroll <rkroll@exploits.org>
13
 
 
 
15
 
14
16
   This program is free software; you can redistribute it and/or modify
15
17
   it under the terms of the GNU General Public License as published by
16
18
   the Free Software Foundation; either version 2 of the License, or
23
25
 
24
26
   You should have received a copy of the GNU General Public License
25
27
   along with this program; if not, write to the Free Software
26
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
28
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
29
 
28
30
*/
29
31
 
30
 
#define DRV_VERSION "0.01"
 
32
#define DRV_VERSION "0.02"
31
33
 
32
34
#include "main.h"
 
35
#include "serial.h"
33
36
 
34
37
#define ENDCHAR         '\r'
35
38
#define IGNCHARS        "\012"
38
41
#define UNKNOWN         100
39
42
#define ME3100          200
40
43
#define MD1KVA          300 /* Software version P5.05 dated 05/18/89 */
 
44
#define RE1800          400
41
45
 
42
46
#include <stdio.h>
43
47
#include <string.h>
74
78
          case MD1KVA:
75
79
            dstate_setinfo("ups.model", "Micro Ferrups (MD) %d", fc.va);
76
80
            break;
 
81
          case RE1800:
 
82
            dstate_setinfo("ups.model", "Micro Ferrups (RE) %d", fc.va);
 
83
            break;
77
84
          default:
78
 
            exit(1); /* Will never get here, upsdrv_initups() will catch */
 
85
            exit(EXIT_FAILURE); /* Will never get here, upsdrv_initups() will catch */
79
86
        } 
80
87
        fprintf(stderr, "Best Power %s detected\n", 
81
88
                dstate_getinfo("ups.model"));
93
100
----------------------------------------------------
94
101
*/
95
102
 
96
 
int execute(char *cmd, char *result, int resultsize) 
 
103
static int execute(const char *cmd, char *result, int resultsize) 
97
104
{
98
105
  int ret;
99
106
  char buf[256];
100
107
  
101
 
  upssend(cmd);
102
 
  upsrecv(buf, sizeof(buf), '\012', "");
103
 
  ret=upsrecv(result, resultsize, '\015', "\012");
104
 
  upsrecv(buf, sizeof(buf), '>', "");
 
108
  ser_send(upsfd, "%s", cmd);
 
109
  ser_get_line(upsfd, buf, sizeof(buf), '\012', "", 3, 0);
 
110
  ret = ser_get_line(upsfd, result, resultsize, '\015', "\012", 3, 0);
 
111
  ser_get_line(upsfd, buf, sizeof(buf), '>', "", 3, 0);
105
112
  return ret;
106
113
 
107
114
}
121
128
    int inverter=0, charger=0, vin=0, vout=0, btimeleft=0, linestat=0, 
122
129
      alstat=0, vaout=0;
123
130
    double ampsout=0.0, vbatt=0.0, battpercent=0.0, loadpercent=0.0,
124
 
      upstemp=0.0, acfreq=0.0;
 
131
      hstemp=0.0, acfreq=0.0, ambtemp=0.0;
125
132
    char tmp[16];
126
133
 
127
134
    /* Inverter status.  0=off 1=on */
187
194
    /* UPS Temperature */
188
195
    memcpy(tmp, fstring+62, 4);
189
196
    tmp[4]= '\0';
190
 
    upstemp = (double)(atoi(tmp));
 
197
    ambtemp = (double)(atoi(tmp));
191
198
 
192
199
    /* Percent Load */
193
200
    switch(fc.model) {
198
205
          loadpercent = (double) l;
199
206
        }
200
207
        break;
 
208
      case RE1800:
 
209
        if (execute("d 16\r", fstring, sizeof(fstring)) > 0) {
 
210
          int l;
 
211
          sscanf(fstring, "16 FullLoad%% %d", &l);
 
212
          loadpercent = (double) l;
 
213
        }
 
214
        if (execute("d 12\r", fstring, sizeof(fstring)) > 0) {
 
215
          int l;
 
216
          sscanf(fstring, "12 HS Temp  %dC", &l);
 
217
          hstemp = (double) l;
 
218
        }
 
219
        break;
201
220
      case MD1KVA:
202
221
        if (execute("d 22\r", fstring, sizeof(fstring)) > 0) {
203
222
          int l;
206
225
        }
207
226
        break;
208
227
      default: /* Will never happen, caught in upsdrv_initups() */
209
 
        fprintf(stderr, "Uknown model in upsdrv_updateinfo()\n");
210
 
        exit(1);
 
228
        fprintf(stderr, "Unknown model in upsdrv_updateinfo()\n");
 
229
        exit(EXIT_FAILURE);
211
230
    }
212
231
    /* Compute battery percent left based on battery voltages. */
213
232
    battpercent = ((vbatt - fc.emptyvolts) 
257
276
              "Poll: inverter %d charger %d vin %d vout %d vaout %d btimeleft %d\n",
258
277
              inverter, charger, vin, vout, vaout, btimeleft);
259
278
      fprintf(stderr,
260
 
              "      ampsout %5.1f vbatt %5.1f batpcnt %5.1f loadpcnt %5.1f upstemp %5.1f acfreq %5.2f\n",
261
 
              ampsout, vbatt, battpercent, loadpercent, upstemp, acfreq);
 
279
              "      ampsout %5.1f vbatt %5.1f batpcnt %5.1f loadpcnt %5.1f upstemp %5.1f acfreq %5.2f ambtemp %5.1f\n",
 
280
              ampsout, vbatt, battpercent, loadpercent, hstemp, acfreq, ambtemp);
262
281
 
263
282
    }
264
283
 
270
289
    dstate_setinfo("ups.load", "%02.1f", loadpercent);
271
290
    dstate_setinfo("battery.voltage", "%02.1f", vbatt);
272
291
    dstate_setinfo("input.frequency", "%05.2f", (double)acfreq);
273
 
    dstate_setinfo("ups.temperature", "%05.1f", (double)upstemp);
 
292
    dstate_setinfo("ups.temperature", "%05.1f", (double)hstemp);
274
293
    dstate_setinfo("battery.runtime", "%d", btimeleft);
 
294
    dstate_setinfo("ambient.temperature", "%05.1f", (double)ambtemp);
275
295
 
276
296
    dstate_dataok();
277
 
 
 
297
    /* Tim: With out this return, it always falls over to the
 
298
        datastate() at the end of the function */
 
299
    return;
278
300
  } else {
279
301
 
280
302
    dstate_datastale();  
286
308
}
287
309
 
288
310
 
289
 
void ups_sync(void)
 
311
static void ups_sync(void)
290
312
{
291
313
  char  buf[256];
292
314
 
300
322
    fprintf(stderr, "UPS Time: %s\n", buf);
301
323
  } else {
302
324
    fprintf(stderr, "Error connecting to UPS.\n");
303
 
    exit(1);
 
325
    exit(EXIT_FAILURE);
304
326
  }
305
327
}
306
328
 
308
330
void upsdrv_shutdown(void)
309
331
{
310
332
/* NB: hard-wired password */
311
 
  upssend("pw377\r");
312
 
  upssend("off 1 a\r"); /* power off in 1 second and restart when line power returns */
 
333
  ser_send(upsfd, "pw377\r");
 
334
  ser_send(upsfd, "off 1 a\r"); /* power off in 1 second and restart when line power returns */
313
335
}
314
336
 
315
337
/* list flags and values that you want to receive via -x */
316
338
void upsdrv_makevartable(void)
317
339
{
318
 
        /* allow '-x xyzzy' */
319
 
        /* addvar(VAR_FLAG, "xyzzy", "Enable xyzzy mode"); */
320
 
 
321
 
        /* allow '-x foo=<some value>' */
322
 
        /* addvar(VAR_VALUE, "foo", "Override foo setting"); */
323
340
}
324
341
 
325
342
void upsdrv_help(void)
329
346
 
330
347
void upsdrv_banner(void)
331
348
{
332
 
        printf("Network UPS Tools - Best Ferrups Series ME %s (%s)\n\n", 
 
349
        printf("Network UPS Tools - Best Ferrups Series ME/RE/MD %s (%s)\n\n", 
333
350
                DRV_VERSION, UPS_VERSION);
334
351
}
335
352
 
336
353
static void sync_serial(void) {
337
354
        char buffer[10];
338
355
 
339
 
        upssend("\r");
340
 
        upsrecv(buffer,sizeof(buffer), '\r', "\012");
341
 
        upsrecv(buffer, sizeof(buffer), ENDCHAR, IGNCHARS);
 
356
        ser_send(upsfd, "\r");
 
357
        ser_get_line(upsfd, buffer, sizeof(buffer), '\r', "\012", 3, 0);
 
358
        ser_get_line(upsfd, buffer, sizeof(buffer), ENDCHAR, IGNCHARS, 3, 0);
342
359
 
343
 
        while (upsrecv(buffer,sizeof(buffer), '>', "\012") <= 0) {
344
 
                upssend("\r");
 
360
        while (ser_get_line(upsfd, buffer, sizeof(buffer), '>', "\012", 3, 0) <= 0) {
 
361
                ser_send(upsfd, "\r");
345
362
        }
346
363
}
347
364
 
379
396
{
380
397
  char  temp[256], fcstring[512];
381
398
 
382
 
  open_serial(device_path, B1200);
 
399
  upsfd = ser_open(device_path);
 
400
  ser_set_speed(upsfd, device_path, B1200);
383
401
  setup_serial();
384
402
  ups_sync();
385
403
 
387
405
  /* Obtain Model */
388
406
  if (execute("id\r", fcstring, sizeof(fcstring)) < 0) {
389
407
    fprintf(stderr, "Failed execute in ups_ident()\n");
390
 
    exit(1);
 
408
    exit(EXIT_FAILURE);
391
409
  }
392
410
  
393
411
  /* response is a one-line packed string starting with $ */
394
412
  if (memcmp(fcstring, "Unit", 4)) {
395
413
    fprintf(stderr, "Bad response from formatconfig command in ups_ident()\n");
396
414
    fprintf(stderr, "id: %s\n", fcstring);
397
 
    exit(1);
 
415
    exit(EXIT_FAILURE);
398
416
  }
399
417
 
400
418
  if (debugging)
406
424
 
407
425
  if (memcmp(temp, "ME", 2) == 0)  {
408
426
    fc.model = ME3100;
409
 
  }
410
 
  if (memcmp(temp, "C1", 2) == 0)  {
 
427
  } else if ((memcmp(temp, "RE", 2) == 0)) {
 
428
    fc.model = RE1800;
 
429
  } else if (memcmp(temp, "C1", 2) == 0)  {
411
430
    /* Better way to identify unit is using "d 15\r", which results in
412
431
       "15 M#    MD1KVA", "id\r" yields "Unit ID "C1K03588"" */
413
432
    fc.model = MD1KVA;
429
448
      /* determine "ideal" voltage by a guess */
430
449
      fc.idealbvolts = ((fc.fullvolts - fc.emptyvolts) * 0.7) + fc.emptyvolts;
431
450
      break;
 
451
    case RE1800:
 
452
      fc.va = 1800;
 
453
      fc.watts = 1200;
 
454
      /* determine shutdown battery voltage */
 
455
      if (execute("d 29\r", fcstring, sizeof(fcstring)) > 0) {
 
456
        sscanf(fcstring, "29 LowBat   %f", &fc.emptyvolts);
 
457
      }
 
458
      /* determine fully charged battery voltage */
 
459
      if (execute("d 31\r", fcstring, sizeof(fcstring)) > 0) {
 
460
        sscanf(fcstring, "31 HiBatt   %f", &fc.fullvolts);
 
461
      }
 
462
      fc.fullvolts = 54.20;
 
463
      /* determine "ideal" voltage by a guess */
 
464
      fc.idealbvolts = ((fc.fullvolts - fc.emptyvolts) * 0.7) + fc.emptyvolts;
 
465
      break;
432
466
    case MD1KVA:
433
467
      fc.va = 1100;
434
468
      fc.watts = 770; /* Approximate, based on 0.7 power factor */
446
480
      break;
447
481
    default:
448
482
      fprintf(stderr, "Uknown model %s in ups_ident()\n", temp);
449
 
      exit(1);
 
483
      exit(EXIT_FAILURE);
450
484
      break;
451
485
  }
452
486
 
456
490
 
457
491
void upsdrv_cleanup(void)
458
492
{
 
493
  ser_close(upsfd, device_path);
459
494
}