|
32 | 32 | #endif
|
33 | 33 |
|
34 | 34 | #define DRIVER_NAME "NUT PhoenixContact Modbus driver (libmodbus link type: " NUT_MODBUS_LINKTYPE_STR ")"
|
35 |
| - #define DRIVER_VERSION "0.1" |
| 35 | + #define DRIVER_VERSION "0.09" |
36 | 36 |
|
37 | 37 | #define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
38 | 38 | #define MODBUS_SLAVE_ID 192
|
|
73 | 73 |
|
74 | 74 | /* --- Shutdown & Mode Configuration --- */
|
75 | 75 |
|
76 |
| - // Macro for fetching a uint16_t config value with fallback |
| 76 | + /* Macro for fetching a uint16_t config value with fallback*/ |
77 | 77 | #define GETVAL_U16(name, fallback) (getval(name) ? (uint16_t)atoi(getval(name)) : (fallback))
|
78 | 78 |
|
79 |
| - // Time [s] after entering battery mode before shutdown signal (bit 15) is triggered |
80 |
| - #define REG_PC_SHUTDOWN_DELAY 0x105A // default: 60s, range: 1–65535 |
| 79 | + /* Time [s] after entering battery mode before shutdown signal (bit 15) is triggered */ |
| 80 | + #define REG_PC_SHUTDOWN_DELAY 0x105A /*default: 60s, range: 1–65535*/ |
81 | 81 |
|
82 |
| - // Time [s] allowed for PC to shut down before output turns off |
83 |
| - #define REG_PC_SHUTDOWN_TIME 0x105D // default: 120s, range: 1–3600 |
| 82 | + /*Time [s] allowed for PC to shut down before output turns off*/ |
| 83 | + #define REG_PC_SHUTDOWN_TIME 0x105D /*default: 120s, range: 1–3600*/ |
84 | 84 |
|
85 |
| - // Time [s] output is off after PC shutdown before reboot |
86 |
| - #define REG_PC_RESET_TIME 0x105E // default: 10s, range: 0–60 |
| 85 | + /*Time [s] output is off after PC shutdown before reboot*/ |
| 86 | + #define REG_PC_RESET_TIME 0x105E /*default: 10s, range: 0–60*/ |
87 | 87 |
|
88 |
| - // Time [s] input voltage must be above threshold to return to mains |
89 |
| - #define REG_MAINS_RETURN_DELAY 0x1058 // default: 10s |
| 88 | + /*Time [s] input voltage must be above threshold to return to mains*/ |
| 89 | + #define REG_MAINS_RETURN_DELAY 0x1058 /*default: 10s*/ |
90 | 90 |
|
91 |
| - // Selector mode switch: PC-Mode = 9 |
92 |
| - #define REG_MODE_SELECTOR_SWITCH 0x1074 // default: 0–9 |
| 91 | + /*Selector mode switch: PC-Mode = 9*/ |
| 92 | + #define REG_MODE_SELECTOR_SWITCH 0x1074 /*default: 0–9*/ |
93 | 93 |
|
94 | 94 | /* --- Battery Monitoring --- */
|
95 | 95 |
|
96 |
| - // SOH warning threshold [%] |
97 |
| - #define REG_WARNING_SOH_THRESHOLD 0x1071 // default: 0 (disabled), range: 1–100 |
| 96 | + /*SOH warning threshold [%]*/ |
| 97 | + #define REG_WARNING_SOH_THRESHOLD 0x1071 /*default: 0 (disabled), range: 1–100*/ |
98 | 98 |
|
99 |
| - // Switch to battery mode if below this input voltage [mV] |
100 |
| - #define REG_VOLTAGE_BELOW_BATTERY 0x1056 // example: 21000 |
| 99 | + /*Switch to battery mode if below this input voltage [mV]*/ |
| 100 | + #define REG_VOLTAGE_BELOW_BATTERY 0x1056 /*example: 21000*/ |
101 | 101 |
|
102 |
| - // Switch to mains mode if above this voltage [mV] |
103 |
| - #define REG_VOLTAGE_ABOVE_MAINS 0x1057 // example: 23000 |
| 102 | + /*Switch to mains mode if above this voltage [mV]*/ |
| 103 | + #define REG_VOLTAGE_ABOVE_MAINS 0x1057 /*example: 23000*/ |
104 | 104 |
|
105 | 105 | typedef enum
|
106 | 106 | {
|
|
126 | 126 |
|
127 | 127 | static const delay_param_t delay_params[] = {
|
128 | 128 | { "ups.delay.shutdown", REG_PC_SHUTDOWN_DELAY},
|
129 |
| - { "ups.delay.pc_shutdown", REG_PC_SHUTDOWN_TIME}, |
130 |
| - { "ups.delay.pc_reset", REG_PC_RESET_TIME}, |
131 |
| - { "ups.delay.mains_return", REG_MAINS_RETURN_DELAY}, |
| 129 | + { "ups.timer.shutdown", REG_PC_SHUTDOWN_TIME}, |
| 130 | + { "ups.timer.start", REG_PC_RESET_TIME}, |
| 131 | + { "ups.delay.start", REG_MAINS_RETURN_DELAY}, |
132 | 132 | { "ups.mode.selector", REG_MODE_SELECTOR_SWITCH},
|
133 |
| - { "ups.bat.warning_soh", REG_WARNING_SOH_THRESHOLD}, |
134 |
| - { "ups.bat.voltage_low", REG_VOLTAGE_BELOW_BATTERY}, |
135 |
| - { "ups.mains.voltage_high", REG_VOLTAGE_ABOVE_MAINS } |
| 133 | + { "battery.warning_soh", REG_WARNING_SOH_THRESHOLD}, |
| 134 | + { "input.voltage.low.critical", REG_VOLTAGE_BELOW_BATTERY}, |
| 135 | + { "input.voltage.high.critical", REG_VOLTAGE_ABOVE_MAINS } |
136 | 136 | };
|
137 | 137 |
|
138 | 138 |
|
|
148 | 148 | upsdrv_info_t upsdrv_info = {
|
149 | 149 | DRIVER_NAME,
|
150 | 150 | DRIVER_VERSION,
|
151 |
| - "Ulfat Hasangarayev <ulfathasangarayev@gmail.com>\n", |
| 151 | + "Spiros Ioannou <sivann@inaccess.com>\n", |
152 | 152 | DRV_BETA,
|
153 | 153 | {NULL}
|
154 | 154 | };
|
155 | 155 |
|
156 | 156 | int write_uint32_register(modbus_t *ctx, int reg, uint32_t value)
|
157 | 157 | {
|
158 | 158 | uint16_t regs[2];
|
159 |
| - regs[0] = value >> 16; // High word |
160 |
| - regs[1] = value & 0xFFFF; // Low word |
| 159 | + regs[0] = value >> 16; /*High word*/ |
| 160 | + regs[1] = value & 0xFFFF; /*Low word*/ |
161 | 161 |
|
162 | 162 | int ret = modbus_write_registers(ctx, reg, 2, regs);
|
163 | 163 | if (ret == -1) {
|
|
170 | 170 | int write_uint32_reg_bit(modbus_t *ctx, int reg, int bit_index, bool bit_value)
|
171 | 171 | {
|
172 | 172 | uint16_t regs[2];
|
| 173 | + uint32_t val; |
| 174 | + |
173 | 175 | if (modbus_read_registers(ctx, reg, 2, regs) != 2) {
|
174 | 176 | upslogx(LOG_ERR, "Failed to read 32-bit register 0x%04X: %s", reg, modbus_strerror(errno));
|
175 | 177 | return -1;
|
176 | 178 | }
|
177 | 179 |
|
178 |
| - uint32_t val = ((uint32_t)regs[0] << 16) | regs[1]; |
| 180 | + val = ((uint32_t)regs[0] << 16) | regs[1]; |
179 | 181 |
|
180 | 182 | if (bit_value)
|
181 | 183 | val |= (1U << bit_index);
|
|
198 | 200 |
|
199 | 201 | write_uint32_reg_bit(ctx, 0x1040, 5, false);
|
200 | 202 |
|
201 |
| - modbus_write_register(ctx, REG_PC_SHUTDOWN_DELAY, GETVAL_U16("delay.shutdown", 60)); |
202 |
| - modbus_write_register(ctx, REG_PC_SHUTDOWN_TIME, GETVAL_U16("delay.pc_shutdown", 60)); |
203 |
| - modbus_write_register(ctx, REG_PC_RESET_TIME, GETVAL_U16("delay.pc_reset", 5)); |
204 |
| - modbus_write_register(ctx, REG_WARNING_SOH_THRESHOLD, GETVAL_U16("bat.warning_soh", 20)); |
205 |
| - modbus_write_register(ctx, REG_MODE_SELECTOR_SWITCH, GETVAL_U16("mode.selector", 9)); |
206 |
| - modbus_write_register(ctx, REG_VOLTAGE_BELOW_BATTERY, GETVAL_U16("bat.voltage_low", 21000)); |
207 |
| - modbus_write_register(ctx, REG_VOLTAGE_ABOVE_MAINS, GETVAL_U16("mains.voltage_high", 23000)); |
208 |
| - modbus_write_register(ctx, REG_MAINS_RETURN_DELAY, GETVAL_U16("mains.return_delay", 10)); |
| 203 | + modbus_write_register(ctx, REG_PC_SHUTDOWN_DELAY, GETVAL_U16("delay.shutdown", 60)); |
| 204 | + modbus_write_register(ctx, REG_PC_SHUTDOWN_TIME, GETVAL_U16("timer.shutdown", 60)); |
| 205 | + modbus_write_register(ctx, REG_PC_RESET_TIME, GETVAL_U16("timer.start", 5)); |
| 206 | + modbus_write_register(ctx, REG_WARNING_SOH_THRESHOLD, GETVAL_U16("battery.warning_soh", 20)); |
| 207 | + modbus_write_register(ctx, REG_MODE_SELECTOR_SWITCH, GETVAL_U16("mode.selector", 9)); |
| 208 | + modbus_write_register(ctx, REG_VOLTAGE_BELOW_BATTERY, GETVAL_U16("voltage.low.critical", 21000)); |
| 209 | + modbus_write_register(ctx, REG_VOLTAGE_ABOVE_MAINS, GETVAL_U16("voltage.high.critical", 29000)); |
| 210 | + modbus_write_register(ctx, REG_MAINS_RETURN_DELAY, GETVAL_U16("delay.start", 10)); |
209 | 211 |
|
210 | 212 | /* the value 0xFFFDFFFF sets bit 17 low so that the mode selector switch is overwritten in software */
|
211 | 213 | write_uint32_register(ctx, 0x1076, 0xFFFDFFFF);
|
|
232 | 234 |
|
233 | 235 | mrir(modbus_ctx, 0x0005, 4, tab_reg);
|
234 | 236 |
|
235 |
| - /* Method provided from Phoenix Conatct to establish the UPS model: |
| 237 | + /* |
| 238 | + Method provided from Phoenix Conatct to establish the UPS model: |
236 | 239 | Read registers from 0x0005 to 0x0008 and "concatenate" them with the order
|
237 | 240 | 0x0008 0x0007 0x0006 0x0005 in hex form, convert the obtained number from hex to dec.
|
238 | 241 | The first 7 most significant digits of the number in dec form are the part number of
|
239 |
| - the UPS.*/ |
| 242 | + the UPS. |
| 243 | + */ |
240 | 244 |
|
241 | 245 | PartNumber = (tab_reg[3] << 16) + tab_reg[2];
|
242 | 246 | PartNumber = (PartNumber << 16) + tab_reg[1];
|
|
337 | 341 | uint16_t battery_runtime;
|
338 | 342 | uint16_t battery_capacity;
|
339 | 343 | uint16_t output_current;
|
| 344 | + uint16_t value = 0; |
340 | 345 |
|
341 | 346 | errcount = 0;
|
342 | 347 |
|
|
348 | 353 | case QUINT4_UPS:
|
349 | 354 |
|
350 | 355 | for (size_t i = 0; i < sizeof(delay_params) / sizeof(delay_params[0]); i++) {
|
351 |
| - uint16_t value = 0; |
352 | 356 | if (modbus_read_registers(modbus_ctx, delay_params[i].reg_addr, 1, &value) != -1) {
|
353 | 357 | dstate_setinfo(delay_params[i].nut_name, "%d", value);
|
354 | 358 | } else {
|
|
790 | 794 | void upsdrv_makevartable(void)
|
791 | 795 | {
|
792 | 796 | addvar(VAR_VALUE, "delay.shutdown", "Delay before initiating PC shutdown (in seconds)");
|
793 |
| - addvar(VAR_VALUE, "delay.pc_shutdown", "Time allowed for PC to shutdown (in seconds)"); |
794 |
| - addvar(VAR_VALUE, "delay.pc_reset", "Duration of output off before reboot (in seconds)"); |
795 |
| - addvar(VAR_VALUE, "delay.mains_return", "Delay before switching back to mains (in seconds)"); |
| 797 | + addvar(VAR_VALUE, "timer.shutdown", "Time allowed for PC to shutdown (in seconds)"); |
| 798 | + addvar(VAR_VALUE, "timer.start", "Duration of output off before reboot (in seconds)"); |
| 799 | + addvar(VAR_VALUE, "delay.start", "Delay before switching back to mains (in seconds)"); |
796 | 800 | addvar(VAR_VALUE, "mode.selector", "UPS operating mode (e.g. 9 = PC-Mode)");
|
797 |
| - addvar(VAR_VALUE, "bat.warning_soh", "Battery warning SOH threshold (%)"); |
798 |
| - addvar(VAR_VALUE, "bat.voltage_low", "Threshold [V] to switch to battery mode"); |
799 |
| - addvar(VAR_VALUE, "mains.voltage_high", "Threshold [V] to return to mains mode"); |
800 |
| - addvar(VAR_VALUE, "mains.return_delay", "Time [s] above threshold before switching back to mains"); |
| 801 | + addvar(VAR_VALUE, "battery.warning_soh", "Battery warning SOH threshold (%)"); |
| 802 | + addvar(VAR_VALUE, "voltage.low.critical", "Threshold [V] to switch to battery mode"); |
| 803 | + addvar(VAR_VALUE, "voltage.high.critical", "Threshold [V] to return to mains mode"); |
801 | 804 | }
|
802 | 805 |
|
803 | 806 | void upsdrv_initups(void)
|
|
0 commit comments