@@ -820,6 +820,42 @@ static int _apc_modbus_date_from_nut(const char *value, uint16_t *output, size_t
820820
821821static apc_modbus_converter_t _apc_modbus_date_conversion = { _apc_modbus_date_to_nut , _apc_modbus_date_from_nut };
822822
823+ /*
824+ * Timer countdown conversion:
825+ * -1: NotActive - No countdown in progress
826+ * 0: CountdownExpired - Countdown has ended
827+ * 1-2147483647: Seconds remaining
828+ */
829+ static int _apc_modbus_timer_to_nut (const apc_modbus_value_t * value , char * output , size_t output_len )
830+ {
831+ int res ;
832+
833+ if (value == NULL || output == NULL || output_len == 0 ) {
834+ /* Invalid parameters */
835+ return 0 ;
836+ }
837+
838+ if (value -> type != APC_VT_INT ) {
839+ return 0 ;
840+ }
841+
842+ if (value -> data .int_value == -1 ) {
843+ res = snprintf (output , output_len , "NotActive" );
844+ } else if (value -> data .int_value == 0 ) {
845+ res = snprintf (output , output_len , "CountdownExpired" );
846+ } else {
847+ res = snprintf (output , output_len , "%" PRIi64 , value -> data .int_value );
848+ }
849+
850+ if (res < 0 || (size_t )res >= output_len ) {
851+ return 0 ;
852+ }
853+
854+ return 1 ;
855+ }
856+
857+ static apc_modbus_converter_t _apc_modbus_timer_conversion = { _apc_modbus_timer_to_nut , NULL };
858+
823859typedef struct {
824860 const char * nut_variable_name ;
825861 size_t modbus_addr ;
@@ -870,9 +906,18 @@ static apc_modbus_register_t apc_modbus_register_map_dynamic[] = {
870906 { "experimental.output.energy" , 145 , 2 , APC_VT_UINT , APC_VF_NONE , NULL , "%" PRIu64 , 0 , NULL },
871907 { "input.voltage" , 151 , 1 , APC_VT_UINT , APC_VF_NONE , & _apc_modbus_voltage_conversion , "%.2f" , 6 , NULL },
872908 { "ups.efficiency" , 154 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_efficiency_conversion , "%.1f" , 7 , NULL },
873- { "ups.timer.shutdown" , 155 , 1 , APC_VT_INT , APC_VF_NONE , NULL , "%" PRIi64 , 0 , NULL },
874- { "ups.timer.start" , 156 , 1 , APC_VT_INT , APC_VF_NONE , NULL , "%" PRIi64 , 0 , NULL },
875- { "ups.timer.reboot" , 157 , 2 , APC_VT_INT , APC_VF_NONE , NULL , "%" PRIi64 , 0 , NULL },
909+ { "ups.timer.shutdown" , 155 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
910+ { "ups.timer.start" , 156 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
911+ { "ups.timer.reboot" , 157 , 2 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
912+ { "outlet.group.1.timer.shutdown" , 159 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
913+ { "outlet.group.1.timer.start" , 160 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
914+ { "outlet.group.1.timer.reboot" , 161 , 2 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
915+ { "outlet.group.2.timer.shutdown" , 163 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
916+ { "outlet.group.2.timer.start" , 164 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
917+ { "outlet.group.2.timer.reboot" , 165 , 2 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
918+ { "outlet.group.3.timer.shutdown" , 167 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
919+ { "outlet.group.3.timer.start" , 168 , 1 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
920+ { "outlet.group.3.timer.reboot" , 169 , 2 , APC_VT_INT , APC_VF_NONE , & _apc_modbus_timer_conversion , NULL , 0 , NULL },
876921 { NULL , 0 , 0 , APC_VT_INT , APC_VF_NONE , NULL , NULL , 0.0f , NULL }
877922};
878923
@@ -1466,7 +1511,7 @@ void upsdrv_initinfo(void)
14661511
14671512void upsdrv_updateinfo (void )
14681513{
1469- uint16_t regbuf [32 ];
1514+ uint16_t regbuf [44 ];
14701515 uint64_t value ;
14711516
14721517 if (!is_open ) {
@@ -1538,7 +1583,7 @@ void upsdrv_updateinfo(void)
15381583 }
15391584
15401585 /* Dynamic Data */
1541- if (_apc_modbus_read_registers (modbus_ctx , 128 , 32 , regbuf )) {
1586+ if (_apc_modbus_read_registers (modbus_ctx , 128 , 44 , regbuf )) {
15421587 /* InputStatus_BF, 1 register */
15431588 _apc_modbus_to_uint64 (& regbuf [22 ], 1 , & value );
15441589 if (value & (1 << 5 )) {
@@ -1548,7 +1593,7 @@ void upsdrv_updateinfo(void)
15481593 status_set ("TRIM" );
15491594 }
15501595
1551- _apc_modbus_process_registers (apc_modbus_register_map_dynamic , regbuf , 32 , 128 );
1596+ _apc_modbus_process_registers (apc_modbus_register_map_dynamic , regbuf , 44 , 128 );
15521597 } else {
15531598 dstate_datastale ();
15541599 return ;
0 commit comments