-
-
Notifications
You must be signed in to change notification settings - Fork 396
Description
I have RAPTOR RPT-1500AP LCD on my linux server and default powercom driver doesn't work with it. I've done a lot of experiments for a several weeks, and i can say that RPT series have the same usb protocol like Smart KING Pro series. In this protocol, we can't set arbitrary value of shutdown delay in seconds like in other powercom upses, shutdown delay can be set only from table "Table of possible delays for Shutdown commands" specified at page 17: https://networkupstools.org/protocols/powercom/Software_USB_communication_controller_SKP_series.doc.
I checked this by changing the powercom-hid.c driver. I changed function "powercom_shutdown_nuf" so it set "command" variable value from func input(fast bypass :D). After changing, i compiled it and execute ./upscmd -u username -p password powercom1 shutdown.return 8
and ups start beeping and turned off exactly after 54 seconds:
static double powercom_shutdown_nuf(const char *value)
{
const char *s = dstate_getinfo("ups.delay.shutdown");
uint8_t val, command;
int iv;
iv = atoi(value ? value : s);
if (iv < 0 || (intmax_t)iv > (intmax_t)UINT8_MAX) {
upsdebugx(0, "%s: value = %d is not in uint16_t range", __func__, iv);
return 0;
}
command = (uint8_t)iv;
// val = (uint16_t)iv;
// val = val ? val : 1; /* 0 sets the maximum delay */
// if (powercom_sdcmd_byte_order_fallback) {
// /* Legacy behavior */
// command = ((uint16_t)((val % 60) << 8)) + (uint16_t)(val / 60);
// command |= 0x4000; /* AC RESTART NORMAL ENABLE */
// } else {
// /* New default */
// command = ((uint16_t)((val / 60) << 8)) + (uint16_t)(val % 60);
// command |= 0x0040; /* AC RESTART NORMAL ENABLE */
// }
upsdebugx(3, "%s: value = %s, command = %02X", __func__, value, command);
return command;
}
The same issue with "powercom_stayoff_nuf" function:
static double powercom_stayoff_nuf(const char *value)
{
const char *s = dstate_getinfo("ups.delay.shutdown");
uint16_t val, command;
int iv;
iv = atoi(value ? value : s);
if (iv < 0 || (intmax_t)iv > (intmax_t)UINT16_MAX) {
upsdebugx(0, "%s: value = %d is not in uint16_t range", __func__, iv);
return 0;
}
val = (uint16_t)iv;
val = val ? val : 1; /* 0 sets the maximum delay */
if (powercom_sdcmd_byte_order_fallback) {
/* Legacy behavior */
command = ((uint16_t)((val % 60) << 8)) + (uint16_t)(val / 60);
command |= 0x8000; /* AC RESTART NORMAL DISABLE */
} else {
/* New default */
command = ((uint16_t)((val / 60) << 8)) + (uint16_t)(val % 60);
command |= 0x0080; /* AC RESTART NORMAL DISABLE */
}
upsdebugx(3, "%s: value = %s, command = %04X", __func__, value, command);
return command;
}
Also, the "powercom_startup_nuf" function doesn't work either. Worked version:
static double powercom_startup_nuf(const char *value)
{
const char *s = dstate_getinfo("ups.delay.start");
uint32_t val, command;
int iv;
//iv = atoi(value ? value : s) / 60;
iv = atoi(value ? value : s);
if (iv < 0 || (intmax_t)iv > (intmax_t)UINT32_MAX) {
upsdebugx(0, "%s: value = %d is not in uint16_t range", __func__, iv);
return 0;
}
/* COMMENTME: What are we doing here, a byte-swap in the word? */
// val = (uint16_t)iv;
// command = (uint16_t)(val << 8);
// command += (uint16_t)(val >> 8);
command = (uint32_t)iv;
upsdebugx(3, "%s: value = %s, command = %04X", __func__, value, command);
return command;
}
After compile, if i execute ./upscmd -u username -p password powercom1 load.on.delay X
- in case of powered off ups and the presence of the input voltage, it will turn on after 1minute + X seconds (Idk why, but it`s work).
I found this bugs 2 month ago, but i haven't time to create issue, so maybe I missed some details.
lsusb log: