Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ https://github.com/networkupstools/nut/milestone/13

- `apc_modbus` driver updates:
* Fixed string join not doing zero termination. [PR #3413]
* Decode `RunTimeCalibrationStatus_BF` into
`experimental.ups.calibration.result` [PR #3416]

- NUT client libraries:
* Complete support for actions documented in `docs/net-protocol.txt`
Expand Down
3 changes: 2 additions & 1 deletion docs/nut.dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 3734 utf-8
personal_ws-1.1 en 3735 utf-8
AAC
AAS
ABI
Expand Down Expand Up @@ -1160,6 +1160,7 @@ Rouben
Rozman
Rucelf
RunAs
RunTimeCalibrationStatus
RunUPSCommand
RxD
Ryabov
Expand Down
64 changes: 64 additions & 0 deletions drivers/apc_modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,69 @@ static int _apc_modbus_battery_test_status_to_nut(const apc_modbus_value_t *valu

static apc_modbus_converter_t _apc_modbus_battery_test_status_conversion = { _apc_modbus_battery_test_status_to_nut, NULL };

static int _apc_modbus_runtime_calibration_status_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len)
{
const char *result, *source, *modifier;
const char *values[3];

if (value == NULL || output == NULL || output_len == 0) {
/* Invalid parameters */
return 0;
}

if (value->type != APC_VT_UINT) {
return 0;
}

result = NULL;
if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_PENDING)) {
result = "Pending";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_INPROGRESS)) {
result = "InProgress";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_PASSED)) {
result = "Passed";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_FAILED)) {
result = "Failed";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_REFUSED)) {
result = "Refused";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_ABORTED)) {
result = "Aborted";
}

source = NULL;
if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_PROTOCOL)) {
source = "Source: Protocol";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_LOCALUI)) {
source = "Source: LocalUI";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_INTERNAL)) {
source = "Source: Internal";
}

modifier = NULL;
if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_INVALIDSTATE)) {
modifier = "Modifier: InvalidState";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_INTERNALFAULT)) {
modifier = "Modifier: InternalFault";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_STATEOFCHARGENOTACCEPTABLE)) {
modifier = "Modifier: StateOfChargeNotAcceptable";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_LOADCHANGE)) {
modifier = "Modifier: LoadChange";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_ACINPUTNOTACCEPTABLE)) {
modifier = "Modifier: ACInputNotAcceptable";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_LOADTOOLOW)) {
modifier = "Modifier: LoadTooLow";
} else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_OVERCHARGEINPROGRESS)) {
modifier = "Modifier: OverChargeInProgress";
}

values[0] = result;
values[1] = source;
values[2] = modifier;
return _apc_modbus_string_join(values, SIZEOF_ARRAY(values), ", ", output, output_len);
}

static apc_modbus_converter_t _apc_modbus_runtime_calibration_status_conversion = { _apc_modbus_runtime_calibration_status_to_nut, NULL };

static const time_t apc_date_start_offset = 946684800; /* 2000-01-01 00:00 */

static int _apc_modbus_date_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len)
Expand Down Expand Up @@ -890,6 +953,7 @@ static apc_modbus_register_t apc_modbus_register_map_inventory[] = {
static apc_modbus_register_t apc_modbus_register_map_status[] = {
{ "input.transfer.reason", 2, 1, APC_VT_UINT, APC_VF_NONE, &_apc_modbus_status_change_cause_conversion, NULL, 0, NULL },
{ "ups.test.result", 23, 1, APC_VT_UINT, APC_VF_NONE, &_apc_modbus_battery_test_status_conversion, NULL, 0, NULL },
{ "experimental.ups.calibration.result", 24, 1, APC_VT_UINT, APC_VF_NONE, &_apc_modbus_runtime_calibration_status_conversion, NULL, 0, NULL },
{ NULL, 0, 0, APC_VT_INT, APC_VF_NONE, NULL, NULL, 0.0f, NULL }
};

Expand Down
19 changes: 19 additions & 0 deletions drivers/apc_modbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@
#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_INTERNALFAULT (1 << 10)
#define APC_MODBUS_REPLACEBATTERYTESTSTATUS_BF_MOD_STATEOFCHARGENOTACCEPTABLE (1 << 11)

/* RunTimeCalibrationStatus_BF register bits (register 24 in status block)
* See MPAO-98KJ7F_R1_EN Appendix B */
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_PENDING (1 << 0)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_INPROGRESS (1 << 1)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_PASSED (1 << 2)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_FAILED (1 << 3)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_REFUSED (1 << 4)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_ABORTED (1 << 5)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_PROTOCOL (1 << 6)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_LOCALUI (1 << 7)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_INTERNAL (1 << 8)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_INVALIDSTATE (1 << 9)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_INTERNALFAULT (1 << 10)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_STATEOFCHARGENOTACCEPTABLE (1 << 11)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_LOADCHANGE (1 << 12)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_ACINPUTNOTACCEPTABLE (1 << 13)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_LOADTOOLOW (1 << 14)
#define APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_OVERCHARGEINPROGRESS (1 << 15)

#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_REG 590
#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_MOG_PRESENT (1 << 0)
#define APC_MODBUS_SOGRELAYCONFIGSETTING_BF_SOG_0_PRESENT (1 << 1)
Expand Down
Loading