Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct voltage and battery capacity for Opti-UPS 230VAC and/or 24VDC models #2089

Merged
merged 7 commits into from
Oct 6, 2023
58 changes: 54 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,27 @@ 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 ) {
optifill( _pollv_ps, sizeof(_pollv_ps)/sizeof(_pollv_ps[0]) );

r = optiquery( "NV" );
float inV = strtol ( _buf, NULL, 10);
jimklimov marked this conversation as resolved.
Show resolved Hide resolved
r = optiquery( "OV" );
float outV = strtol ( _buf, NULL, 10);

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

Expand All @@ -475,8 +517,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