56
static char *get_belkin_field(const char *in, char *out, size_t outlen,
64
snprintf(out, outlen, "%s", in);
65
ptr = strchr(out, ';');
73
for (i = 0; i < strlen(in); i++) {
78
snprintf(out, outlen, "%s", &in[i + 1]);
79
ptr = strchr(out, ';');
90
static int do_status(void)
51
92
char temp[SMALLBUF], st[SMALLBUF];
73
114
send_belkin_command(STATUS,STAT_BATTERY,"");
74
115
res = get_belkin_reply(temp);
78
122
get_belkin_field(temp, st, sizeof(st), 10);
80
124
get_belkin_field(temp, st, sizeof(st), 2);
82
126
if (*st == '1' || res < LOW_BAT)
83
status_set("LB"); /* low battery */
127
status_set("LB"); /* low battery */
86
130
status_set("OL"); /* on line */
106
182
send_belkin_command(STATUS, VERSION, "");
107
183
res = get_belkin_reply(temp);
111
187
dstate_setinfo("ups.firmware", "%s", temp);
189
/* deal with stupid firmware that breaks RAT */
113
191
send_belkin_command(STATUS, RATING, "");
114
res = get_belkin_reply(temp);
116
get_belkin_field(temp, st, sizeof(st), 8);
117
low = atof(st) / 0.88;
119
get_belkin_field(temp, st, sizeof(st), 9);
120
high = atof(st) * 0.88;
193
if (!strcmp(temp, "001"))
194
res = do_broken_rat(temp);
196
res = get_belkin_reply(temp);
199
get_belkin_field(temp, st, sizeof(st), 8);
200
low = atof(st) / 0.88;
202
get_belkin_field(temp, st, sizeof(st), 9);
203
high = atof(st) * 0.88;
205
dstate_setinfo("input.transfer.low", "%03.1f", low);
206
dstate_setinfo("input.transfer.high", "%03.1f", high);
122
209
tcflush(upsfd,TCIOFLUSH);
124
dstate_setinfo("input.transfer.low", "%03.1f", low);
125
dstate_setinfo("input.transfer.high", "%03.1f", high);
127
211
dstate_addcmd("load.off");
128
212
dstate_addcmd("load.on");
129
213
upsdrv_updateinfo();
158
247
dstate_setinfo("battery.charge", "%03.0f", val);
249
get_belkin_field(temp, st, sizeof(st), 9);
251
dstate_setinfo("battery.temperature", "%03.0f", val);
160
253
get_belkin_field(temp, st, sizeof(st), 7);
161
254
val = atof(st) / 10;
162
255
dstate_setinfo("battery.voltage", "%4.1f", val);
183
276
dstate_setinfo("ups.load", "%03.0f", val);
187
void get_belkin_field(char *temp, char *data, size_t datalen, int n)
279
static int get_belkin_reply(char *buf)
192
strlcpy(st, temp, sizeof(st));
195
while (st[i] && st[i] != ';')
286
/* pull first 7 bytes to get data length - like ~00S004 */
287
ret = ser_get_buf_len(upsfd, tmp, 7, 3, 0);
290
ser_comm_fail("Initial read returned %d bytes", ret);
204
while (st[i] && st[i] != ';')
209
snprintf(data, datalen, "%s", st+f);
212
int get_belkin_reply(char *buf)
216
res = recvbinary(buf, 7);
223
res = recvbinary(buf, cnt);
297
if ((cnt < 1) || (cnt > 255))
300
/* give it time to respond to us */
303
ret = ser_get_buf_len(upsfd, buf, cnt, 3, 0);
229
void send_belkin_command(char command, const char *subcommand, const char *data)
231
upssend("~00%c%03d%s%s", command, strlen(data) + 3, subcommand, data);
308
ser_comm_fail("Second read returned %d bytes, expected %d",
234
318
/* power down the attached load immediately */
235
319
void upsdrv_shutdown(void)
238
char temp[SMALLBUF], st[SMALLBUF];
240
323
res = init_communication();
242
325
printf("Detection failed. Trying a shutdown command anyway.\n");
243
send_belkin_command(CONTROL, POWER_OFF, "1;1");
247
send_belkin_command(STATUS, STAT_STATUS, "");
248
res = get_belkin_reply(temp);
249
get_belkin_field(temp, st, sizeof(st), 2);
252
printf("On battery - sending shutdown comand...\n");
253
send_belkin_command(CONTROL,POWER_OFF,"1;1");
257
printf("Power restored - sending shutdown+return command...\n");
259
/* turn off the outlet in 5 seconds */
260
send_belkin_command(CONTROL, POWER_OFF, "1;5");
262
/* ... and turn it back on 10 seconds after that */
263
send_belkin_command(CONTROL, POWER_ON, "1;15");
327
/* tested on a F6C525-SER: this works when OL and OB */
329
/* shutdown type 2 (UPS system) */
330
send_belkin_command(CONTROL, "SDT", "2");
332
/* SDR means "do SDT and SDA, then reboot after n minutes" */
333
send_belkin_command(CONTROL, "SDR", "1");
335
printf("UPS should power off load in 5 seconds\n");
337
/* shutdown in 5 seconds */
338
send_belkin_command(CONTROL, "SDA", "5");
266
341
/* handle the "load.off" with some paranoia */
342
static void do_off(void)
269
344
static time_t lastcmd = 0;
270
345
time_t now, elapsed;
279
354
if ((elapsed < MINCMDTIME) || (elapsed > MAXCMDTIME)) {
281
356
/* FUTURE: tell the user (via upsd) to try it again */
282
/* msgreply(UPSMSG_REPAGAIN); */
287
361
upslogx(LOG_INFO, "Sending powerdown command to UPS\n");
288
send_belkin_command(CONTROL,POWER_OFF,"1;1");
362
send_belkin_command(CONTROL,POWER_OFF,"1;1");
290
send_belkin_command(CONTROL,POWER_OFF,"1;1");
364
send_belkin_command(CONTROL,POWER_OFF,"1;1");
293
int instcmd(const char *cmdname, const char *extra)
367
static int instcmd(const char *cmdname, const char *extra)
295
369
if (!strcasecmp(cmdname, "load.off")) {
306
380
return STAT_INSTCMD_UNKNOWN;
309
/* install pointers to functions for msg handlers called from msgparse */
310
void setuphandlers(void)
312
upsh.new_instcmd = instcmd;
315
int send_string(char *data)
317
tcflush(upsfd, TCIFLUSH);
318
return(write(upsfd, data, strlen(data)));
321
int recvbinary(char *buf, int buflen)
324
int ret, counter = 0, retval = 0;
326
sigset_t bel_sigmask;
328
sa.sa_handler = timeout;
329
sigemptyset(&bel_sigmask);
330
sa.sa_mask = bel_sigmask;
332
sigaction(SIGALRM, &sa, NULL);
336
while (counter < buflen) {
337
ret = read(upsfd, &in, 1);
345
upslogx(LOG_DEBUG, "error reading from serial device!");
352
signal(SIGALRM, SIG_IGN);
357
void set_serialDTR0RTS1(void)
383
static void set_serialDTR0RTS1(void)
359
385
int dtr_bit = TIOCM_DTR;
360
386
int rts_bit = TIOCM_RTS;
398
425
printf("Unable to detect an Belkin Smart protocol UPS on port %s\n",
400
427
printf("Check the cabling, port name or model name and try again\n");
404
/* manufacturer ID - hardcoded in this particular module */
405
dstate_setinfo("ups.mfr", "BELKIN", 0, 0);
431
dstate_setinfo("ups.mfr", "BELKIN");
407
432
dstate_setinfo("driver.version.internal", "%s", DRV_VERSION);
409
434
/* see what's out there */