|
44 | 44 | #endif |
45 | 45 |
|
46 | 46 | #define DRIVER_NAME "NUT APC Modbus driver " DRIVER_NAME_NUT_MODBUS_HAS_USB_WITH_STR " USB support (libmodbus link type: " NUT_MODBUS_LINKTYPE_STR ")" |
47 | | -#define DRIVER_VERSION "0.19" |
| 47 | +#define DRIVER_VERSION "0.20" |
48 | 48 |
|
49 | 49 | #if defined NUT_MODBUS_HAS_USB |
50 | 50 |
|
@@ -695,6 +695,7 @@ static int _apc_modbus_string_join(const char *values[], size_t values_len, cons |
695 | 695 | } |
696 | 696 |
|
697 | 697 | output_idx = 0; |
| 698 | + output[0] = 0; /* Always zero terminate */ |
698 | 699 |
|
699 | 700 | for (i = 0; i < values_len && output_idx < output_len; i++) { |
700 | 701 | if (values[i] == NULL) |
@@ -771,6 +772,69 @@ static int _apc_modbus_battery_test_status_to_nut(const apc_modbus_value_t *valu |
771 | 772 |
|
772 | 773 | static apc_modbus_converter_t _apc_modbus_battery_test_status_conversion = { _apc_modbus_battery_test_status_to_nut, NULL }; |
773 | 774 |
|
| 775 | +static int _apc_modbus_runtime_calibration_status_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len) |
| 776 | +{ |
| 777 | + const char *result, *source, *modifier; |
| 778 | + const char *values[3]; |
| 779 | + |
| 780 | + if (value == NULL || output == NULL || output_len == 0) { |
| 781 | + /* Invalid parameters */ |
| 782 | + return 0; |
| 783 | + } |
| 784 | + |
| 785 | + if (value->type != APC_VT_UINT) { |
| 786 | + return 0; |
| 787 | + } |
| 788 | + |
| 789 | + result = NULL; |
| 790 | + if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_PENDING)) { |
| 791 | + result = "Pending"; |
| 792 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_INPROGRESS)) { |
| 793 | + result = "InProgress"; |
| 794 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_PASSED)) { |
| 795 | + result = "Passed"; |
| 796 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_FAILED)) { |
| 797 | + result = "Failed"; |
| 798 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_REFUSED)) { |
| 799 | + result = "Refused"; |
| 800 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_ABORTED)) { |
| 801 | + result = "Aborted"; |
| 802 | + } |
| 803 | + |
| 804 | + source = NULL; |
| 805 | + if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_PROTOCOL)) { |
| 806 | + source = "Source: Protocol"; |
| 807 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_LOCALUI)) { |
| 808 | + source = "Source: LocalUI"; |
| 809 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_SOURCE_INTERNAL)) { |
| 810 | + source = "Source: Internal"; |
| 811 | + } |
| 812 | + |
| 813 | + modifier = NULL; |
| 814 | + if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_INVALIDSTATE)) { |
| 815 | + modifier = "Modifier: InvalidState"; |
| 816 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_INTERNALFAULT)) { |
| 817 | + modifier = "Modifier: InternalFault"; |
| 818 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_STATEOFCHARGENOTACCEPTABLE)) { |
| 819 | + modifier = "Modifier: StateOfChargeNotAcceptable"; |
| 820 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_LOADCHANGE)) { |
| 821 | + modifier = "Modifier: LoadChange"; |
| 822 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_ACINPUTNOTACCEPTABLE)) { |
| 823 | + modifier = "Modifier: ACInputNotAcceptable"; |
| 824 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_LOADTOOLOW)) { |
| 825 | + modifier = "Modifier: LoadTooLow"; |
| 826 | + } else if ((value->data.uint_value & APC_MODBUS_RUNTIMECALIBRATIONSTATUS_BF_MOD_OVERCHARGEINPROGRESS)) { |
| 827 | + modifier = "Modifier: OverChargeInProgress"; |
| 828 | + } |
| 829 | + |
| 830 | + values[0] = result; |
| 831 | + values[1] = source; |
| 832 | + values[2] = modifier; |
| 833 | + return _apc_modbus_string_join(values, SIZEOF_ARRAY(values), ", ", output, output_len); |
| 834 | +} |
| 835 | + |
| 836 | +static apc_modbus_converter_t _apc_modbus_runtime_calibration_status_conversion = { _apc_modbus_runtime_calibration_status_to_nut, NULL }; |
| 837 | + |
774 | 838 | static const time_t apc_date_start_offset = 946684800; /* 2000-01-01 00:00 */ |
775 | 839 |
|
776 | 840 | static int _apc_modbus_date_to_nut(const apc_modbus_value_t *value, char *output, size_t output_len) |
@@ -889,6 +953,7 @@ static apc_modbus_register_t apc_modbus_register_map_inventory[] = { |
889 | 953 | static apc_modbus_register_t apc_modbus_register_map_status[] = { |
890 | 954 | { "input.transfer.reason", 2, 1, APC_VT_UINT, APC_VF_NONE, &_apc_modbus_status_change_cause_conversion, NULL, 0, NULL }, |
891 | 955 | { "ups.test.result", 23, 1, APC_VT_UINT, APC_VF_NONE, &_apc_modbus_battery_test_status_conversion, NULL, 0, NULL }, |
| 956 | + { "experimental.ups.calibration.result", 24, 1, APC_VT_UINT, APC_VF_NONE, &_apc_modbus_runtime_calibration_status_conversion, NULL, 0, NULL }, |
892 | 957 | { NULL, 0, 0, APC_VT_INT, APC_VF_NONE, NULL, NULL, 0.0f, NULL } |
893 | 958 | }; |
894 | 959 |
|
|
0 commit comments