4
* NUT Oneac EG and ON model specific drivers for UPS units using
5
* the Oneac Advanced Interface. If your UPS is equipped with the
6
* Oneac Basic Interface, use the genericups driver
10
Copyright (C) 2002 by Eric Lawson <elawson@inficad.com>
12
This program is free software; you can redistribute it and/or modify
13
it under the terms of the GNU General Public License as published by
14
the Free Software Foundation; either version 2 of the License, or
15
(at your option) any later version.
17
This program is distributed in the hope that it will be useful,
18
but WITHOUT ANY WARRANTY; without even the implied warranty of
19
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
GNU General Public License for more details.
22
You should have received a copy of the GNU General Public License
23
along with this program; if not, write to the Free Software
24
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28
* 13 Sept 2002. Eric Lawson
29
* added BTEST0, BTEST1, RESETVOLT and SIMPWF instant commands.
30
* RESETVOLT resets the max and min measured voltage that
31
* has been measured by the UPS.
33
* 11 Sept 2002. Eric Lawson
34
* Cleaned up code to take full advantage of upssend().
36
* Added support for gathering ON specific values.
37
* The driver reports nominal utility voltage, nominal operating
38
* frequency, per cent of full load, current utility voltage,
39
* minimum and maximum utility voltage since the UPS last shut
40
* down, output UPS voltage, and if the UPS is boosting low utility
47
#define DRV_VERSION "0.4"
52
void do_battery_test(void)
56
if (getval("testtime") == NULL)
57
strlcpy(buffer, DEFAULT_BAT_TEST_TIME, 3);
59
strlcpy(buffer, getval("testtime"),3);
61
/*the UPS wants this value to always be two characters long*/
62
/*so put a zero in front of the string, if needed.... */
63
if (strlen(buffer) < 2) {
65
buffer[1] = buffer[0];
69
upssend("%s%s%s",BAT_TEST_PREFIX,buffer,COMMAND_END);
73
/****************************************************************
74
*below are the commands that are called by main (part of the *
75
*Above, are functions used only in this oneac driver *
76
***************************************************************/
78
int instcmd(const char *cmdname, const char *extra)
80
if (!strcasecmp(cmdname, "test.failure.start")) {
81
upssend("%s%s",SIM_PWR_FAIL,COMMAND_END);
82
return STAT_INSTCMD_HANDLED;
85
if (!strcasecmp(cmdname, "test.battery.start")) {
87
return STAT_INSTCMD_HANDLED;
90
if (!strcasecmp(cmdname, "test.battery.stop")) {
91
upssend("%s00%s",BAT_TEST_PREFIX,COMMAND_END);
92
return STAT_INSTCMD_HANDLED;
95
if (!strcasecmp(cmdname, "reset.input.minmax")) {
96
upssend("%c%s",RESET_MIN_MAX, COMMAND_END);
97
return STAT_INSTCMD_HANDLED;
100
upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname);
101
return STAT_INSTCMD_UNKNOWN;
105
void upsdrv_initinfo(void)
109
dstate_setinfo("ups.mfr", "ONEAC");
111
dstate_addcmd("test.battery.start");
112
dstate_addcmd("test.battery.stop");
113
dstate_addcmd("test.failure.start");
114
dstate_addcmd("reset.input.minmax");
116
/*set some stuff that shouldn't change after initialization*/
117
/*this stuff is common to both the EG and ON family of UPS */
119
/*firmware revision*/
120
upssend ("%c%s",GET_VERSION, COMMAND_END);
121
upsrecv (buffer, sizeof(buffer),ENDCHAR,IGNCHARS);
122
dstate_setinfo("ups.firmware", "%.3s",buffer);
124
/*nominal AC frequency setting --either 50 or 60*/
125
upssend ("%c%s",GET_NOM_FREQ,COMMAND_END);
126
upsrecv (buffer, sizeof(buffer), ENDCHAR,IGNCHARS);
127
dstate_setinfo("input.frequency", "%.2s", buffer);
132
upssend ("%c%s",GET_FAMILY,COMMAND_END);
133
upsrecv (buffer, sizeof(buffer), ENDCHAR, IGNCHARS);
134
dstate_setinfo("ups.model", "%.2s",buffer);
135
printf("Found %.2s family of Oneac UPS\n", buffer);
137
if (strncmp(buffer,FAMILY_ON,2) || strncmp(buffer,FAMILY_EG,2) == 0)
138
printf("Unknown family of UPS. Assuming EG capabilities.\n");
140
upsh.new_instcmd = instcmd;
142
/*The ON series of UPS supports more stuff than does the EG.
143
*Take care of the ON only stuff here
145
if(strncmp (dstate_getinfo("ups.model"), FAMILY_ON, 2) == 0) {
146
/*now set the ON specific "static" parameters*/
148
/*nominal input voltage*/
150
upssend("%c%s", GET_NOM_VOLTAGE, COMMAND_END);
151
upsrecv(buffer,sizeof(buffer),ENDCHAR,IGNCHARS);
155
dstate_setinfo("output.voltage.target.line",
160
dstate_setinfo("output.voltage.target.line",
165
upslogx(LOG_INFO,"Oneac: "
166
"Invalid voltage parameter from UPS");
171
void upsdrv_updateinfo(void)
175
upssend ("%c%s",GET_ALL,COMMAND_END);
176
upsrecv (buffer, sizeof(buffer), ENDCHAR, IGNCHARS);
178
upsdebugx (2,"upsrecv_updateinfo: upsrecv returned: %s\n",buffer);
181
/*take care of the UPS status information*/
182
switch (buffer[12]) {
186
case ON_BAT_LOW_LINE :
187
case ON_BAT_HI_LINE :
190
case LO_BAT_LOW_LINE :
191
case LO_BAT_HI_LINE :
195
status_set("OVER OB LB");
199
/* this is not defined */
201
setinfo (INFO_ALRM_GENERAL, "ALARM ");
207
default : /*cry for attention, fake a status*/
208
/*Would another status be better?*/
209
upslogx (LOG_ERR, "Oneac: Unknown UPS status");
213
/*take care of the reason why the UPS last transfered to battery*/
214
switch (buffer[13]) {
216
dstate_setinfo("input.transfer.reason", "Blackout");
219
dstate_setinfo("input.transfer.reason",
220
"Low Input Voltage");
223
dstate_setinfo("input.transfer.reason",
224
"High Input Voltage");
227
dstate_setinfo("input.transfer.reason",
231
upslogx(LOG_INFO,"Oneac: Unknown reason for UPS battery transfer");
233
/* now update info for only the ON family of UPS*/
235
if (strncmp(dstate_getinfo("ups.model"), FAMILY_ON, 2) == 0) {
236
dstate_setinfo("ups.load", "0%.2s",buffer+31);
240
/* I've commented this out until I either figure out how to convert
241
* to an actual time, or I decide I can't do that and remove this code
243
if(buffer[10] == YES)
244
dstate_setinfo("batt.runtime", "0%.2s",buffer+33);
245
else dstate_setinfo("batt.runtime", "100");
248
dstate_setinfo("input.voltage", "%.3s",buffer+35);
249
dstate_setinfo("input.voltage.minimum", "%.3s",buffer+38);
250
dstate_setinfo("input.voltage.maximum", "%.3s",buffer+41);
251
dstate_setinfo("output.voltage", "%.3s",buffer+44);
252
if (buffer[47] == YES) status_set("BOOST");
258
void upsdrv_shutdown(void)
264
void upsdrv_help(void)
266
printf("\n---------\nNOTE:\n");
267
printf("You must set the UPS interface card DIP switch to 9600BPS\n");
270
void upsdrv_makevartable(void)
272
addvar(VAR_VALUE,"testtime",
273
"Change battery test time from 2 minute default.");
276
void upsdrv_banner(void)
278
printf("Network UPS Tools - Oneac EG/ON UPS driver %s (%s)\n\n",
279
DRV_VERSION, UPS_VERSION);
280
experimental_driver = 1; /*causes a warning to be printed*/
283
void upsdrv_initups(void)
287
/* this driver doesn't do sanity checks in upsdrv_updateinfo */
291
open_serial(device_path, B9600);
293
/*Is there anybody out there?*/
295
upssend (COMMAND_END);
297
upssend (COMMAND_END);
299
upssend("%c%s",GET_MFR, COMMAND_END);
300
upsrecv (buffer, sizeof(buffer), ENDCHAR, IGNCHARS);
301
if (strncmp(buffer, MFGR, sizeof(MFGR)))
302
fatalx("Unable to contact ONEAC UPS on %s\n",device_path);
305
void upsdrv_cleanup(void)