|
Lines 25-34
Link Here
|
| 25 |
#include "main.h" |
25 |
#include "main.h" |
| 26 |
#include "serial.h" |
26 |
#include "serial.h" |
| 27 |
#include "megatec.h" |
27 |
#include "megatec.h" |
|
|
28 |
#include "timehead.h" |
| 28 |
|
29 |
|
| 29 |
#include <stdio.h> |
30 |
#include <stdio.h> |
| 30 |
#include <limits.h> |
31 |
#include <limits.h> |
| 31 |
#include <string.h> |
32 |
#include <string.h> |
|
|
33 |
#include <ctype.h> |
| 32 |
|
34 |
|
| 33 |
|
35 |
|
| 34 |
#define ENDCHAR '\r' |
36 |
#define ENDCHAR '\r' |
|
Lines 49-58
Link Here
|
| 49 |
|
51 |
|
| 50 |
#define MAX_START_DELAY 9999 |
52 |
#define MAX_START_DELAY 9999 |
| 51 |
#define MAX_SHUTDOWN_DELAY 99 |
53 |
#define MAX_SHUTDOWN_DELAY 99 |
|
|
54 |
#define MAX_REPEAT_DELAY 15000 |
| 52 |
|
55 |
|
| 53 |
/* Maximum length of a string representing these values */ |
56 |
/* Maximum length of a string representing these values */ |
| 54 |
#define MAX_START_DELAY_LEN 4 |
57 |
#define MAX_START_DELAY_LEN 4 |
| 55 |
#define MAX_SHUTDOWN_DELAY_LEN 2 |
58 |
#define MAX_SHUTDOWN_DELAY_LEN 2 |
|
|
59 |
#define MAX_REPEAT_DELAY_LEN 5 |
| 56 |
|
60 |
|
| 57 |
#define N_FLAGS 8 |
61 |
#define N_FLAGS 8 |
| 58 |
|
62 |
|
|
Lines 130-136
Link Here
|
| 130 |
|
134 |
|
| 131 |
/* In minutes: */ |
135 |
/* In minutes: */ |
| 132 |
static short start_delay = 2; /* wait this amount of time to come back online */ |
136 |
static short start_delay = 2; /* wait this amount of time to come back online */ |
| 133 |
static short shutdown_delay = 0; /* wait until going offline */ |
137 |
static unsigned char shutdown_delay[3] = ".2"; /* wait until going offline */ |
|
|
138 |
|
| 139 |
/* In milliseconds: */ |
| 140 |
static short off_cmd_repeat = 0; /* wait this amount of time to repeat off/shutdown command */ |
| 134 |
|
141 |
|
| 135 |
/* In percentage: */ |
142 |
/* In percentage: */ |
| 136 |
static float lowbatt = -1; /* disabled */ |
143 |
static float lowbatt = -1; /* disabled */ |
|
Lines 412-418
Link Here
|
| 412 |
} |
419 |
} |
| 413 |
|
420 |
|
| 414 |
if (getval("offdelay")) { |
421 |
if (getval("offdelay")) { |
| 415 |
shutdown_delay = CLAMP(atoi(getval("offdelay")), 0, MAX_SHUTDOWN_DELAY); |
422 |
shutdown_delay[2] = '\0'; |
|
|
423 |
strncpy(shutdown_delay, getval("offdelay"), 2); |
| 424 |
if (shutdown_delay[0] == '\0') { |
| 425 |
shutdown_delay[0] = '.'; |
| 426 |
shutdown_delay[1] = '2'; |
| 427 |
} else if (shutdown_delay[0] != '.') { |
| 428 |
i = CLAMP(atoi(shutdown_delay), 0, MAX_SHUTDOWN_DELAY); |
| 429 |
snprintf(shutdown_delay, 2, "%02d", i); |
| 430 |
} else if (shutdown_delay[1] == '\0') { |
| 431 |
shutdown_delay[1] = '2'; |
| 432 |
} |
| 433 |
} |
| 434 |
|
| 435 |
if (getval("cmdrepeat")) { |
| 436 |
off_cmd_repeat = CLAMP(atoi(getval("cmdrepeat")), 0, MAX_REPEAT_DELAY); |
| 416 |
} |
437 |
} |
| 417 |
|
438 |
|
| 418 |
/* |
439 |
/* |
|
Lines 422-431
Link Here
|
| 422 |
dstate_setflags("ups.delay.start", ST_FLAG_RW | ST_FLAG_STRING); |
443 |
dstate_setflags("ups.delay.start", ST_FLAG_RW | ST_FLAG_STRING); |
| 423 |
dstate_setaux("ups.delay.start", MAX_START_DELAY_LEN); |
444 |
dstate_setaux("ups.delay.start", MAX_START_DELAY_LEN); |
| 424 |
|
445 |
|
| 425 |
dstate_setinfo("ups.delay.shutdown", "%d", shutdown_delay); |
446 |
dstate_setinfo("ups.delay.shutdown", "%s", shutdown_delay); |
| 426 |
dstate_setflags("ups.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING); |
447 |
dstate_setflags("ups.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING); |
| 427 |
dstate_setaux("ups.delay.shutdown", MAX_SHUTDOWN_DELAY_LEN); |
448 |
dstate_setaux("ups.delay.shutdown", MAX_SHUTDOWN_DELAY_LEN); |
| 428 |
|
449 |
|
|
|
450 |
dstate_setinfo("ups.delay.cmdrepeat", "%d", off_cmd_repeat); |
| 451 |
dstate_setflags("ups.delay.cmdrepeat", ST_FLAG_RW | ST_FLAG_STRING); |
| 452 |
dstate_setaux("ups.delay.cmdrepeat", MAX_REPEAT_DELAY_LEN); |
| 453 |
|
| 429 |
/* |
454 |
/* |
| 430 |
* Register the available instant commands. |
455 |
* Register the available instant commands. |
| 431 |
*/ |
456 |
*/ |
|
Lines 543-549
Link Here
|
| 543 |
upslogx(LOG_INFO, "Shutting down UPS immediately."); |
568 |
upslogx(LOG_INFO, "Shutting down UPS immediately."); |
| 544 |
|
569 |
|
| 545 |
ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); |
570 |
ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); |
| 546 |
ser_send_pace(upsfd, SEND_PACE, "S%02dR%04d%c", shutdown_delay, start_delay, ENDCHAR); |
571 |
ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); |
|
|
572 |
if (off_cmd_repeat > 0) { |
| 573 |
usleep(off_cmd_repeat * 1000); |
| 574 |
ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); |
| 575 |
} |
| 547 |
} |
576 |
} |
| 548 |
|
577 |
|
| 549 |
|
578 |
|
|
Lines 598-604
Link Here
|
| 598 |
ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); |
627 |
ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); |
| 599 |
watchdog_enabled = 0; |
628 |
watchdog_enabled = 0; |
| 600 |
|
629 |
|
| 601 |
ser_send_pace(upsfd, SEND_PACE, "S%02dR%04d%c", shutdown_delay, start_delay, ENDCHAR); |
630 |
ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); |
|
|
631 |
if (off_cmd_repeat > 0) { |
| 632 |
usleep(off_cmd_repeat * 1000); |
| 633 |
ser_send_pace(upsfd, SEND_PACE, "S%.2sR%04d%c", shutdown_delay, start_delay, ENDCHAR); |
| 634 |
} |
| 602 |
|
635 |
|
| 603 |
upslogx(LOG_INFO, "Shutdown (return) initiated."); |
636 |
upslogx(LOG_INFO, "Shutdown (return) initiated."); |
| 604 |
|
637 |
|
|
Lines 609-615
Link Here
|
| 609 |
ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); |
642 |
ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); |
| 610 |
watchdog_enabled = 0; |
643 |
watchdog_enabled = 0; |
| 611 |
|
644 |
|
| 612 |
ser_send_pace(upsfd, SEND_PACE, "S%02dR0000%c", shutdown_delay, ENDCHAR); |
645 |
ser_send_pace(upsfd, SEND_PACE, "S%.2sR0000%c", shutdown_delay, ENDCHAR); |
|
|
646 |
if (off_cmd_repeat > 0) { |
| 647 |
usleep(off_cmd_repeat * 1000); |
| 648 |
ser_send_pace(upsfd, SEND_PACE, "S%.2sR0000%c", shutdown_delay, ENDCHAR); |
| 649 |
} |
| 613 |
|
650 |
|
| 614 |
upslogx(LOG_INFO, "Shutdown (stayoff) initiated."); |
651 |
upslogx(LOG_INFO, "Shutdown (stayoff) initiated."); |
| 615 |
|
652 |
|
|
Lines 639-644
Link Here
|
| 639 |
watchdog_enabled = 0; |
676 |
watchdog_enabled = 0; |
| 640 |
|
677 |
|
| 641 |
ser_send_pace(upsfd, SEND_PACE, "S00R0000%c", ENDCHAR); |
678 |
ser_send_pace(upsfd, SEND_PACE, "S00R0000%c", ENDCHAR); |
|
|
679 |
if (off_cmd_repeat > 0) { |
| 680 |
usleep(off_cmd_repeat * 1000); |
| 681 |
ser_send_pace(upsfd, SEND_PACE, "S00R0000%c", ENDCHAR); |
| 682 |
} |
| 642 |
|
683 |
|
| 643 |
upslogx(LOG_INFO, "Turning load off."); |
684 |
upslogx(LOG_INFO, "Turning load off."); |
| 644 |
|
685 |
|
|
Lines 688-699
Link Here
|
| 688 |
int setvar(const char *varname, const char *val) |
729 |
int setvar(const char *varname, const char *val) |
| 689 |
{ |
730 |
{ |
| 690 |
int delay; |
731 |
int delay; |
|
|
732 |
int i; |
| 691 |
|
733 |
|
| 692 |
if (sscanf(val, "%d", &delay) != 1) { |
734 |
i = sscanf(val, "%d", &delay); |
| 693 |
return STAT_SET_UNKNOWN; |
|
|
| 694 |
} |
| 695 |
|
735 |
|
| 696 |
if (strcasecmp(varname, "ups.delay.start") == 0) { |
736 |
if (strcasecmp(varname, "ups.delay.start") == 0) { |
|
|
737 |
if (i != 1) { |
| 738 |
return STAT_SET_UNKNOWN; |
| 739 |
} |
| 697 |
delay = CLAMP(delay, 0, MAX_START_DELAY); |
740 |
delay = CLAMP(delay, 0, MAX_START_DELAY); |
| 698 |
start_delay = delay; |
741 |
start_delay = delay; |
| 699 |
dstate_setinfo("ups.delay.start", "%d", delay); |
742 |
dstate_setinfo("ups.delay.start", "%d", delay); |
|
Lines 704-712
Link Here
|
| 704 |
} |
747 |
} |
| 705 |
|
748 |
|
| 706 |
if (strcasecmp(varname, "ups.delay.shutdown") == 0) { |
749 |
if (strcasecmp(varname, "ups.delay.shutdown") == 0) { |
| 707 |
delay = CLAMP(delay, 0, MAX_SHUTDOWN_DELAY); |
750 |
if (!val || !val[0]) { |
| 708 |
shutdown_delay = delay; |
751 |
return STAT_SET_UNKNOWN; |
| 709 |
dstate_setinfo("ups.delay.shutdown", "%d", delay); |
752 |
} |
|
|
753 |
if (val[0] != '.' ) { |
| 754 |
if (i != 1) { |
| 755 |
return STAT_SET_UNKNOWN; |
| 756 |
} |
| 757 |
delay = CLAMP(delay, 0, MAX_SHUTDOWN_DELAY); |
| 758 |
snprintf(shutdown_delay, 2, "%02d", delay); |
| 759 |
} else { |
| 760 |
i = val[1]; |
| 761 |
if (!isdigit(i)) { |
| 762 |
return STAT_SET_UNKNOWN; |
| 763 |
} |
| 764 |
strncpy(shutdown_delay, val, 2); |
| 765 |
} |
| 766 |
shutdown_delay[2] = '\0'; |
| 767 |
dstate_setinfo("ups.delay.shutdown", "%s", shutdown_delay); |
| 768 |
|
| 769 |
dstate_dataok(); |
| 770 |
|
| 771 |
return STAT_SET_HANDLED; |
| 772 |
} |
| 773 |
|
| 774 |
if (strcasecmp(varname, "ups.delay.cmdrepeat") == 0) { |
| 775 |
if (i != 1) { |
| 776 |
return STAT_SET_UNKNOWN; |
| 777 |
} |
| 778 |
delay = CLAMP(delay, 0, MAX_REPEAT_DELAY); |
| 779 |
off_cmd_repeat = delay; |
| 780 |
dstate_setinfo("ups.delay.cmdrepeat", "%d", delay); |
| 710 |
|
781 |
|
| 711 |
dstate_dataok(); |
782 |
dstate_dataok(); |
| 712 |
|
783 |
|
|
Lines 730-735
Link Here
|
| 730 |
addvar(VAR_VALUE, "lowbatt", "Low battery level (%)"); |
801 |
addvar(VAR_VALUE, "lowbatt", "Low battery level (%)"); |
| 731 |
addvar(VAR_VALUE, "ondelay", "Delay before UPS startup (minutes)"); |
802 |
addvar(VAR_VALUE, "ondelay", "Delay before UPS startup (minutes)"); |
| 732 |
addvar(VAR_VALUE, "offdelay", "Delay before UPS shutdown (minutes)"); |
803 |
addvar(VAR_VALUE, "offdelay", "Delay before UPS shutdown (minutes)"); |
|
|
804 |
addvar(VAR_VALUE, "cmdrepeat", "Delay (msec) to repeat shutdown cmd"); |
| 733 |
} |
805 |
} |
| 734 |
|
806 |
|
| 735 |
|
807 |
|