From 33bda61aa572b6d09ba077e0a560da0fcae8f8f8 Mon Sep 17 00:00:00 2001 From: moonbuggy <3319867+moonbuggy@users.noreply.github.com> Date: Wed, 4 Oct 2023 21:50:20 +1100 Subject: [PATCH 1/6] correct voltages for Opti-UPS 230V AC models; correct battery capacity for 24V models Signed-off-by: moonbuggy <3319867+moonbuggy@users.noreply.github.com> --- drivers/optiups.c | 58 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/optiups.c b/drivers/optiups.c index eddd94e173..4814b48af9 100644 --- a/drivers/optiups.c +++ b/drivers/optiups.c @@ -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 = { @@ -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 }; @@ -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 }, @@ -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??? */ @@ -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]) ); @@ -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 ); From 14f6dd1d442c5b1839cb3a212398677dadf33e30 Mon Sep 17 00:00:00 2001 From: moonbuggy <3319867+moonbuggy@users.noreply.github.com> Date: Thu, 5 Oct 2023 04:00:52 +1100 Subject: [PATCH 2/6] updated driver.list.in Signed-off-by: moonbuggy <3319867+moonbuggy@users.noreply.github.com> --- data/driver.list.in | 1 + 1 file changed, 1 insertion(+) diff --git a/data/driver.list.in b/data/driver.list.in index ac613778c6..d1eb3951e2 100644 --- a/data/driver.list.in +++ b/data/driver.list.in @@ -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" From 8e496b33e8c2a609ed4eb046f1d8b83a7b7b1760 Mon Sep 17 00:00:00 2001 From: moonbuggy <3319867+moonbuggy@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:56:41 +1100 Subject: [PATCH 3/6] use short instead of long/float Signed-off-by: moonbuggy <3319867+moonbuggy@users.noreply.github.com> --- drivers/optiups.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/optiups.c b/drivers/optiups.c index 4814b48af9..62cfa98aa4 100644 --- a/drivers/optiups.c +++ b/drivers/optiups.c @@ -488,22 +488,22 @@ void upsdrv_updateinfo(void) optifill( _pollv_ps, sizeof(_pollv_ps)/sizeof(_pollv_ps[0]) ); r = optiquery( "NV" ); - float inV = strtol ( _buf, NULL, 10); + short inV = atoi ( _buf ); r = optiquery( "OV" ); - float outV = strtol ( _buf, NULL, 10); + short outV = atoi ( _buf ); r = optiquery( "FV" ); if ( r >= 1 ) { - float f = strtol ( _buf, NULL, 10 ); + short f = atoi ( _buf ); if ( f > 180 ) { inV = inV * 2; outV = outV * 2; } } - dstate_setinfo( "input.voltage", "%.1f", inV ); - dstate_setinfo( "output.voltage", "%.1f", outV ); + dstate_setinfo( "input.voltage", "%d", inV ); + dstate_setinfo( "output.voltage", "%d", outV ); } else optifill( _pollv, sizeof(_pollv)/sizeof(_pollv[0]) ); From 45e40b04e1750130497530f74c504636fe5765d0 Mon Sep 17 00:00:00 2001 From: moonbuggy <3319867+moonbuggy@users.noreply.github.com> Date: Thu, 5 Oct 2023 19:46:10 +1100 Subject: [PATCH 4/6] use str_to_short() instead of atoi() Signed-off-by: moonbuggy <3319867+moonbuggy@users.noreply.github.com> --- drivers/optiups.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/optiups.c b/drivers/optiups.c index 62cfa98aa4..02ec2f1182 100644 --- a/drivers/optiups.c +++ b/drivers/optiups.c @@ -487,16 +487,18 @@ void upsdrv_updateinfo(void) else if ( optimodel == OPTIMODEL_PS ) { optifill( _pollv_ps, sizeof(_pollv_ps)/sizeof(_pollv_ps[0]) ); + short inV, outV, fV; + r = optiquery( "NV" ); - short inV = atoi ( _buf ); + str_to_short ( _buf, &inV, 10 ); r = optiquery( "OV" ); - short outV = atoi ( _buf ); + str_to_short ( _buf, &outV, 10 ); r = optiquery( "FV" ); if ( r >= 1 ) { - short f = atoi ( _buf ); - if ( f > 180 ) + str_to_short ( _buf, &fV, 10 ); + if ( fV > 180 ) { inV = inV * 2; outV = outV * 2; From 9327fa5b8dca493f312e0e306f73a19d42b97ae6 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Thu, 5 Oct 2023 11:45:41 +0200 Subject: [PATCH 5/6] drivers/optiups.c: Shuffle lines to keep declarations before operations Signed-off-by: Jim Klimov --- drivers/optiups.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/optiups.c b/drivers/optiups.c index 02ec2f1182..35f1005361 100644 --- a/drivers/optiups.c +++ b/drivers/optiups.c @@ -485,10 +485,10 @@ void upsdrv_updateinfo(void) 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]) ); - 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" ); From 26bf63d5af0d2ca2d457e780f4497e95f0168890 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Fri, 6 Oct 2023 05:21:59 +0200 Subject: [PATCH 6/6] NEWS.adoc: optiups fixes [#2089] Signed-off-by: Jim Klimov --- NEWS.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS.adoc b/NEWS.adoc index de559cf130..b640d8f1d0 100644 --- a/NEWS.adoc +++ b/NEWS.adoc @@ -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