Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
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