Skip to content

Commit

Permalink
Merge pull request #2089 from moonbuggy/master
Browse files Browse the repository at this point in the history
Correct voltage and battery capacity for Opti-UPS 230VAC and/or 24VDC models
  • Loading branch information
jimklimov authored Oct 6, 2023
2 parents bfcee3f + 26bf63d commit 3bf526e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
8 changes: 8 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ as part of https://github.com/networkupstools/nut/issues/1410 solution.
- The `bestfortress` driver shutdown handling was fixed to use a non-trivial
default timeout [#1820]

- The `optiups` driver only gave accurate voltage information with 120VAC
models and assumed a 12V battery when calculating capacity. There is
a protocol command that gives a (fixed) voltage which correlates with
the voltage selection DIP switches on the back of the UPS, taking into
account whether it is a 120 or 240VAC model. Likewise, now the battery
capacity fix is applied globally, based on whether or not the battery
voltage is greater than 20V. [#2089]

- GPIO drivers [#1855]:
* Added a new category of drivers, using GPIO interface to locally connected
devices (currently limited to 2018+ Linux libgpiod, but its architecture
Expand Down
1 change: 1 addition & 0 deletions data/driver.list.in
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@
"Opti-UPS" "ups" "1" "PowerES" "420E" "optiups"
"Opti-UPS" "ups" "1" "VS 575C" "type=OPTI" "powercom"
"Opti-UPS" "ups" "1" "Power Series" "PS1500E" "blazer_usb"
"Opti-UPS" "ups" "1" "Power Series" "PS1440RM" "optiups"

"Orvaldi Power Protection" "ups" "2" "various" "not 400 or 600" "blazer_ser"
"Orvaldi Power Protection" "ups" "2" "750 / 900SP" "USB" "blazer_usb"
Expand Down
60 changes: 56 additions & 4 deletions drivers/optiups.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include "nut_stdint.h"

#define DRIVER_NAME "Opti-UPS driver"
#define DRIVER_VERSION "1.03"
#define DRIVER_VERSION "1.04"

/* driver description structure */
upsdrv_info_t upsdrv_info = {
Expand Down Expand Up @@ -83,7 +83,8 @@ static char _buf[256];
static int optimodel = 0;
enum {
OPTIMODEL_DEFAULT = 0,
OPTIMODEL_ZINTO = 1
OPTIMODEL_ZINTO = 1,
OPTIMODEL_PS = 2
};


Expand Down Expand Up @@ -123,6 +124,19 @@ static ezfill_t _pollv_zinto[] = {
{ "BT", "ups.temperature", 0 },
};

/* When on a 220-2400V mains supply, the NV and OV commands return 115V values. FV
* returns a value that matches the DIP switch settings for 120/240V models, so
* it can be used to scale the valus from NV and OV.
*
* I suspect this will be the case for other Opti-UPS models, but as I can only
* test with a PS-1440RM at 230V the change is only applied to PowerSeries models.
*/
static ezfill_t _pollv_ps[] = {
{ "OL", "ups.load", 1.0 },
{ "FF", "input.frequency", 0.1 },
{ "BT", "ups.temperature", 0 },
};

/* model "IO" is parsed differently in upsdrv_initinfo() */
static ezfill_t _initv[] = {
{ "IM", "ups.mfr", 0 },
Expand Down Expand Up @@ -347,6 +361,13 @@ void upsdrv_initinfo(void)
optiquery( "ON" );
}

/* Autodetect an Opti-UPS PS series */
r = optiquery( "IO" );
if ( r > 0 && !strncasecmp(_buf, "PS-", 3) )
{
optimodel = OPTIMODEL_PS;
}

optifill( _initv, sizeof(_initv)/sizeof(_initv[0]) );

/* Parse out model into longer string -- is this really USEFUL??? */
Expand Down Expand Up @@ -463,6 +484,29 @@ void upsdrv_updateinfo(void)
/* read some easy settings */
if ( optimodel == OPTIMODEL_ZINTO )
optifill( _pollv_zinto, sizeof(_pollv_zinto)/sizeof(_pollv_zinto[0]) );
else if ( optimodel == OPTIMODEL_PS ) {
short inV, outV, fV;

optifill( _pollv_ps, sizeof(_pollv_ps)/sizeof(_pollv_ps[0]) );

r = optiquery( "NV" );
str_to_short ( _buf, &inV, 10 );
r = optiquery( "OV" );
str_to_short ( _buf, &outV, 10 );

r = optiquery( "FV" );
if ( r >= 1 )
{
str_to_short ( _buf, &fV, 10 );
if ( fV > 180 )
{
inV = inV * 2;
outV = outV * 2;
}
}
dstate_setinfo( "input.voltage", "%d", inV );
dstate_setinfo( "output.voltage", "%d", outV );
}
else
optifill( _pollv, sizeof(_pollv)/sizeof(_pollv[0]) );

Expand All @@ -475,8 +519,16 @@ void upsdrv_updateinfo(void)
float p, v = strtol( _buf, NULL, 10 ) / 10.0;
dstate_setinfo("battery.voltage", "%.1f", v );

/* battery voltage range: 10.4 - 13.0 VDC */
p = ((v - 10.4) / 2.6) * 100.0;
if (v > 20)
{
/* battery voltage range: 20.8 - 26.0 VDC */
p = ((v - 20.8) / 5.2) * 100.0;
}
else
{
/* battery voltage range: 10.4 - 13.0 VDC */
p = ((v - 10.4) / 2.6) * 100.0;
}
if ( p > 100.0 )
p = 100.0;
dstate_setinfo("battery.charge", "%.1f", p );
Expand Down

0 comments on commit 3bf526e

Please sign in to comment.