Skip to content

Commit 650fa5f

Browse files
authored
Merge pull request #3268 from jimklimov/issue-2766
Several small fixes contributed out of PR stream
2 parents 23e52d0 + 161b3a5 commit 650fa5f

File tree

5 files changed

+100
-12
lines changed

5 files changed

+100
-12
lines changed

NEWS.adoc

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,11 @@ https://github.com/networkupstools/nut/milestone/12
212212
ignore any useful reports, and that we successfully use reasonably many
213213
of the existing mappings. Suggest how user can help improve the driver
214214
if too few data points were seen. [#3082, #3095]
215+
* `cps-hid` updated with Replace Battery information. [PR #3268]
215216
* `openups-hid` had `nobattery` definition inverted, causing alarms -- now
216217
fixed to use the same mapping helper as other subdrivers. [issue #3246]
218+
* `powercom-hid` subdriver improved with a `powercom_hack_voltage_lkp` to
219+
query `battery.voltage`. [issue #2766]
217220
* Improved handling of transient `LIBUSB_ERROR_IO` failures during polling.
218221
Some devices (CyberPower, etc.) have firmware bugs causing random I/O
219222
errors on certain HID reports. The driver now skips failing reports and
@@ -377,16 +380,18 @@ several `FSD` notifications into one executed action. [PR #3097]
377380
include the source distribution (was posted for NUT v2.8.1 and v2.8.2
378381
tagged releases, but absent for v2.8.3 and v2.8.4). [#3056]
379382
* Updated `make spellcheck` to help avoid asciidoc admonition blocks with
380-
visually invalid sentences (after rendering as a box in HTML or PDF). [#3077]
381-
* Added a `make dist-docs` goal to generate, collect and tarball all document
382-
types (`man`, `html-single`, `html-chunked`, `pdf`) that we may have enabled
383-
for the current build configuration and available tooling. [#1400]
383+
visually invalid sentences (after rendering as a box in HTML or PDF).
384+
[#3077]
385+
* Added a `make dist-docs` goal to generate, collect and tarball all
386+
document types (`man`, `html-single`, `html-chunked`, `pdf`) that we
387+
may have enabled for the current build configuration and available
388+
tooling. [#1400]
384389
* Further developer workflow speedup with `make spellcheck-interactive-quick`
385390
which should now not re-check source texts that were okay with the previous
386391
dictionary contents, in case some new terms have to be added. [PRs #3186,
387392
#2871]
388-
* Introduced `make distcheck-completeness` goal to verify that our distribution
389-
archives can exactly reproduce themselves. [#2829]
393+
* Introduced `make distcheck-completeness` goal to verify that our
394+
distribution archives can exactly reproduce themselves. [#2829]
390395
* Added a GitHub Actions CI job to generate, upload and recycle `make dist`
391396
and `make dist-docs` tarballs so they are easier to obtain for people and
392397
other CI systems (which might not want to follow a Git repository). Links

docs/nut.dict

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
personal_ws-1.1 en 3631 utf-8
1+
personal_ws-1.1 en 3632 utf-8
22
AAC
33
AAS
44
ABI
@@ -438,7 +438,6 @@ GITREV
438438
GND
439439
GNUmakefile
440440
GObject
441-
GoldenMate
442441
GPIO
443442
GPL
444443
GPLv
@@ -472,6 +471,7 @@ GitHub's
472471
Gnomovision
473472
GnuTLS
474473
Goebl
474+
GoldenMate
475475
Gomes
476476
Goncalves
477477
Gordeev
@@ -2496,6 +2496,7 @@ listsnapshots
24962496
littleguy
24972497
livedata
24982498
lk
2499+
lkp
24992500
lldb
25002501
llvm
25012502
lm

drivers/cps-hid.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include "cps-hid.h"
3333
#include "usb-common.h"
3434

35-
#define CPS_HID_VERSION "CyberPower HID 0.84"
35+
#define CPS_HID_VERSION "CyberPower HID 0.85"
3636

3737
/* Cyber Power Systems */
3838
#define CPS_VENDORID 0x0764
@@ -398,6 +398,7 @@ static hid_info_t cps_hid2nut[] = {
398398
{ "BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.BelowRemainingCapacityLimit", NULL, NULL, HU_FLAG_QUICK_POLL, lowbatt_info },
399399
{ "BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.FullyCharged", NULL, NULL, 0, fullycharged_info },
400400
{ "BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.RemainingTimeLimitExpired", NULL, NULL, 0, timelimitexpired_info },
401+
{ "BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.NeedReplacement", NULL, NULL, 0, replacebatt_info },
401402
{ "BOOL", 0, 0, "UPS.Output.Boost", NULL, NULL, 0, boost_info },
402403
{ "BOOL", 0, 0, "UPS.Output.Overload", NULL, NULL, 0, overload_info },
403404

drivers/powercom-hid.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
#include "powercom-hid.h"
2727
#include "usb-common.h"
2828

29-
#define POWERCOM_HID_VERSION "PowerCOM HID 0.72"
29+
#include <ctype.h> /* isdigit() */
30+
31+
#define POWERCOM_HID_VERSION "PowerCOM HID 0.73"
3032
/* FIXME: experimental flag to be put in upsdrv_info */
3133

3234
/* PowerCOM */
@@ -382,6 +384,78 @@ static info_lkp_t powercom_overload_conversion[] = {
382384
{ 0, NULL, powercom_overload_conversion_fun, NULL }
383385
};
384386

387+
/* FAIL-SAFE HACK (proper solution welcome) as proposed in
388+
* https://github.com/networkupstools/nut/issues/2766#issuecomment-3751553822 :
389+
* Use global udev handle from usbhid-ups.h for a custom conversion function
390+
* that reads Report 0xa4 directly via generic USB call. Formally this is
391+
* now triggered by a read of ACPresent which is always served, and ends
392+
* up requesting another report instead.
393+
*/
394+
static const char *powercom_hack_voltage(double value)
395+
{
396+
static char buf[32];
397+
static char last_valid[32] = "0.0"; /* Cache last valid reading */
398+
usb_ctrl_char data[8];
399+
int ret, retry, max_retries = 1;
400+
401+
/* We do not care for ACPresent reading received here */
402+
NUT_UNUSED_VARIABLE(value);
403+
404+
/* Global 'udev' is defined in usbhid-ups.h and initialized by main driver */
405+
if (!udev)
406+
return last_valid;
407+
408+
/* If we don't have a valid value yet (driver startup), try harder to get one */
409+
if (!strcmp(last_valid, "0.0")) {
410+
/* Retry up to 5 times (approx 0.5s) */
411+
max_retries = 5;
412+
}
413+
414+
for (retry = 0; retry < max_retries; retry++) {
415+
/* Portable read of Report 0xa4 (Feature) using NUT's wrapper */
416+
/* 0xA1: Dir=IN, Type=Class, Recp=Interface */
417+
ret = usb_control_msg(udev, 0xA1, 0x01, (0x03 << 8) | 0xa4, 0, data, sizeof(data), 1000);
418+
419+
if (ret > 0) {
420+
char msg[32], *start, *end;
421+
int len = (ret > 8) ? 8 : ret;
422+
int j = 0, i;
423+
424+
/* Skip byte 0 (Report ID) */
425+
for (i=1; i<len; i++) {
426+
msg[j++] = (char)data[i];
427+
}
428+
msg[j] = '\0';
429+
430+
/* Parse " 13.7 2" -> "13.7" */
431+
start = msg;
432+
while (*start && !isdigit((unsigned char)(*start)) && *start != '.') {
433+
start++;
434+
}
435+
end = start;
436+
while (*end && (isdigit((unsigned char)(*end)) || *end == '.')) {
437+
end++;
438+
}
439+
*end = '\0';
440+
441+
/* VALIDATION */
442+
if (strlen(start) > 0 && strchr(start, '.') != NULL) {
443+
snprintf(buf, sizeof(buf), "%s", start);
444+
snprintf(last_valid, sizeof(last_valid), "%s", start);
445+
return buf;
446+
}
447+
}
448+
if (max_retries > 1) {
449+
usleep(100000);
450+
}
451+
}
452+
return last_valid;
453+
}
454+
455+
static info_lkp_t powercom_hack_voltage_lkp[] = {
456+
{ 0, NULL, powercom_hack_voltage, NULL }
457+
};
458+
385459
/* --------------------------------------------------------------- */
386460
/* Vendor-specific usage table */
387461
/* --------------------------------------------------------------- */
@@ -465,6 +539,13 @@ static hid_info_t powercom_hid2nut[] = {
465539
* { "battery.voltage.nominal", 0, 0, "UPS.PowerSummary.ConfigVoltage", NULL, "%.0f", HU_FLAG_STATIC, NULL },
466540
* { "battery.voltage.nominal", 0, 0, "UPS.Battery.ConfigVoltage", NULL, "%.0f", HU_FLAG_STATIC, NULL },
467541
*/
542+
/* HACK (proper fix welcome): Formally we map battery.voltage
543+
* to *ACPresent* (Report 0x0a) which is always present.
544+
* But then we use our HACK conversion function to ignore the
545+
* passed value, and read and interpret Report 0xa4 instead!
546+
*/
547+
{ "battery.voltage", 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", NULL, "%s", 0, powercom_hack_voltage_lkp },
548+
468549
{ "battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", NULL, "%.0f", 0, NULL },
469550
{ "battery.charge", 0, 0, "UPS.Battery.RemainingCapacity", NULL, "%.0f", 0, NULL },
470551
{ "battery.charge.low", 0, 0, "UPS.PowerSummary.RemainingCapacityLimit", NULL, "%.0f", 0, NULL },

scripts/upower/95-upower-hid.hwdb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ usb:v06DApFFFF*
9393
UPOWER_BATTERY_TYPE=ups
9494
UPOWER_VENDOR=Phoenixtec Power Co., Ltd
9595

96-
# iDowell
96+
# iDowell, Goldenmate
9797
usb:v075Dp0300*
9898
UPOWER_BATTERY_TYPE=ups
99-
UPOWER_VENDOR=iDowell
99+
UPOWER_VENDOR=iDowell, Goldenmate
100100

101101
# Cyber Power Systems
102102
usb:v0764p0005*

0 commit comments

Comments
 (0)